Re: [PATCH/Resend 2/2] arm: mach-omap2: prevent UART console idleon suspend while using "no_console_suspend"

From: Sourav Poddar
Date: Wed Mar 20 2013 - 08:06:42 EST


Realised the list to whom the patch was send got dropped. Ccing them all..
On Wednesday 20 March 2013 05:18 PM, Sourav Poddar wrote:
Hi Kevin,
On Tuesday 19 March 2013 12:24 AM, Kevin Hilman wrote:
Sourav Poddar<sourav.poddar@xxxxxx> writes:

With dt boot, uart wakeup after suspend is non functional on omap4/5 while using
"no_console_suspend" in the bootargs. With "no_console_suspend" used, od->flags
should be ORed with "OMAP_DEVICE_NO_IDLE_ON_SUSPEND", thereby not allowing the console
to idle in the suspend path. For non-dt case, this was taken care by platform data.

Tested on omap5430evm, omap4430sdp.

Cc: Santosh Shilimkar<santosh.shilimkar@xxxxxx>
Cc: Felipe Balbi<balbi@xxxxxx>
Cc: Rajendra nayak<rnayak@xxxxxx>
Signed-off-by: Sourav Poddar<sourav.poddar@xxxxxx>
This patch creates a dependency between omap_device (generic,
device-independent code) and a specific driver (UART.)

If you need to do something like this that's DT boot specific, then
we probably need some late initcall in serial.c to handle this. It does
not belong in omap_device.

The following function "omap_device_disable_idle_on_suspend(pdev)" should only
be called once the omap device has been build, which in the case of device tree is
done in omap_device.c file. Moreover, the above call should be executed conditionally
and should depend on the following two parameter.

[1] a. Whether "no_console_suspend" is set and
b. the device build is a console uart.

When I look closely into the serial.c file, I realised that
"core_initcall(omap_serial_early_init)" gets called irrespective
of dt/non dt boot and will take care of most of the stuff(checking whether
"no_console_suspend" is used and which uart is used as a console uart) which the
$subject patch is proposing.

But the problem is that we need to exchange the parsed information
from serial.c to the omap_device file for the condtional execution of
"omap_device_disable_idle_on_suspend"

In this case,
from "serial.c" we need
1. no_console_suspend = true
2. strcpy(console_name, oh_name), where oh_name corresponds to the console uart.

then in "omap_device.c" do
if (no_console_suspend && !strcmp(oh->name, console_name))
omap_device_disable_idle_on_suspend(pdev);

Please correct if I am understanding it incorrectly.

If the above understanding looks good to you, is there a way we can make this
exchange of information happen between serial.c and omap_device.c file?
Kevin

---
arch/arm/mach-omap2/omap_device.c | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 381be7a..71f5a73 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -35,11 +35,17 @@
#include<linux/pm_runtime.h>
#include<linux/of.h>
#include<linux/notifier.h>
+#include<linux/platform_data/serial-omap.h>

#include "soc.h"
#include "omap_device.h"
#include "omap_hwmod.h"

+#define MAX_UART_HWMOD_NAME_LEN 16
+
+static u8 no_console_suspend;
+static u8 console_uart_num;
+
/* Private functions */

static void _add_clkdev(struct omap_device *od, const char *clk_alias,
@@ -108,6 +114,12 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
_add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
}

+static char *cmdline_find_option(char *str)
+{
+ extern char *saved_command_line;
+
+ return strstr(saved_command_line, str);
+}

/**
* omap_device_build_from_dt - build an omap_device with multiple hwmods
@@ -129,6 +141,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
const char *oh_name;
int oh_cnt, i, ret = 0;
+ static u8 console_uart_id;

oh_cnt = of_property_count_strings(node, "ti,hwmods");
if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) {
@@ -170,7 +183,12 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
r->name = dev_name(&pdev->dev);
}

- if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
+ if (no_console_suspend&& !strncmp(oh->name, "uart", 4)) {
+ if (console_uart_num == console_uart_id)
+ omap_device_disable_idle_on_suspend(pdev);
+ else
+ console_uart_id++;
+ } else if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
omap_device_disable_idle_on_suspend(pdev);

pdev->dev.pm_domain =&omap_device_pm_domain;
@@ -838,7 +856,21 @@ static struct notifier_block platform_nb = {

static int __init omap_device_init(void)
{
+ int i;
+ char uart_name[MAX_UART_HWMOD_NAME_LEN];
+
bus_register_notifier(&platform_bus_type,&platform_nb);
+
+ if (cmdline_find_option("no_console_suspend")) {
+ no_console_suspend = true;
+ for (i = 0; i< OMAP_MAX_HSUART_PORTS; i++) {
+ snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
+ "%s%d", OMAP_SERIAL_NAME, i);
+ if (cmdline_find_option(uart_name))
+ console_uart_num = i;
+ }
+ }
+
return 0;
}
omap_core_initcall(omap_device_init);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/