Skip to contentSkip to conversation

OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART

PATCH New Govindraj.R 4 participants 14 messages Nov 11, 2011 – Jan 3, 2012

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH v8 15/20 OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART

From: Jon Hunter <[email protected]>

When using DMA there are two timeouts defined. The first timeout, rx_timeout, is really a polling rate in which software polls the DMA status to see if the DMA has finished. This is necessary for the RX side because we do not know how much data we will receive. The secound timeout, RX_TIMEOUT, is a timeout after which the DMA will be stopped if no more data is received. To make this clearer, rename rx_timeout as rx_poll_rate and rename the function serial_omap_rx_timeout() to serial_omap_rxdma_poll().

The OMAP-Serial driver defines an RX_TIMEOUT of 3 seconds that is used to indicate when the DMA for UART can be stopped if no more data is received. The value is a global definition that is applied to all instances of the UART.

Each UART may be used for a different purpose and so the timeout required may differ. Make this value configurable for each UART so that this value can be optimised for power savings.

---
 arch/arm/mach-omap2/serial.c                  |    5 ++++-
 arch/arm/plat-omap/include/plat/omap-serial.h |    3 ++-
 drivers/tty/serial/omap-serial.c              |   15 ++++++++-------
 3 files changed, 14 insertions(+), 9 deletions(-)
arch/arm/mach-omap2/serial.c +4 -1
index 3eb2469..5c6c48f 100644
@@ -64,13 +64,15 @@ struct omap_uart_state {
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
 
-#define DEFAULT_RXDMA_TIMEOUT		1	/* RX DMA polling rate (us) */
+#define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
 #define DEFAULT_RXDMA_BUFSIZE		4096	/* RX DMA buffer size */
+#define DEFAULT_RXDMA_TIMEOUT		(3 * HZ)/* RX DMA timeout (jiffies) */
 
 static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
 	{
 		.dma_enabled	= false,
 		.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
+		.dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
 		.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
 		.autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
 	},
@@ -351,6 +353,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 	omap_up.enable_wakeup = omap_uart_enable_wakeup;
 	omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
 	omap_up.dma_rx_timeout = info->dma_rx_timeout;
+	omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
 	omap_up.autosuspend_timeout = info->autosuspend_timeout;
 
 	/* Enable the MDR1 errata for OMAP2/3/4 */
arch/arm/plat-omap/include/plat/omap-serial.h +2 -1
index 84906e9..e05c8da 100644
@@ -53,7 +53,6 @@
 
 #define OMAP_UART_DMA_CH_FREE	-1
 
-#define RX_TIMEOUT		(3 * HZ)
 #define OMAP_MAX_HSUART_PORTS	4
 
 #define MSR_SAVE_FLAGS		UART_MSR_ANY_DELTA
@@ -68,6 +67,7 @@ struct omap_uart_port_info {
 	unsigned int		dma_rx_buf_size;
 	unsigned int		dma_rx_timeout;
 	unsigned int		autosuspend_timeout;
+	unsigned int		dma_rx_poll_rate;
 
 	int (*get_context_loss_count)(struct device *);
 	void (*set_forceidle)(struct platform_device *);
@@ -97,6 +97,7 @@ struct uart_omap_dma {
 	/* timer to poll activity on rx dma */
 	struct timer_list	rx_timer;
 	unsigned int		rx_buf_size;
+	unsigned int		rx_poll_rate;
 	unsigned int		rx_timeout;
 };
 
drivers/tty/serial/omap-serial.c +8 -7
index 297fcec..be55a5d 100644
@@ -47,7 +47,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
 static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
-static void serial_omap_rx_timeout(unsigned long uart_no);
+static void serial_omap_rxdma_poll(unsigned long uart_no);
 static int serial_omap_start_rxdma(struct uart_omap_port *up);
 static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1);
 
@@ -542,7 +542,7 @@ static int serial_omap_startup(struct uart_port *port)
 			(dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys),
 			0);
 		init_timer(&(up->uart_dma.rx_timer));
-		up->uart_dma.rx_timer.function = serial_omap_rx_timeout;
+		up->uart_dma.rx_timer.function = serial_omap_rxdma_poll;
 		up->uart_dma.rx_timer.data = up->pdev->id;
 		/* Currently the buffer size is 4KB. Can increase it */
 		up->uart_dma.rx_buf = dma_alloc_coherent(NULL,
@@ -1160,7 +1160,7 @@ static int serial_omap_resume(struct device *dev)
 }
 #endif
 
-static void serial_omap_rx_timeout(unsigned long uart_no)
+static void serial_omap_rxdma_poll(unsigned long uart_no)
 {
 	struct uart_omap_port *up = ui[uart_no];
 	unsigned int curr_dma_pos, curr_transmitted_size;
@@ -1170,9 +1170,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
 	if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) ||
 			     (curr_dma_pos == 0)) {
 		if (jiffies_to_msecs(jiffies - up->port_activity) <
-							RX_TIMEOUT) {
+						up->uart_dma.rx_timeout) {
 			mod_timer(&up->uart_dma.rx_timer, jiffies +
-				usecs_to_jiffies(up->uart_dma.rx_timeout));
+				usecs_to_jiffies(up->uart_dma.rx_poll_rate));
 		} else {
 			serial_omap_stop_rxdma(up);
 			up->ier |= (UART_IER_RDI | UART_IER_RLSI);
@@ -1201,7 +1201,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
 		}
 	} else  {
 		mod_timer(&up->uart_dma.rx_timer, jiffies +
-			usecs_to_jiffies(up->uart_dma.rx_timeout));
+			usecs_to_jiffies(up->uart_dma.rx_poll_rate));
 	}
 	up->port_activity = jiffies;
 }
@@ -1240,7 +1240,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
 	/* FIXME: Cache maintenance needed here? */
 	omap_start_dma(up->uart_dma.rx_dma_channel);
 	mod_timer(&up->uart_dma.rx_timer, jiffies +
-				usecs_to_jiffies(up->uart_dma.rx_timeout));
+				usecs_to_jiffies(up->uart_dma.rx_poll_rate));
 	up->uart_dma.rx_dma_used = true;
 	return ret;
 }
@@ -1376,6 +1376,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 		up->use_dma = 1;
 		up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size;
 		up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout;
+		up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate;
 		spin_lock_init(&(up->uart_dma.tx_lock));
 		spin_lock_init(&(up->uart_dma.rx_lock));
 		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH v8 16/20 OMAP2+: UART: remove temporary variable used to count uart instance

Reuse the num_uarts variable itself to count number of uarts.

---
 arch/arm/mach-omap2/serial.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/serial.c +2 -5
index 5c6c48f..4d65d00 100644
@@ -266,15 +266,13 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
 
 static int __init omap_serial_early_init(void)
 {
-	int i = 0;
-
 	do {
 		char oh_name[MAX_UART_HWMOD_NAME_LEN];
 		struct omap_hwmod *oh;
 		struct omap_uart_state *uart;
 
 		snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
-			 "uart%d", i + 1);
+			 "uart%d", num_uarts + 1);
 		oh = omap_hwmod_lookup(oh_name);
 		if (!oh)
 			break;
@@ -284,9 +282,8 @@ static int __init omap_serial_early_init(void)
 			return -ENODEV;
 
 		uart->oh = oh;
-		uart->num = i++;
+		uart->num = num_uarts++;
 		list_add_tail(&uart->node, &uart_list);
-		num_uarts++;
 
 		/*
 		 * NOTE: omap_hwmod_setup*() has not yet been called,
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v8 17/20 OMAP2+: UART: Use custom activate func for console uart.

In reply to Govindraj.R

Omap-uart can be used as console uart to print early boot messages using earlyprintk so for console uart prevent hwmod reset or idling during bootup.

Identify the console_uart set the id and use the custom pm_latency ops for console uart for the first time to idle console uart left enabled from bootup and then enable them back and reset pm_latency ops to default ops.

Thanks to Kevin Hilman <[email protected]> for suggesting this approach.

---
 arch/arm/mach-omap2/serial.c |   86 +++++++++++++++++++++++++++++------------
 1 files changed, 61 insertions(+), 25 deletions(-)
arch/arm/mach-omap2/serial.c +61 -25
index 4d65d00..631d72a 100644
@@ -61,8 +61,10 @@ struct omap_uart_state {
 	struct platform_device *pdev;
 };
 
+static struct omap_device_pm_latency *default_uart_latency;
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
+static u8 console_uart_id = -1;
 
 #define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
 #define DEFAULT_RXDMA_BUFSIZE		4096	/* RX DMA buffer size */
@@ -78,6 +80,34 @@ static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
 	},
 };
 
+static int console_uart_enable_hwmod(struct omap_device *od)
+{
+	console_lock();
+	/*
+	 * For early console we prevented hwmod reset and idle
+	 * So before we enable the uart clocks idle the console
+	 * uart clocks, then enable back the console uart hwmod.
+	 */
+	omap_hwmod_idle(od->hwmods[0]);
+	omap_hwmod_enable(od->hwmods[0]);
+	console_unlock();
+
+	/*
+	 * Restore the default activate/deactivate funcs,
+	 * since now we have set the hwmod state machine right
+	 * with the idle/enable for console uart
+	 */
+	od->pm_lats = default_uart_latency;
+
+	return 0;
+}
+
+static struct omap_device_pm_latency console_uart_latency[] = {
+	{
+		.activate_func	 = console_uart_enable_hwmod,
+	},
+};
+
 #ifdef CONFIG_PM
 
 int omap_uart_can_sleep(void)
@@ -264,12 +294,20 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
 #endif
 
+char *cmdline_find_option(char *str)
+{
+	extern char *saved_command_line;
+
+	return strstr(saved_command_line, str);
+}
+
 static int __init omap_serial_early_init(void)
 {
 	do {
 		char oh_name[MAX_UART_HWMOD_NAME_LEN];
 		struct omap_hwmod *oh;
 		struct omap_uart_state *uart;
+		char uart_name[MAX_UART_HWMOD_NAME_LEN];
 
 		snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
 			 "uart%d", num_uarts + 1);
@@ -284,18 +322,23 @@ static int __init omap_serial_early_init(void)
 		uart->oh = oh;
 		uart->num = num_uarts++;
 		list_add_tail(&uart->node, &uart_list);
+		snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
+				"%s%d", OMAP_SERIAL_NAME, uart->num);
+
+		if (cmdline_find_option(uart_name)) {
+			console_uart_id = uart->num;
+			/*
+			 * omap-uart can be used for earlyprintk logs
+			 * So if omap-uart is used as console then prevent
+			 * uart reset and idle to get logs from omap-uart
+			 * until uart console driver is available to take
+			 * care for console messages.
+			 * Idling or resetting omap-uart while printing logs
+			 * early boot logs can stall the boot-up.
+			 */
+			oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+		}
 
-		/*
-		 * NOTE: omap_hwmod_setup*() has not yet been called,
-		 *       so no hwmod functions will work yet.
-		 */
-
-		/*
-		 * During UART early init, device need to be probed
-		 * to determine SoC specific init before omap_device
-		 * is ready.  Therefore, don't allow idle here
-		 */
-		uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
 	} while (1);
 
 	return 0;
@@ -324,6 +367,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 	u32 pdata_size = 0;
 	char *name;
 	struct omap_uart_port_info omap_up;
+	struct omap_device *od;
 
 	if (WARN_ON(!bdata))
 		return;
@@ -369,6 +413,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 	WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
 	     name, oh->name);
 
+	if (console_uart_id == bdata->id) {
+		od = to_omap_device(pdev);
+		default_uart_latency = od->pm_lats;
+		od->pm_lats = console_uart_latency;
+	}
+
 	omap_device_disable_idle_on_suspend(pdev);
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
@@ -376,20 +426,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 
 	oh->dev_attr = uart;
 
-	console_lock(); /* in case the earlycon is on the UART */
-
-	/*
-	 * Because of early UART probing, UART did not get idled
-	 * on init.  Now that omap_device is ready, ensure full idle
-	 * before doing omap_device_enable().
-	 */
-	omap_hwmod_idle(uart->oh);
-
-	omap_device_enable(uart->pdev);
-	omap_device_idle(uart->pdev);
-
-	console_unlock();
-
 	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
 		device_init_wakeup(&pdev->dev, true);
 }
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH v8 17/20 OMAP2+: UART: Use custom activate func for console uart.

Quoted 11 lines · Govindraj.R

Omap-uart can be used as console uart to print early boot messages using earlyprintk so for console uart prevent hwmod reset or idling during bootup.

Identify the console_uart set the id and use the custom pm_latency ops for console uart for the first time to idle console uart left enabled from bootup and then enable them back and reset pm_latency ops to default ops.

Thanks to Kevin Hilman <[email protected]> for suggesting this approach.

You're welcome, but Rajendra's solution is much better. ;)

Can you updated your branch without these custom hooks and using Rajendra's INIT_NO_IDLE change to the hwmod core.

Kevin

#4 lore raw

PATCH v8 17/20 OMAP2+: UART: Use custom activate func for console uart.

Quoted 11 lines · Kevin Hilman
Quoted 9 lines · Govindraj.R

Omap-uart can be used as console uart to print early boot messages using earlyprintk so for console uart prevent hwmod reset or idling during bootup.

Identify the console_uart set the id and use the custom pm_latency ops for console uart for the first time to idle console uart left enabled from bootup and then enable them back and reset pm_latency ops to default ops.

Quoted 4 lines
Quoted 2 lines

Thanks to Kevin Hilman <[email protected]> for suggesting this approach.

You're welcome, but Rajendra's solution is much better. ;)

Agree.

Quoted 4 lines

Can you updated your branch without these custom hooks and using Rajendra's INIT_NO_IDLE change to the hwmod core.

Yes done, rebased on 3.2-rc2 and created a new branch [1].

Removed custom activate function usage and used Rajendra's hwmod patch[2]

--
Thanks,
Govindraj.R

[1]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
3.2-rc1_uart_runtime

[2]:
http://permalink.gmane.org/gmane.linux.ports.arm.omap/66974

#5 lore raw

PATCH v8 17/20 OMAP2+: UART: Use custom activate func for console uart.

Quoted 28 lines · Govindraj
Quoted 11 lines · Kevin Hilman
Quoted 9 lines · Govindraj.R

Omap-uart can be used as console uart to print early boot messages using earlyprintk so for console uart prevent hwmod reset or idling during bootup.

Identify the console_uart set the id and use the custom pm_latency ops for console uart for the first time to idle console uart left enabled from bootup and then enable them back and reset pm_latency ops to default ops.

Quoted 4 lines
Quoted 2 lines

Thanks to Kevin Hilman <[email protected]> for suggesting this approach.

You're welcome, but Rajendra's solution is much better. ;)

Agree.

Quoted 4 lines

Can you updated your branch without these custom hooks and using Rajendra's INIT_NO_IDLE change to the hwmod core.

Yes done, rebased on 3.2-rc2 and created a new branch [1].

Removed custom activate function usage and used Rajendra's hwmod patch[2]

Quoted 7 lines

--
Thanks,
Govindraj.R

[1]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
3.2-rc1_uart_runtime

^^^^^^^^^^^^^^^^^^^^^^^^^

small correction new branch is
3.2-rc2_uart_runtime

--
Thanks,
Govindraj.R

#6 lore raw

PATCH v8 18/20 OMAP2+: UART: Avoid uart idling on suspend for no_console_suspend usecase

In reply to Govindraj.R

If no_console_suspend is used we have prevent uart idling during suspend to provide debug prints.

Power domain hooks can idle uarts if left enabled during system wide suspend so re-use the omap_device_disable_idle_on_suspend API's to ensure console_uart is not idled during suspend.

omap_device_disable_idle_on_suspend API was used on all uarts since the uart driver was not runtime adapted, now with runtime adaptation we can re-use this API only for no_console_suspend use cases.

---
 arch/arm/mach-omap2/serial.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/serial.c +7 -1
index 631d72a..5d910ef 100644
@@ -65,6 +65,7 @@ static struct omap_device_pm_latency *default_uart_latency;
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
 static u8 console_uart_id = -1;
+static u8 no_console_suspend;
 
 #define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
 #define DEFAULT_RXDMA_BUFSIZE		4096	/* RX DMA buffer size */
@@ -327,6 +328,10 @@ static int __init omap_serial_early_init(void)
 
 		if (cmdline_find_option(uart_name)) {
 			console_uart_id = uart->num;
+
+			if (cmdline_find_option("no_console_suspend"))
+				no_console_suspend = true;
+
 			/*
 			 * omap-uart can be used for earlyprintk logs
 			 * So if omap-uart is used as console then prevent
@@ -417,9 +422,10 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 		od = to_omap_device(pdev);
 		default_uart_latency = od->pm_lats;
 		od->pm_lats = console_uart_latency;
+		if (no_console_suspend)
+			omap_device_disable_idle_on_suspend(pdev);
 	}
 
-	omap_device_disable_idle_on_suspend(pdev);
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
 	uart->pdev = pdev;
Signature · 1 line
1.7.4.1
#7 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

In reply to Govindraj.R

If OMAP UART is used as console uart and debug is enabled, avoid gating of uart clocks to print all debug prints.

If uart clocks are gated then the debug prints from omap_device framework or hwmod framework can cause uart to enter recursive pm_runtime calls, which can cause a deadlock over power lock usage.

For example: Say, uart clocks are cut and we get a print from omap_device_disable stating disabling uart clocks. This print calls omap_uart driver console_write which will call runtime API get_sync which means we enter from runtime API put context to runtime API get context.

--> runtime put (take power lock)

    --> print disabling uart clocks
        --> call uart console write
            --> call get_sync (try to take power lock)

Also any clock enable API call from uart driver should not call any uart operation until clocks are enabled back. Like get_sync having debug print calling uart console write even before clocks are enabled.

So to avoid these scenarios, identify from bootargs if OMAP_UART(ttyO) is used in debug mode. If so, do not set device_may_wakeup. This will prevent pm_runtime_enable in uart driver and will avoid uart clock gating. Debug is enabled either by adding debug word in bootarg or by setting loglevel=10

---
 arch/arm/mach-omap2/serial.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/serial.c +10 -1
index 5d910ef..a5d9c9c 100644
@@ -66,6 +66,7 @@ static LIST_HEAD(uart_list);
 static u8 num_uarts;
 static u8 console_uart_id = -1;
 static u8 no_console_suspend;
+static u8 uart_debug;
 
 #define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
 #define DEFAULT_RXDMA_BUFSIZE		4096	/* RX DMA buffer size */
@@ -329,6 +330,13 @@ static int __init omap_serial_early_init(void)
 		if (cmdline_find_option(uart_name)) {
 			console_uart_id = uart->num;
 
+			if (console_loglevel >= 10) {
+				uart_debug = true;
+				pr_info("%s used as console in debug mode"
+						" uart%d clocks will not be"
+						" gated", uart_name, uart->num);
+			}
+
 			if (cmdline_find_option("no_console_suspend"))
 				no_console_suspend = true;
 
@@ -432,7 +440,8 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 
 	oh->dev_attr = uart;
 
-	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+			&& !uart_debug)
 		device_init_wakeup(&pdev->dev, true);
 }
 
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Hello,

On Fri, Nov 11, 2011 at 15:31:52, R, Govindraj wrote:
[...]

arch/arm/mach-omap2/serial.c void __init omap_serial_init_port(struct omap_board_data *bdata, · line 446

Quoted 6 lines
arch/arm/mach-omap2/serial.c +2 -1
-	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+			&& !uart_debug)
 		device_init_wakeup(&pdev->dev, true);
 }

I was testing this on AM335x and realized that this leads to creation of two 'wakeup' entries for UART. One is created by the tty layer in serial-core.c and the other is created here.

Here's what I see on a branch based on Tony's 3.2-rc6:

./sys/devices/platform/omap/omap_uart.0/power/wakeup ./sys/devices/platform/omap/omap_uart.0/tty/ttyO0/power/wakeup

Shouldn't the OMAP serial just enable the 'wakeup' entry created by serial-core.c?

Regards,
Vaibhav

#9 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Hi Vaibhav,

Quoted 15 lines · Vaibhav

Hello,

On Fri, Nov 11, 2011 at 15:31:52, R, Govindraj wrote:
[...]

Quoted 6 lines

- ? ? if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+ ? ? if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+ ? ? ? ? ? ? ? ? ? ? && !uart_debug)
? ? ? ? ? ? ? device_init_wakeup(&pdev->dev, true);
?}

I was testing this on AM335x and realized that this leads to creation of two 'wakeup' entries for UART. One is created by the tty layer in serial-core.c and the other is created here.

Quoted 6 lines

Here's what I see on a branch based on Tony's 3.2-rc6:

./sys/devices/platform/omap/omap_uart.0/power/wakeup ./sys/devices/platform/omap/omap_uart.0/tty/ttyO0/power/wakeup

Shouldn't the OMAP serial just enable the 'wakeup' entry created by serial-core.c?

currently runtime pm is available from omap-serial device and not from tty_dev. Setting tty_dev wakeup is to use irq_wakeup from suspend available from serail_core layer which I think we are not using for omap-uart and we use pad wakeup from suspend path.

Also omap-uart.x/power/wakeup is used to gate uart clocks using runtime PM api's in omap-serial driver.

--
Thanks,
Govindraj.R

#10 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Hi Govindraj,

Quoted 9 lines · Govindraj

currently runtime pm is available from omap-serial device and not from tty_dev. Setting tty_dev wakeup is to use irq_wakeup from suspend available from serail_core layer which I think we are not using for omap-uart and we use pad wakeup from suspend path.

Also omap-uart.x/power/wakeup is used to gate uart clocks using runtime PM api's in omap-serial driver.

Thanks for clarifying. On AM335x, one of the UARTs is in a wakeup domain and swakeup from this is used to come out of suspend.

I have basic suspend-resume working on it. Strangely this works irrespective of the value of tty_dev wakeup entry. Do you know if this is expected on OMAP?

The other issue concerning runtime PM is that as soon as I set a non-zero to the autosuspend_delay_ms I get some garbage characters and eventually the console stops responding.

[root at arago /]# cat .../omap_uart.0/power/autosuspend_delay_ms -1
[root at arago /]# echo 3000 > ?KW???+???+wU.???,z,??.??osuspend_delay??????...
[root at arago /]# <- No response after some time

The comment in the code mentions delay is receiving characters if runtime PM is enabled. Any idea what's going wrong@my end?

Regards,
Vaibhav B.

#11 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Quoted 13 lines · Vaibhav

Hi Govindraj,

Quoted 9 lines · Govindraj

currently runtime pm is available from omap-serial device and not from tty_dev. Setting tty_dev wakeup is to use irq_wakeup from suspend available from serail_core layer which I think we are not using for omap-uart and we use pad wakeup from suspend path.

Also omap-uart.x/power/wakeup is used to gate uart clocks using runtime PM api's in omap-serial driver.

Quoted 6 lines

Thanks for clarifying. On AM335x, one of the UARTs is in a wakeup domain and swakeup from this is used to come out of suspend.

I have basic suspend-resume working on it. Strangely this works irrespective of the value of tty_dev wakeup entry. Do you know if this is expected on OMAP?

AFAIK yes.

Quoted 9 lines

The other issue concerning runtime PM is that as soon as I set a non-zero to the autosuspend_delay_ms I get some garbage characters and eventually the console stops responding.

[root at arago /]# cat .../omap_uart.0/power/autosuspend_delay_ms -1
[root at arago /]# echo 3000 > ?KW???+???+wU.???,z,??.??osuspend_delay??????... [root at arago /]# <- No response after some time

try enabling CONFIG_CPU_IDLE for pm qos_usage from uart driver.

--
Thanks,
Govindraj.R

#12 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Quoted 6 lines · Govindraj
Quoted 4 lines

I have basic suspend-resume working on it. Strangely this works irrespective of the value of tty_dev wakeup entry. Do you know if this is expected on OMAP?

AFAIK yes.

Ok.

Quoted 5 lines
Quoted 5 lines

The other issue concerning runtime PM is that as soon as I set a non-zero to the autosuspend_delay_ms I get some garbage characters and eventually the console stops responding.

Quoted 8 lines
Quoted 5 lines

[root at arago /]# cat .../omap_uart.0/power/autosuspend_delay_ms -1
[root at arago /]# echo 3000 > ?KW???+???+wU.???,z,??.??osuspend_delay??????... [root at arago /]# <- No response after some time

try enabling CONFIG_CPU_IDLE for pm qos_usage from uart driver.

Its enabled.

Regards,
Vaibhav

#13 lore raw

PATCH v8 19/20 OMAP2+: UART: Do not gate uart clocks if used for debug_prints

Quoted 21 lines · Vaibhav
Quoted 6 lines · Govindraj
Quoted 4 lines

I have basic suspend-resume working on it. Strangely this works irrespective of the value of tty_dev wakeup entry. Do you know if this is expected on OMAP?

AFAIK yes.

Ok.

Quoted 11 lines
Quoted 10 lines

The other issue concerning runtime PM is that as soon as I set a non-zero to the autosuspend_delay_ms I get some garbage characters and eventually the console stops responding.

[root at arago /]# cat .../omap_uart.0/power/autosuspend_delay_ms -1
[root at arago /]# echo 3000 > ?KW???+???+wU.???,z,??.??osuspend_delay??????... [root at arago /]# <- No response after some time

Quoted 4 lines
Quoted 2 lines

try enabling CONFIG_CPU_IDLE for pm qos_usage from uart driver.

Its enabled.

I checked on Beagle-xm with latest LO master I don't see that issue.

Lo master commit used
commit: 6489f6de3a219dfd23a91261eea1b09fba7ae128

Logs:
http://pastebin.pandaboard.org/index.php/view/55509914

--
Thanks,
Govindraj.R