linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup
@ 2011-04-29 12:39 Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 01/12] OMAP2+: UART: Remove certain uart calls from sram_idle Govindraj.R
                   ` (11 more replies)
  0 siblings, 12 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Converting uart driver to adapt to pm runtime api's.
Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Changes involves:
================
1.) Cleaning up certain uart calls from sram_idle func.
2.) Removed all types of uart clock handling code from serial.c   
3.) Using hwmod_mux api enable wakeup capability for uart pad during
    hwmod_idle state i.e., when uart clocks are disabled we can enable
    io-pad wakeup capability for uart if mux_data is available for 
    given uart. Also during during resume from idle call to uart we need
    to enable clocks back conditionally and this can be done only when io-pad
    wakeup event bit is set for uart_rx pad. So we need a hwmod api
    which can probe the uart pad and let us know whether a uart wakeup
    happened. So omap_hmwod_pad_wakeup_status api is added to meet this 
    requirement.
3.) Adapted omap-serial driver to use runtime api's.
4.) Modify serial_init calls to accept certain uart parameters from board file.
5.) using resume_call to enable uart port back untill we have irq_chaining available.

Patch series is based on Kevin's PM Tree / pm-core branch [2.6.39-rc4]
Patch series hosted at https://gitorious.org/uart_runtime/pm

Testing updates:
----------------
3430SDP:
retention, off_mode, system_wide suspend is tested.
(earlyprintk & no_console_suspend checked)

OMAP3630 - Zoom3:
pm-retention checked, off mode for per domain checked.
[uart3/uart4 in per domain on omap3630].
[ZOOM3 tested with uart3 as console uart and pm-ret checked]

OMAP4430-SDP: Boot tested.
OMAP2420/2430SDP: Boot tested.
-------------

Deepak K (1):
  OMAP: Serial: Allow UART parameters to be configured from board file

Govindraj.R (10):
  OMAP2+: UART: Remove certain uart calls from sram_idle
  OMAP2+: UART: Remove uart clock handling code from serial.c
  OMAP2+: Serial: Add default mux for all uarts.
  Serial: OMAP: Add runtime pm support for omap-serial driver
  OMAP: Serial: Hold console lock for console usage.
  Serial: OMAP2+: Move erratum handling from serial.c
  OMAP3: Serial: Remove uart pads from 3430 board file.
  OMAP2+: hwmod: Add api to enable io_ring wakeup.
  OMAP: Serial: Use resume call from prcm to enable uart
  OMAP2: Serial: Add no async wake flag.

Jon Hunter (1):
  Serial: OMAP2+: Make the RX_TIMEOUT for DMA configurable for each
    UART

 arch/arm/mach-omap2/board-2430sdp.c           |    3 +-
 arch/arm/mach-omap2/board-3430sdp.c           |  101 +---
 arch/arm/mach-omap2/board-4430sdp.c           |   11 +-
 arch/arm/mach-omap2/board-am3517evm.c         |    3 +-
 arch/arm/mach-omap2/board-apollon.c           |    3 +-
 arch/arm/mach-omap2/board-cm-t35.c            |    3 +-
 arch/arm/mach-omap2/board-cm-t3517.c          |    3 +-
 arch/arm/mach-omap2/board-devkit8000.c        |    3 +-
 arch/arm/mach-omap2/board-generic.c           |    3 +-
 arch/arm/mach-omap2/board-h4.c                |    3 +-
 arch/arm/mach-omap2/board-igep0020.c          |    3 +-
 arch/arm/mach-omap2/board-igep0030.c          |    3 +-
 arch/arm/mach-omap2/board-ldp.c               |    3 +-
 arch/arm/mach-omap2/board-n8x0.c              |    9 +-
 arch/arm/mach-omap2/board-omap3beagle.c       |    3 +-
 arch/arm/mach-omap2/board-omap3evm.c          |    3 +-
 arch/arm/mach-omap2/board-omap3logic.c        |    3 +-
 arch/arm/mach-omap2/board-omap3pandora.c      |    3 +-
 arch/arm/mach-omap2/board-omap3stalker.c      |    3 +-
 arch/arm/mach-omap2/board-omap3touchbook.c    |    3 +-
 arch/arm/mach-omap2/board-omap4panda.c        |   11 +-
 arch/arm/mach-omap2/board-overo.c             |    3 +-
 arch/arm/mach-omap2/board-rm680.c             |    3 +-
 arch/arm/mach-omap2/board-rx51.c              |    3 +-
 arch/arm/mach-omap2/board-ti8168evm.c         |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c  |    3 +-
 arch/arm/mach-omap2/mux.c                     |   23 +
 arch/arm/mach-omap2/mux.h                     |   13 +
 arch/arm/mach-omap2/omap_hwmod.c              |   47 ++
 arch/arm/mach-omap2/pm24xx.c                  |   19 +-
 arch/arm/mach-omap2/pm34xx.c                  |   26 +-
 arch/arm/mach-omap2/serial.c                  |  917 +++++++------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |   38 +-
 arch/arm/plat-omap/include/plat/omap_device.h |    1 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h  |    2 +
 arch/arm/plat-omap/include/plat/serial.h      |   13 +-
 arch/arm/plat-omap/omap_device.c              |   34 +-
 drivers/tty/serial/omap-serial.c              |  319 ++++++++-
 38 files changed, 747 insertions(+), 902 deletions(-)


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v2 01/12] OMAP2+: UART: Remove certain uart calls from sram_idle
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 02/12] OMAP2+: UART: Remove uart clock handling code from serial.c Govindraj.R
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

In preparation to UART runtime conversion. Remove certain uart specific calls
from sram_idle path in pm24xx/34xx files.
These func calls will no more be used with upcoming uart runtime design.

1.) Removing console lock holding :- Now can be handled with omap-serial file
    itself.
2.) omap_uart_can_sleep :- not needed driver can autosuspend based on usage_count
    and autosuspend delay.
3.) omap_uart_prepare_suspend :- omap-serial can be taken care with driver
    suspend/resume hooks.
4.) Also remove individual uart_prepare/resume calls.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/pm24xx.c             |   19 -------------------
 arch/arm/mach-omap2/pm34xx.c             |   24 ------------------------
 arch/arm/plat-omap/include/plat/serial.h |    6 ------
 3 files changed, 0 insertions(+), 49 deletions(-)

diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index df3ded6..c405bda 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -132,27 +132,11 @@ static void omap2_enter_full_retention(void)
 	if (omap_irq_pending())
 		goto no_sleep;
 
-	/* Block console output in case it is on one of the OMAP UARTs */
-	if (!is_suspending())
-		if (!console_trylock())
-			goto no_sleep;
-
-	omap_uart_prepare_idle(0);
-	omap_uart_prepare_idle(1);
-	omap_uart_prepare_idle(2);
-
 	/* Jump to SRAM suspend code */
 	omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
 			   OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
 			   OMAP_SDRC_REGADDR(SDRC_POWER));
 
-	omap_uart_resume_idle(2);
-	omap_uart_resume_idle(1);
-	omap_uart_resume_idle(0);
-
-	if (!is_suspending())
-		console_unlock();
-
 no_sleep:
 	if (omap2_pm_debug) {
 		unsigned long long tmp;
@@ -267,8 +251,6 @@ static int omap2_can_sleep(void)
 {
 	if (omap2_fclks_active())
 		return 0;
-	if (!omap_uart_can_sleep())
-		return 0;
 	if (osc_ck->usecount > 1)
 		return 0;
 	if (omap_dma_running())
@@ -319,7 +301,6 @@ static int omap2_pm_suspend(void)
 	mir1 = omap_readl(0x480fe0a4);
 	omap_writel(1 << 5, 0x480fe0ac);
 
-	omap_uart_prepare_suspend();
 	omap2_enter_full_retention();
 
 	omap_writel(mir1, 0x480fe0a4);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0c5e3a4..ce0ecdc 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -391,18 +391,9 @@ void omap_sram_idle(void)
 		omap3_enable_io_chain();
 	}
 
-	/* Block console output in case it is on one of the OMAP UARTs */
-	if (!is_suspending())
-		if (per_next_state < PWRDM_POWER_ON ||
-		    core_next_state < PWRDM_POWER_ON)
-			if (!console_trylock())
-				goto console_still_active;
-
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
-		omap_uart_prepare_idle(2);
-		omap_uart_prepare_idle(3);
 		omap2_gpio_prepare_for_idle(per_going_off);
 		if (per_next_state == PWRDM_POWER_OFF)
 				omap3_per_save_context();
@@ -410,8 +401,6 @@ void omap_sram_idle(void)
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
-		omap_uart_prepare_idle(0);
-		omap_uart_prepare_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_cm_save_context();
@@ -458,8 +447,6 @@ void omap_sram_idle(void)
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		omap_uart_resume_idle(0);
-		omap_uart_resume_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF)
 			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
 					       OMAP3430_GR_MOD,
@@ -473,14 +460,8 @@ void omap_sram_idle(void)
 		omap2_gpio_resume_after_idle();
 		if (per_prev_state == PWRDM_POWER_OFF)
 			omap3_per_restore_context();
-		omap_uart_resume_idle(2);
-		omap_uart_resume_idle(3);
 	}
 
-	if (!is_suspending())
-		console_unlock();
-
-console_still_active:
 	/* Disable IO-PAD and IO-CHAIN wakeup */
 	if (omap3_has_io_wakeup() &&
 	    (per_next_state < PWRDM_POWER_ON ||
@@ -499,8 +480,6 @@ int omap3_can_sleep(void)
 {
 	if (!sleep_while_idle)
 		return 0;
-	if (!omap_uart_can_sleep())
-		return 0;
 	return 1;
 }
 
@@ -549,7 +528,6 @@ static int omap3_pm_suspend(void)
 			goto restore;
 	}
 
-	omap_uart_prepare_suspend();
 	omap3_intc_suspend();
 
 	omap_sram_idle();
@@ -596,14 +574,12 @@ static int omap3_pm_begin(suspend_state_t state)
 {
 	disable_hlt();
 	suspend_state = state;
-	omap_uart_enable_irqs(0);
 	return 0;
 }
 
 static void omap3_pm_end(void)
 {
 	suspend_state = PM_SUSPEND_ON;
-	omap_uart_enable_irqs(1);
 	enable_hlt();
 	return;
 }
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 2723f91..ab1761a 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -106,12 +106,6 @@ struct omap_board_data;
 
 extern void omap_serial_init(void);
 extern void omap_serial_init_port(struct omap_board_data *bdata);
-extern int omap_uart_can_sleep(void);
-extern void omap_uart_check_wakeup(void);
-extern void omap_uart_prepare_suspend(void);
-extern void omap_uart_prepare_idle(int num);
-extern void omap_uart_resume_idle(int num);
-extern void omap_uart_enable_irqs(int enable);
 #endif
 
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 02/12] OMAP2+: UART: Remove uart clock handling code from serial.c
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 01/12] OMAP2+: UART: Remove certain uart calls from sram_idle Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-04-29 13:20   ` Alan Cox
  2011-04-29 12:39 ` [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts Govindraj.R
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Cleanup serial.c file in preparation to addition of runtime api's in omap-serial
file. Remove all clock handling mechanism as this will be taken care with
pm runtime api's in omap-serial.c file itself.

1.) Remove omap-device enable and disable. We can can use get_sync/put_sync api's
2.) Remove context save/restore can be done with runtime_resume callback for
    get_sync call. No need to save context as all reg details available in
    uart_port structure can be used for restore, so add missing regs in
    uart port struct.
3.) Add func to identify console uart.
4.) Erratum handling informed as flag to driver and func to handle erratum
    can be moved to omap-serial driver itself.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c                  |  754 ++-----------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |   15 +-
 2 files changed, 74 insertions(+), 695 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 1ac361b..b16768a 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -19,25 +19,18 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/serial_reg.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/serial_8250.h>
 #include <linux/pm_runtime.h>
-#include <linux/console.h>
 
-#ifdef CONFIG_SERIAL_OMAP
 #include <plat/omap-serial.h>
-#endif
-
 #include <plat/common.h>
 #include <plat/board.h>
 #include <plat/clock.h>
 #include <plat/dma.h>
-#include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
 #include "prm2xxx_3xxx.h"
@@ -47,65 +40,9 @@
 #include "control.h"
 #include "mux.h"
 
-#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV	0x52
-#define UART_OMAP_WER		0x17	/* Wake-up enable register */
-
-#define UART_ERRATA_FIFO_FULL_ABORT	(0x1 << 0)
-#define UART_ERRATA_i202_MDR1_ACCESS	(0x1 << 1)
-
-/*
- * NOTE: By default the serial timeout is disabled as it causes lost characters
- * over the serial ports. This means that the UART clocks will stay on until
- * disabled via sysfs. This also causes that any deeper omap sleep states are
- * blocked. 
- */
-#define DEFAULT_TIMEOUT 0
-
-#define MAX_UART_HWMOD_NAME_LEN		16
+#define MAX_UART_HWMOD_NAME_LEN                16
 
-struct omap_uart_state {
-	int num;
-	int can_sleep;
-	struct timer_list timer;
-	u32 timeout;
-
-	void __iomem *wk_st;
-	void __iomem *wk_en;
-	u32 wk_mask;
-	u32 padconf;
-	u32 dma_enabled;
-
-	struct clk *ick;
-	struct clk *fck;
-	int clocked;
-
-	int irq;
-	int regshift;
-	int irqflags;
-	void __iomem *membase;
-	resource_size_t mapbase;
-
-	struct list_head node;
-	struct omap_hwmod *oh;
-	struct platform_device *pdev;
-
-	u32 errata;
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-	int context_valid;
-
-	/* Registers to be saved/restored for OFF-mode */
-	u16 dll;
-	u16 dlh;
-	u16 ier;
-	u16 sysc;
-	u16 scr;
-	u16 wer;
-	u16 mcr;
-#endif
-};
-
-static LIST_HEAD(uart_list);
-static u8 num_uarts;
+static int omap_uart_con_id __initdata = -1;
 
 static int uart_idle_hwmod(struct omap_device *od)
 {
@@ -129,396 +66,35 @@ static struct omap_device_pm_latency omap_uart_latency[] = {
 	},
 };
 
-static inline unsigned int __serial_read_reg(struct uart_port *up,
-					     int offset)
-{
-	offset <<= up->regshift;
-	return (unsigned int)__raw_readb(up->membase + offset);
-}
-
-static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
-					   int offset)
-{
-	offset <<= uart->regshift;
-	return (unsigned int)__raw_readb(uart->membase + offset);
-}
-
-static inline void __serial_write_reg(struct uart_port *up, int offset,
-		int value)
-{
-	offset <<= up->regshift;
-	__raw_writeb(value, up->membase + offset);
-}
-
-static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
-				    int value)
-{
-	offset <<= uart->regshift;
-	__raw_writeb(value, uart->membase + offset);
-}
-
-/*
- * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly. Note that the TX watermark initialization may not be needed
- * once the 8250.c watermark handling code is merged.
- */
-
-static inline void __init omap_uart_reset(struct omap_uart_state *uart)
-{
-	serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-	serial_write_reg(uart, UART_OMAP_SCR, 0x08);
-	serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
-}
-
-#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
-
-/*
- * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
- * The access to uart register after MDR1 Access
- * causes UART to corrupt data.
- *
- * Need a delay =
- * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
- * give 10 times as much
- */
-static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
-		u8 fcr_val)
-{
-	u8 timeout = 255;
-
-	serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
-	udelay(2);
-	serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
-			UART_FCR_CLEAR_RCVR);
-	/*
-	 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
-	 * TX_FIFO_E bit is 1.
-	 */
-	while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
-				(UART_LSR_THRE | UART_LSR_DR))) {
-		timeout--;
-		if (!timeout) {
-			/* Should *never* happen. we warn and carry on */
-			dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
-			serial_read_reg(uart, UART_LSR));
-			break;
-		}
-		udelay(1);
-	}
-}
-
-static void omap_uart_save_context(struct omap_uart_state *uart)
-{
-	u16 lcr = 0;
-
-	if (!enable_off_mode)
-		return;
-
-	lcr = serial_read_reg(uart, UART_LCR);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	uart->dll = serial_read_reg(uart, UART_DLL);
-	uart->dlh = serial_read_reg(uart, UART_DLM);
-	serial_write_reg(uart, UART_LCR, lcr);
-	uart->ier = serial_read_reg(uart, UART_IER);
-	uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
-	uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
-	uart->wer = serial_read_reg(uart, UART_OMAP_WER);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-	uart->mcr = serial_read_reg(uart, UART_MCR);
-	serial_write_reg(uart, UART_LCR, lcr);
-
-	uart->context_valid = 1;
-}
-
-static void omap_uart_restore_context(struct omap_uart_state *uart)
+static void omap_uart_idle_init(struct omap_uart_port_info *uart,
+				unsigned short num)
 {
-	u16 efr = 0;
-
-	if (!enable_off_mode)
-		return;
-
-	if (!uart->context_valid)
-		return;
-
-	uart->context_valid = 0;
-
-	if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-		omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
-	else
-		serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	efr = serial_read_reg(uart, UART_EFR);
-	serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
-	serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-	serial_write_reg(uart, UART_IER, 0x0);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	serial_write_reg(uart, UART_DLL, uart->dll);
-	serial_write_reg(uart, UART_DLM, uart->dlh);
-	serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-	serial_write_reg(uart, UART_IER, uart->ier);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-	serial_write_reg(uart, UART_MCR, uart->mcr);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	serial_write_reg(uart, UART_EFR, efr);
-	serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
-	serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
-	serial_write_reg(uart, UART_OMAP_WER, uart->wer);
-	serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
-
-	if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-		omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
-	else
-		/* UART 16x mode */
-		serial_write_reg(uart, UART_OMAP_MDR1,
-				UART_OMAP_MDR1_16X_MODE);
-}
-#else
-static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
-static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
-#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
-
-static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
-{
-	if (uart->clocked)
-		return;
-
-	omap_device_enable(uart->pdev);
-	uart->clocked = 1;
-	omap_uart_restore_context(uart);
-}
-
-#ifdef CONFIG_PM
-
-static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
-{
-	if (!uart->clocked)
-		return;
-
-	omap_uart_save_context(uart);
-	uart->clocked = 0;
-	omap_device_idle(uart->pdev);
-}
-
-static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
-{
-	/* Set wake-enable bit */
-	if (uart->wk_en && uart->wk_mask) {
-		u32 v = __raw_readl(uart->wk_en);
-		v |= uart->wk_mask;
-		__raw_writel(v, uart->wk_en);
-	}
-
-	/* Ensure IOPAD wake-enables are set */
-	if (cpu_is_omap34xx() && uart->padconf) {
-		u16 v = omap_ctrl_readw(uart->padconf);
-		v |= OMAP3_PADCONF_WAKEUPENABLE0;
-		omap_ctrl_writew(v, uart->padconf);
-	}
-}
-
-static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
-{
-	/* Clear wake-enable bit */
-	if (uart->wk_en && uart->wk_mask) {
-		u32 v = __raw_readl(uart->wk_en);
-		v &= ~uart->wk_mask;
-		__raw_writel(v, uart->wk_en);
-	}
-
-	/* Ensure IOPAD wake-enables are cleared */
-	if (cpu_is_omap34xx() && uart->padconf) {
-		u16 v = omap_ctrl_readw(uart->padconf);
-		v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
-		omap_ctrl_writew(v, uart->padconf);
-	}
-}
-
-static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
-					       int enable)
-{
-	u8 idlemode;
-
-	if (enable) {
-		/**
-		 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
-		 * in Smartidle Mode When Configured for DMA Operations.
-		 */
-		if (uart->dma_enabled)
-			idlemode = HWMOD_IDLEMODE_FORCE;
-		else
-			idlemode = HWMOD_IDLEMODE_SMART;
-	} else {
-		idlemode = HWMOD_IDLEMODE_NO;
-	}
-
-	omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
-}
-
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
-{
-	omap_uart_enable_clocks(uart);
-
-	omap_uart_smart_idle_enable(uart, 0);
-	uart->can_sleep = 0;
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
-	else
-		del_timer(&uart->timer);
-}
-
-static void omap_uart_allow_sleep(struct omap_uart_state *uart)
-{
-	if (device_may_wakeup(&uart->pdev->dev))
-		omap_uart_enable_wakeup(uart);
-	else
-		omap_uart_disable_wakeup(uart);
-
-	if (!uart->clocked)
-		return;
-
-	omap_uart_smart_idle_enable(uart, 1);
-	uart->can_sleep = 1;
-	del_timer(&uart->timer);
-}
-
-static void omap_uart_idle_timer(unsigned long data)
-{
-	struct omap_uart_state *uart = (struct omap_uart_state *)data;
-
-	omap_uart_allow_sleep(uart);
-}
-
-void omap_uart_prepare_idle(int num)
-{
-	struct omap_uart_state *uart;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		if (num == uart->num && uart->can_sleep) {
-			omap_uart_disable_clocks(uart);
-			return;
-		}
-	}
-}
-
-void omap_uart_resume_idle(int num)
-{
-	struct omap_uart_state *uart;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		if (num == uart->num && uart->can_sleep) {
-			omap_uart_enable_clocks(uart);
-
-			/* Check for IO pad wakeup */
-			if (cpu_is_omap34xx() && uart->padconf) {
-				u16 p = omap_ctrl_readw(uart->padconf);
-
-				if (p & OMAP3_PADCONF_WAKEUPEVENT0)
-					omap_uart_block_sleep(uart);
-			}
-
-			/* Check for normal UART wakeup */
-			if (__raw_readl(uart->wk_st) & uart->wk_mask)
-				omap_uart_block_sleep(uart);
-			return;
-		}
-	}
-}
-
-void omap_uart_prepare_suspend(void)
-{
-	struct omap_uart_state *uart;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		omap_uart_allow_sleep(uart);
-	}
-}
-
-int omap_uart_can_sleep(void)
-{
-	struct omap_uart_state *uart;
-	int can_sleep = 1;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		if (!uart->clocked)
-			continue;
-
-		if (!uart->can_sleep) {
-			can_sleep = 0;
-			continue;
-		}
-
-		/* This UART can now safely sleep. */
-		omap_uart_allow_sleep(uart);
-	}
-
-	return can_sleep;
-}
-
-/**
- * omap_uart_interrupt()
- *
- * This handler is used only to detect that *any* UART interrupt has
- * occurred.  It does _nothing_ to handle the interrupt.  Rather,
- * any UART interrupt will trigger the inactivity timer so the
- * UART will not idle or sleep for its timeout period.
- *
- **/
-/* static int first_interrupt; */
-static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
-{
-	struct omap_uart_state *uart = dev_id;
-
-	omap_uart_block_sleep(uart);
-
-	return IRQ_NONE;
-}
-
-static void omap_uart_idle_init(struct omap_uart_state *uart)
-{
-	int ret;
-
-	uart->can_sleep = 0;
-	uart->timeout = DEFAULT_TIMEOUT;
-	setup_timer(&uart->timer, omap_uart_idle_timer,
-		    (unsigned long) uart);
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
-	omap_uart_smart_idle_enable(uart, 0);
-
-	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
-		u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
+	if (cpu_is_omap34xx()) {
+		u32 mod = num > 1 ? OMAP3430_PER_MOD : CORE_MOD;
 		u32 wk_mask = 0;
-		u32 padconf = 0;
 
-		/* XXX These PRM accesses do not belong here */
 		uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
 		uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
-		switch (uart->num) {
+		switch (num) {
 		case 0:
 			wk_mask = OMAP3430_ST_UART1_MASK;
-			padconf = 0x182;
 			break;
 		case 1:
 			wk_mask = OMAP3430_ST_UART2_MASK;
-			padconf = 0x17a;
 			break;
 		case 2:
 			wk_mask = OMAP3430_ST_UART3_MASK;
-			padconf = 0x19e;
 			break;
 		case 3:
 			wk_mask = OMAP3630_ST_UART4_MASK;
-			padconf = 0x0d2;
 			break;
 		}
 		uart->wk_mask = wk_mask;
-		uart->padconf = padconf;
 	} else if (cpu_is_omap24xx()) {
 		u32 wk_mask = 0;
 		u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
 
-		switch (uart->num) {
+		switch (num) {
 		case 0:
 			wk_mask = OMAP24XX_ST_UART1_MASK;
 			break;
@@ -543,155 +119,49 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		uart->wk_en = NULL;
 		uart->wk_st = NULL;
 		uart->wk_mask = 0;
-		uart->padconf = 0;
-	}
-
-	uart->irqflags |= IRQF_SHARED;
-	ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
-				   IRQF_SHARED, "serial idle", (void *)uart);
-	WARN_ON(ret);
-}
-
-void omap_uart_enable_irqs(int enable)
-{
-	int ret;
-	struct omap_uart_state *uart;
-
-	list_for_each_entry(uart, &uart_list, node) {
-		if (enable) {
-			pm_runtime_put_sync(&uart->pdev->dev);
-			ret = request_threaded_irq(uart->irq, NULL,
-						   omap_uart_interrupt,
-						   IRQF_SHARED,
-						   "serial idle",
-						   (void *)uart);
-		} else {
-			pm_runtime_get_noresume(&uart->pdev->dev);
-			free_irq(uart->irq, (void *)uart);
-		}
-	}
-}
-
-static ssize_t sleep_timeout_show(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap_device *odev = to_omap_device(pdev);
-	struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-
-	return sprintf(buf, "%u\n", uart->timeout / HZ);
-}
-
-static ssize_t sleep_timeout_store(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf, size_t n)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap_device *odev = to_omap_device(pdev);
-	struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-	unsigned int value;
-
-	if (sscanf(buf, "%u", &value) != 1) {
-		dev_err(dev, "sleep_timeout_store: Invalid value\n");
-		return -EINVAL;
 	}
-
-	uart->timeout = value * HZ;
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
-	else
-		/* A zero value means disable timeout feature */
-		omap_uart_block_sleep(uart);
-
-	return n;
-}
-
-static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
-		sleep_timeout_store);
-#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
-#else
-static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
-{
-	/* Needed to enable UART clocks when built without CONFIG_PM */
-	omap_uart_enable_clocks(uart);
 }
-#define DEV_CREATE_FILE(dev, attr)
-#endif /* CONFIG_PM */
 
-#ifndef CONFIG_SERIAL_OMAP
-/*
- * Override the default 8250 read handler: mem_serial_in()
- * Empty RX fifo read causes an abort on omap3630 and omap4
- * This function makes sure that an empty rx fifo is not read on these silicons
- * (OMAP1/2/3430 are not affected)
- */
-static unsigned int serial_in_override(struct uart_port *up, int offset)
+char *cmdline_find_option(char *str)
 {
-	if (UART_RX == offset) {
-		unsigned int lsr;
-		lsr = __serial_read_reg(up, UART_LSR);
-		if (!(lsr & UART_LSR_DR))
-			return -EPERM;
-	}
+	extern char *saved_command_line;
 
-	return __serial_read_reg(up, offset);
+	return strstr(saved_command_line, str);
 }
 
-static void serial_out_override(struct uart_port *up, int offset, int value)
+struct omap_hwmod *omap_uart_hwmod_lookup(int num)
 {
-	unsigned int status, tmout = 10000;
+	struct omap_hwmod *oh;
+	char oh_name[MAX_UART_HWMOD_NAME_LEN];
 
-	status = __serial_read_reg(up, UART_LSR);
-	while (!(status & UART_LSR_THRE)) {
-		/* Wait up to 10ms for the character(s) to be sent. */
-		if (--tmout == 0)
-			break;
-		udelay(1);
-		status = __serial_read_reg(up, UART_LSR);
-	}
-	__serial_write_reg(up, offset, value);
+	snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, "uart%d", num + 1);
+	oh = omap_hwmod_lookup(oh_name);
+	WARN(IS_ERR(oh), "Could not lookup hmwod info for %s\n",
+					oh_name);
+	return oh;
 }
-#endif
 
 static int __init omap_serial_early_init(void)
 {
+#ifdef CONFIG_EARLY_PRINTK
 	int i = 0;
+	char omap_tty_name[MAX_UART_HWMOD_NAME_LEN];
+	struct omap_hwmod *oh;
 
-	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);
-		oh = omap_hwmod_lookup(oh_name);
-		if (!oh)
-			break;
-
-		uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
-		if (WARN_ON(!uart))
-			return -ENODEV;
-
-		uart->oh = oh;
-		uart->num = i++;
-		list_add_tail(&uart->node, &uart_list);
-		num_uarts++;
-
-		/*
-		 * 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);
-
+	if (!cmdline_find_option("earlyprintk"))
+		return 0;
+
+	for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
+		snprintf(omap_tty_name, MAX_UART_HWMOD_NAME_LEN,
+			"%s%d", OMAP_SERIAL_NAME, i);
+		if (cmdline_find_option(omap_tty_name)) {
+			omap_uart_con_id = i;
+			oh = omap_uart_hwmod_lookup(i);
+			oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+			return 0;
+		}
+	}
+#endif
 	return 0;
 }
 core_initcall(omap_serial_early_init);
@@ -709,149 +179,50 @@ core_initcall(omap_serial_early_init);
  */
 void __init omap_serial_init_port(struct omap_board_data *bdata)
 {
-	struct omap_uart_state *uart;
 	struct omap_hwmod *oh;
 	struct omap_device *od;
-	void *pdata = NULL;
-	u32 pdata_size = 0;
-	char *name;
-#ifndef CONFIG_SERIAL_OMAP
-	struct plat_serial8250_port ports[2] = {
-		{},
-		{.flags = 0},
-	};
-	struct plat_serial8250_port *p = &ports[0];
-#else
-	struct omap_uart_port_info omap_up;
-#endif
+	struct omap_uart_port_info *pdata;
+	char *name = DRIVER_NAME;
 
 	if (WARN_ON(!bdata))
 		return;
 	if (WARN_ON(bdata->id < 0))
 		return;
-	if (WARN_ON(bdata->id >= num_uarts))
+	if (WARN_ON(bdata->id >= OMAP_MAX_HSUART_PORTS))
 		return;
 
-	list_for_each_entry(uart, &uart_list, node)
-		if (bdata->id == uart->num)
-			break;
-
-	oh = uart->oh;
-	uart->dma_enabled = 0;
-#ifndef CONFIG_SERIAL_OMAP
-	name = "serial8250";
-
-	/*
-	 * !! 8250 driver does not use standard IORESOURCE* It
-	 * has it's own custom pdata that can be taken from
-	 * the hwmod resource data.  But, this needs to be
-	 * done after the build.
-	 *
-	 * ?? does it have to be done before the register ??
-	 * YES, because platform_device_data_add() copies
-	 * pdata, it does not use a pointer.
-	 */
-	p->flags = UPF_BOOT_AUTOCONF;
-	p->iotype = UPIO_MEM;
-	p->regshift = 2;
-	p->uartclk = OMAP24XX_BASE_BAUD * 16;
-	p->irq = oh->mpu_irqs[0].irq;
-	p->mapbase = oh->slaves[0]->addr->pa_start;
-	p->membase = omap_hwmod_get_mpu_rt_va(oh);
-	p->irqflags = IRQF_SHARED;
-	p->private_data = uart;
-
-	/*
-	 * omap44xx, ti816x: Never read empty UART fifo
-	 * omap3xxx: Never read empty UART fifo on UARTs
-	 * with IP rev >=0x52
-	 */
-	uart->regshift = p->regshift;
-	uart->membase = p->membase;
-	if (cpu_is_omap44xx() || cpu_is_ti816x())
-		uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
-	else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
-			>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
-		uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
+	oh = omap_uart_hwmod_lookup(bdata->id);
+	if (!oh)
+		return;
 
-	if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
-		p->serial_in = serial_in_override;
-		p->serial_out = serial_out_override;
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("Memory allocation for UART pdata failed\n");
+		return;
 	}
 
-	pdata = &ports[0];
-	pdata_size = 2 * sizeof(struct plat_serial8250_port);
-#else
-
-	name = DRIVER_NAME;
-
-	omap_up.dma_enabled = uart->dma_enabled;
-	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
-	omap_up.mapbase = oh->slaves[0]->addr->pa_start;
-	omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
-	omap_up.irqflags = IRQF_SHARED;
-	omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+	/* Enable the MDR1 errata for OMAP3 */
+	if (cpu_is_omap34xx())
+		pdata->errata |= UART_ERRATA_i202_MDR1_ACCESS;
 
-	pdata = &omap_up;
-	pdata_size = sizeof(struct omap_uart_port_info);
-#endif
+	omap_uart_idle_init(pdata, bdata->id);
 
-	if (WARN_ON(!oh))
-		return;
+	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
+	pdata->flags = UPF_BOOT_AUTOCONF;
+	if (bdata->id == omap_uart_con_id)
+		pdata->console_uart = true;
 
-	od = omap_device_build(name, uart->num, oh, pdata, pdata_size,
-			       omap_uart_latency,
-			       ARRAY_SIZE(omap_uart_latency), false);
+	od = omap_device_build(name, bdata->id, oh, pdata,
+				sizeof(*pdata), omap_uart_latency,
+				ARRAY_SIZE(omap_uart_latency), false);
 	WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
 	     name, oh->name);
 
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
-
-	uart->irq = oh->mpu_irqs[0].irq;
-	uart->regshift = 2;
-	uart->mapbase = oh->slaves[0]->addr->pa_start;
-	uart->membase = omap_hwmod_get_mpu_rt_va(oh);
-	uart->pdev = &od->pdev;
-
-	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_uart_idle_init(uart);
-	omap_uart_reset(uart);
-	omap_hwmod_enable_wakeup(uart->oh);
-	omap_device_idle(uart->pdev);
-
-	/*
-	 * Need to block sleep long enough for interrupt driven
-	 * driver to start.  Console driver is in polling mode
-	 * so device needs to be kept enabled while polling driver
-	 * is in use.
-	 */
-	if (uart->timeout)
-		uart->timeout = (30 * HZ);
-	omap_uart_block_sleep(uart);
-	uart->timeout = DEFAULT_TIMEOUT;
-
-	console_unlock();
-
-	if ((cpu_is_omap34xx() && uart->padconf) ||
-	    (uart->wk_en && uart->wk_mask)) {
+	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) ||
+	    (pdata->wk_en && pdata->wk_mask)) {
 		device_init_wakeup(&od->pdev.dev, true);
-		DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
 	}
-
-	/* Enable the MDR1 errata for OMAP3 */
-	if (cpu_is_omap34xx() && !cpu_is_ti816x())
-		uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
 }
 
 /**
@@ -863,15 +234,14 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
  */
 void __init omap_serial_init(void)
 {
-	struct omap_uart_state *uart;
 	struct omap_board_data bdata;
+	u8 i;
 
-	list_for_each_entry(uart, &uart_list, node) {
-		bdata.id = uart->num;
+	for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
+		bdata.id = i;
 		bdata.flags = 0;
 		bdata.pads = NULL;
 		bdata.pads_cnt = 0;
 		omap_serial_init_port(&bdata);
-
 	}
 }
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2682043..2ca885b 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -56,13 +56,18 @@
 
 #define MSR_SAVE_FLAGS		UART_MSR_ANY_DELTA
 
+#define UART_ERRATA_i202_MDR1_ACCESS	BIT(0)
+
 struct omap_uart_port_info {
 	bool			dma_enabled;	/* To specify DMA Mode */
 	unsigned int		uartclk;	/* UART clock rate */
-	void __iomem		*membase;	/* ioremap cookie or NULL */
-	resource_size_t		mapbase;	/* resource base */
-	unsigned long		irqflags;	/* request_irq flags */
 	upf_t			flags;		/* UPF_* flags */
+	unsigned int		errata;
+	unsigned int		console_uart;
+
+	void __iomem *wk_st;
+	void __iomem *wk_en;
+	u32 wk_mask;
 };
 
 struct uart_omap_dma {
@@ -100,6 +105,9 @@ struct uart_omap_port {
 	unsigned char		mcr;
 	unsigned char		fcr;
 	unsigned char		efr;
+	unsigned char		dll;
+	unsigned char		dlh;
+	unsigned char		mdr1;
 
 	int			use_dma;
 	/*
@@ -111,6 +119,7 @@ struct uart_omap_port {
 	unsigned char		msr_saved_flags;
 	char			name[20];
 	unsigned long		port_activity;
+	unsigned int		errata;
 };
 
 #endif /* __OMAP_SERIAL_H__ */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts.
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 01/12] OMAP2+: UART: Remove certain uart calls from sram_idle Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 02/12] OMAP2+: UART: Remove uart clock handling code from serial.c Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-04 10:00   ` Tony Lindgren
  2011-04-29 12:39 ` [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver Govindraj.R
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Add default mux data for all uarts if mux info is not passed from
board file to avoid breaking any board support.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c |  127 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 126 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b16768a..8c1a4c7 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -66,6 +66,129 @@ static struct omap_device_pm_latency omap_uart_latency[] = {
 	},
 };
 
+#ifdef CONFIG_OMAP_MUX
+static struct omap_device_pad default_uart1_pads[] __initdata = {
+	{
+		.name	= "uart1_cts.uart1_cts",
+		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart1_rts.uart1_rts",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart1_tx.uart1_tx",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart1_rx.uart1_rx",
+		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+	},
+};
+
+static struct omap_device_pad default_uart2_pads[] __initdata = {
+	{
+		.name	= "uart2_cts.uart2_cts",
+		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart2_rts.uart2_rts",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart2_tx.uart2_tx",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart2_rx.uart2_rx",
+		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+	},
+};
+
+static struct omap_device_pad default_uart3_pads[] __initdata = {
+	{
+		.name	= "uart3_cts_rctx.uart3_cts_rctx",
+		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart3_rts_sd.uart3_rts_sd",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart3_tx_irtx.uart3_tx_irtx",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart3_rx_irrx.uart3_rx_irrx",
+		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+	},
+};
+
+static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
+	{
+		.name   = "gpmc_wait2.uart4_tx",
+		.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "gpmc_wait3.uart4_rx",
+		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE2,
+	},
+};
+
+static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
+	{
+		.name	= "uart4_tx.uart4_tx",
+		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+	},
+	{
+		.name	= "uart4_rx.uart4_rx",
+		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+	},
+};
+#else
+static struct omap_device_pad default_uart1_pads[] __initdata = {};
+static struct omap_device_pad default_uart2_pads[] __initdata = {};
+static struct omap_device_pad default_uart3_pads[] __initdata = {};
+static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {};
+static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {};
+#endif
+
+static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
+{
+	switch (bdata->id) {
+	case 0:
+		bdata->pads = default_uart1_pads;
+		bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
+		break;
+	case 1:
+		bdata->pads = default_uart2_pads;
+		bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
+		break;
+	case 2:
+		bdata->pads = default_uart3_pads;
+		bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
+		break;
+	case 3:
+		if (cpu_is_omap44xx()) {
+			bdata->pads = default_omap4_uart4_pads;
+			bdata->pads_cnt =
+				ARRAY_SIZE(default_omap4_uart4_pads);
+		} else {
+			bdata->pads = default_omap36xx_uart4_pads;
+			bdata->pads_cnt =
+				ARRAY_SIZE(default_omap36xx_uart4_pads);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static void omap_uart_idle_init(struct omap_uart_port_info *uart,
 				unsigned short num)
 {
@@ -242,6 +365,8 @@ void __init omap_serial_init(void)
 		bdata.flags = 0;
 		bdata.pads = NULL;
 		bdata.pads_cnt = 0;
-		omap_serial_init_port(&bdata);
+
+		if (cpu_is_omap44xx() || cpu_is_omap34xx())
+			omap_serial_fill_default_pads(&bdata);
 	}
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (2 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-04 20:35   ` Kevin Hilman
  2011-04-29 12:39 ` [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage Govindraj.R
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Adapts omap-serial driver to use pm_runtime api's.

1.) Populate reg values to uart port which can be used for context restore.
2.) Moving context_restore func to driver from serial.c
3.) Adding port_enable/disable func to enable/disable given uart port.
    enable port using get_sync and disable using autosuspend.
4.) using runtime irq safe api to make get_sync be called from irq context.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c                  |   16 ++
 arch/arm/plat-omap/include/plat/omap-serial.h |    2 +
 drivers/tty/serial/omap-serial.c              |  211 ++++++++++++++++++++++---
 3 files changed, 203 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 8c1a4c7..314d82f 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -189,6 +189,21 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 	}
 }
 
+static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
+{
+	struct omap_uart_port_info *up = pdev->dev.platform_data;
+
+	/* Set or clear wake-enable bit */
+	if (up->wk_en && up->wk_mask) {
+		u32 v = __raw_readl(up->wk_en);
+		if (enable)
+			v |= up->wk_mask;
+		else
+			v &= ~up->wk_mask;
+		__raw_writel(v, up->wk_en);
+	}
+}
+
 static void omap_uart_idle_init(struct omap_uart_port_info *uart,
 				unsigned short num)
 {
@@ -332,6 +347,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
 	pdata->flags = UPF_BOOT_AUTOCONF;
+	pdata->enable_wakeup = omap_uart_wakeup_enable;
 	if (bdata->id == omap_uart_con_id)
 		pdata->console_uart = true;
 
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2ca885b..ac30de8 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -65,6 +65,7 @@ struct omap_uart_port_info {
 	unsigned int		errata;
 	unsigned int		console_uart;
 
+	void (*enable_wakeup)(struct platform_device *, bool);
 	void __iomem *wk_st;
 	void __iomem *wk_en;
 	u32 wk_mask;
@@ -120,6 +121,7 @@ struct uart_omap_port {
 	char			name[20];
 	unsigned long		port_activity;
 	unsigned int		errata;
+	void (*enable_wakeup)(struct platform_device *, bool);
 };
 
 #endif /* __OMAP_SERIAL_H__ */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 47cadf4..633dfb4 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -37,10 +37,14 @@
 #include <linux/clk.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
+#include <linux/pm_runtime.h>
 
 #include <plat/dma.h>
 #include <plat/dmtimer.h>
 #include <plat/omap-serial.h>
+#include <plat/omap_device.h>
+
+#define OMAP_UART_AUTOSUSPEND_DELAY (30 * HZ) /* Value is msecs */
 
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
@@ -94,6 +98,17 @@ serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
 	return port->uartclk/(baud * divisor);
 }
 
+static inline void serial_omap_port_disable(struct uart_omap_port *up)
+{
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
+}
+
+static inline void serial_omap_port_enable(struct uart_omap_port *up)
+{
+	pm_runtime_get_sync(&up->pdev->dev);
+}
+
 static void serial_omap_stop_rxdma(struct uart_omap_port *up)
 {
 	if (up->uart_dma.rx_dma_used) {
@@ -110,8 +125,11 @@ static void serial_omap_enable_ms(struct uart_port *port)
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 
 	dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id);
+
+	serial_omap_port_enable(up);
 	up->ier |= UART_IER_MSI;
 	serial_out(up, UART_IER, up->ier);
+	serial_omap_port_disable(up);
 }
 
 static void serial_omap_stop_tx(struct uart_port *port)
@@ -131,21 +149,26 @@ static void serial_omap_stop_tx(struct uart_port *port)
 		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
 	}
 
+	serial_omap_port_enable(up);
 	if (up->ier & UART_IER_THRI) {
 		up->ier &= ~UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
 	}
+
+	serial_omap_port_disable(up);
 }
 
 static void serial_omap_stop_rx(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 
+	serial_omap_port_enable(up);
 	if (up->use_dma)
 		serial_omap_stop_rxdma(up);
 	up->ier &= ~UART_IER_RLSI;
 	up->port.read_status_mask &= ~UART_LSR_DR;
 	serial_out(up, UART_IER, up->ier);
+	serial_omap_port_disable(up);
 }
 
 static inline void receive_chars(struct uart_omap_port *up, int *status)
@@ -261,8 +284,10 @@ static void serial_omap_start_tx(struct uart_port *port)
 	unsigned int start;
 	int ret = 0;
 
+	serial_omap_port_enable(up);
 	if (!up->use_dma) {
 		serial_omap_enable_ier_thri(up);
+		serial_omap_port_disable(up);
 		return;
 	}
 
@@ -354,9 +379,12 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 	unsigned int iir, lsr;
 	unsigned long flags;
 
+	serial_omap_port_enable(up);
 	iir = serial_in(up, UART_IIR);
-	if (iir & UART_IIR_NO_INT)
+	if (iir & UART_IIR_NO_INT) {
+		serial_omap_port_disable(up);
 		return IRQ_NONE;
+	}
 
 	spin_lock_irqsave(&up->port.lock, flags);
 	lsr = serial_in(up, UART_LSR);
@@ -378,6 +406,8 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 		transmit_chars(up);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	serial_omap_port_disable(up);
+
 	up->port_activity = jiffies;
 	return IRQ_HANDLED;
 }
@@ -388,11 +418,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
 	unsigned long flags = 0;
 	unsigned int ret = 0;
 
+	serial_omap_port_enable(up);
 	dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id);
 	spin_lock_irqsave(&up->port.lock, flags);
 	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
 	spin_unlock_irqrestore(&up->port.lock, flags);
-
+	serial_omap_port_disable(up);
 	return ret;
 }
 
@@ -402,7 +433,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)
 	unsigned char status;
 	unsigned int ret = 0;
 
+	serial_omap_port_enable(up);
 	status = check_modem_status(up);
+	serial_omap_port_disable(up);
+
 	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);
 
 	if (status & UART_MSR_DCD)
@@ -434,7 +468,9 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
 		mcr |= UART_MCR_LOOP;
 
 	mcr |= up->mcr;
+	serial_omap_port_enable(up);
 	serial_out(up, UART_MCR, mcr);
+	serial_omap_port_disable(up);
 }
 
 static void serial_omap_break_ctl(struct uart_port *port, int break_state)
@@ -443,6 +479,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
 	unsigned long flags = 0;
 
 	dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id);
+	serial_omap_port_enable(up);
 	spin_lock_irqsave(&up->port.lock, flags);
 	if (break_state == -1)
 		up->lcr |= UART_LCR_SBC;
@@ -450,6 +487,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
 		up->lcr &= ~UART_LCR_SBC;
 	serial_out(up, UART_LCR, up->lcr);
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	serial_omap_port_disable(up);
 }
 
 static int serial_omap_startup(struct uart_port *port)
@@ -468,6 +506,7 @@ static int serial_omap_startup(struct uart_port *port)
 
 	dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id);
 
+	serial_omap_port_enable(up);
 	/*
 	 * Clear the FIFO buffers and disable them.
 	 * (they will be reenabled in set_termios())
@@ -523,6 +562,7 @@ static int serial_omap_startup(struct uart_port *port)
 	/* Enable module level wake up */
 	serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP);
 
+	serial_omap_port_disable(up);
 	up->port_activity = jiffies;
 	return 0;
 }
@@ -533,6 +573,8 @@ static void serial_omap_shutdown(struct uart_port *port)
 	unsigned long flags = 0;
 
 	dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id);
+
+	serial_omap_port_enable(up);
 	/*
 	 * Disable interrupts from this port
 	 */
@@ -566,6 +608,7 @@ static void serial_omap_shutdown(struct uart_port *port)
 			up->uart_dma.rx_buf_dma_phys);
 		up->uart_dma.rx_buf = NULL;
 	}
+	serial_omap_port_disable(up);
 	free_irq(up->port.irq, up);
 }
 
@@ -671,6 +714,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
 	quot = serial_omap_get_divisor(port, baud);
 
+	up->dll = quot & 0xff;
+	up->dlh = quot >> 8;
+	up->mdr1 = UART_OMAP_MDR1_DISABLE;
+
 	up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 |
 			UART_FCR_ENABLE_FIFO;
 	if (up->use_dma)
@@ -680,6 +727,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	 * Ok, we're now changing the port state. Do it with
 	 * interrupts disabled.
 	 */
+	serial_omap_port_enable(up);
 	spin_lock_irqsave(&up->port.lock, flags);
 
 	/*
@@ -758,8 +806,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_out(up, UART_MCR, up->mcr);
 
 	/* Protocol, Baud Rate, and Interrupt Settings */
-
-	serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
 	up->efr = serial_in(up, UART_EFR);
@@ -769,8 +816,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_out(up, UART_IER, 0);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
-	serial_out(up, UART_DLL, quot & 0xff);          /* LS of divisor */
-	serial_out(up, UART_DLM, quot >> 8);            /* MS of divisor */
+	serial_out(up, UART_DLL, up->dll);	/* LS of divisor */
+	serial_out(up, UART_DLM, up->dlh);	/* MS of divisor */
 
 	serial_out(up, UART_LCR, 0);
 	serial_out(up, UART_IER, up->ier);
@@ -780,9 +827,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_out(up, UART_LCR, cval);
 
 	if (baud > 230400 && baud != 3000000)
-		serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE);
+		up->mdr1 = UART_OMAP_MDR1_13X_MODE;
 	else
-		serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
+		up->mdr1 = UART_OMAP_MDR1_16X_MODE;
+
+	serial_out(up, UART_OMAP_MDR1, up->mdr1)
 
 	/* Hardware Flow Control Configuration */
 
@@ -810,6 +859,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 		serial_omap_configure_xonxoff(up, termios);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	serial_omap_port_disable(up);
 	dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
 }
 
@@ -821,6 +871,8 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
 	unsigned char efr;
 
 	dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
+
+	serial_omap_port_enable(up);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	efr = serial_in(up, UART_EFR);
 	serial_out(up, UART_EFR, efr | UART_EFR_ECB);
@@ -830,6 +882,10 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	serial_out(up, UART_EFR, efr);
 	serial_out(up, UART_LCR, 0);
+	if (state)
+		pm_runtime_put_sync(&up->pdev->dev);
+	else
+		serial_omap_port_disable(up);
 }
 
 static void serial_omap_release_port(struct uart_port *port)
@@ -907,25 +963,31 @@ static inline void wait_for_xmitr(struct uart_omap_port *up)
 static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
+
+	serial_omap_port_enable(up);
 	wait_for_xmitr(up);
 	serial_out(up, UART_TX, ch);
+	serial_omap_port_disable(up);
 }
 
 static int serial_omap_poll_get_char(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
-	unsigned int status = serial_in(up, UART_LSR);
+	unsigned int status;
 
+	serial_omap_port_enable(up);
+	status = serial_in(up, UART_LSR);
 	if (!(status & UART_LSR_DR))
 		return NO_POLL_CHAR;
 
-	return serial_in(up, UART_RX);
+	status = serial_in(up, UART_RX);
+	serial_omap_port_disable(up);
+	return status;
 }
 
 #endif /* CONFIG_CONSOLE_POLL */
 
 #ifdef CONFIG_SERIAL_OMAP_CONSOLE
-
 static struct uart_omap_port *serial_omap_console_ports[4];
 
 static struct uart_driver serial_omap_reg;
@@ -955,6 +1017,8 @@ serial_omap_console_write(struct console *co, const char *s,
 	else
 		spin_lock(&up->port.lock);
 
+	serial_omap_port_enable(up);
+
 	/*
 	 * First save the IER then disable the interrupts
 	 */
@@ -979,6 +1043,7 @@ serial_omap_console_write(struct console *co, const char *s,
 	if (up->msr_saved_flags)
 		check_modem_status(up);
 
+	serial_omap_port_disable(up);
 	if (locked)
 		spin_unlock(&up->port.lock);
 	local_irq_restore(flags);
@@ -1061,22 +1126,27 @@ static struct uart_driver serial_omap_reg = {
 	.cons		= OMAP_CONSOLE,
 };
 
-static int
-serial_omap_suspend(struct platform_device *pdev, pm_message_t state)
+static int serial_omap_suspend(struct device *dev)
 {
-	struct uart_omap_port *up = platform_get_drvdata(pdev);
+	struct uart_omap_port *up = dev_get_drvdata(dev);
 
-	if (up)
+	if (up) {
 		uart_suspend_port(&serial_omap_reg, &up->port);
+		console_trylock();
+		serial_omap_pm(&up->port, 3, 0);
+	}
 	return 0;
 }
 
-static int serial_omap_resume(struct platform_device *dev)
+static int serial_omap_resume(struct device *dev)
 {
-	struct uart_omap_port *up = platform_get_drvdata(dev);
+	struct uart_omap_port *up = dev_get_drvdata(dev);
 
-	if (up)
+	if (up) {
 		uart_resume_port(&serial_omap_reg, &up->port);
+		console_unlock();
+	}
+
 	return 0;
 }
 
@@ -1097,6 +1167,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
 			serial_omap_stop_rxdma(up);
 			up->ier |= (UART_IER_RDI | UART_IER_RLSI);
 			serial_out(up, UART_IER, up->ier);
+			serial_omap_port_disable(up);
 		}
 		return;
 	}
@@ -1128,6 +1199,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
 
 static void uart_rx_dma_callback(int lch, u16 ch_status, void *data)
 {
+	struct uart_omap_port *up = (struct uart_omap_port *)data;
+
+	serial_omap_port_disable(up);
 	return;
 }
 
@@ -1135,6 +1209,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
 {
 	int ret = 0;
 
+	serial_omap_port_enable(up);
 	if (up->uart_dma.rx_dma_channel == -1) {
 		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
 				"UART Rx DMA",
@@ -1214,6 +1289,7 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
 		serial_omap_stop_tx(&up->port);
 		up->uart_dma.tx_dma_used = false;
 		spin_unlock(&(up->uart_dma.tx_lock));
+		serial_omap_port_disable(up);
 	} else {
 		omap_stop_dma(up->uart_dma.tx_dma_channel);
 		serial_omap_continue_tx(up);
@@ -1224,9 +1300,10 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
 
 static int serial_omap_probe(struct platform_device *pdev)
 {
-	struct uart_omap_port	*up;
+	struct uart_omap_port	*up = NULL;
 	struct resource		*mem, *irq, *dma_tx, *dma_rx;
 	struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data;
+	struct omap_device *od;
 	int ret = -ENOSPC;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1276,12 +1353,20 @@ static int serial_omap_probe(struct platform_device *pdev)
 	up->port.ops = &serial_omap_pops;
 	up->port.line = pdev->id;
 
-	up->port.membase = omap_up_info->membase;
-	up->port.mapbase = omap_up_info->mapbase;
+	up->port.mapbase = mem->start;
+	up->port.membase = ioremap(mem->start, mem->end - mem->start);
+
+	if (!up->port.membase) {
+		dev_err(&pdev->dev, "can't ioremap UART\n");
+		ret = -ENOMEM;
+		goto err1;
+	}
+
 	up->port.flags = omap_up_info->flags;
-	up->port.irqflags = omap_up_info->irqflags;
 	up->port.uartclk = omap_up_info->uartclk;
 	up->uart_dma.uart_base = mem->start;
+	up->errata = omap_up_info->errata;
+	up->enable_wakeup = omap_up_info->enable_wakeup;
 
 	if (omap_up_info->dma_enabled) {
 		up->uart_dma.uart_dma_tx = dma_tx->start;
@@ -1295,18 +1380,36 @@ static int serial_omap_probe(struct platform_device *pdev)
 		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
 	}
 
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev,
+			OMAP_UART_AUTOSUSPEND_DELAY);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_irq_safe(&pdev->dev);
+
+	if (omap_up_info->console_uart) {
+		od = to_omap_device(up->pdev);
+		omap_hwmod_idle(od->hwmods[0]);
+		serial_omap_port_enable(up);
+		serial_omap_port_disable(up);
+	}
+
 	ui[pdev->id] = up;
 	serial_omap_add_console_port(up);
 
 	ret = uart_add_one_port(&serial_omap_reg, &up->port);
 	if (ret != 0)
-		goto do_release_region;
+		goto err1;
 
+	dev_set_drvdata(&pdev->dev, up);
 	platform_set_drvdata(pdev, up);
+
 	return 0;
 err:
 	dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
 				pdev->id, __func__, ret);
+err1:
+	kfree(up);
 do_release_region:
 	release_mem_region(mem->start, (mem->end - mem->start) + 1);
 	return ret;
@@ -1318,20 +1421,76 @@ static int serial_omap_remove(struct platform_device *dev)
 
 	platform_set_drvdata(dev, NULL);
 	if (up) {
+		pm_runtime_disable(&up->pdev->dev);
 		uart_remove_one_port(&serial_omap_reg, &up->port);
 		kfree(up);
 	}
 	return 0;
 }
 
+static void omap_uart_restore_context(struct uart_omap_port *up)
+{
+	u16 efr = 0;
+
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
+	efr = serial_in(up, UART_EFR);
+	serial_out(up, UART_EFR, UART_EFR_ECB);
+	serial_out(up, UART_LCR, 0x0); /* Operational mode */
+	serial_out(up, UART_IER, 0x0);
+	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
+	serial_out(up, UART_DLL, up->dll);
+	serial_out(up, UART_DLM, up->dlh);
+	serial_out(up, UART_LCR, 0x0); /* Operational mode */
+	serial_out(up, UART_IER, up->ier);
+	serial_out(up, UART_FCR, up->fcr);
+	serial_out(up, UART_LCR, 0x80);
+	serial_out(up, UART_MCR, up->mcr);
+	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
+	serial_out(up, UART_EFR, efr);
+	serial_out(up, UART_LCR, UART_LCR_WLEN8);
+	/* UART 16x mode */
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+}
+
+static int omap_serial_runtime_suspend(struct device *dev)
+{
+	struct uart_omap_port *up = dev_get_drvdata(dev);
+
+	if (!up)
+		goto done;
+
+	if (device_may_wakeup(dev))
+		up->enable_wakeup(up->pdev, true);
+	else
+		up->enable_wakeup(up->pdev, false);
+done:
+	return 0;
+}
+
+static int omap_serial_runtime_resume(struct device *dev)
+{
+	struct uart_omap_port *up = dev_get_drvdata(dev);
+
+	if (up)
+		omap_uart_restore_context(up);
+
+	return 0;
+}
+
+static const struct dev_pm_ops omap_serial_dev_pm_ops = {
+	.suspend = serial_omap_suspend,
+	.resume	= serial_omap_resume,
+	.runtime_suspend = omap_serial_runtime_suspend,
+	.runtime_resume = omap_serial_runtime_resume,
+};
+
 static struct platform_driver serial_omap_driver = {
 	.probe          = serial_omap_probe,
 	.remove         = serial_omap_remove,
-
-	.suspend	= serial_omap_suspend,
-	.resume		= serial_omap_resume,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.pm = &omap_serial_dev_pm_ops,
 	},
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (3 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-04 10:02   ` Tony Lindgren
  2011-05-04 20:43   ` Kevin Hilman
  2011-04-29 12:39 ` [PATCH v2 06/12] Serial: OMAP2+: Move erratum handling from serial.c Govindraj.R
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Acquire console lock before enabling and writing to console-uart
to avoid any recursive prints from console write.
for ex:
	--> printk
	  --> uart_console_write
	    --> get_sync
	      --> printk from omap_device enable
		--> uart_console write

Also during bootup console_lock is not available.
       --> uart_add_one_port
	   --> console_register
	       --> console_lock
	        --> console_unlock
	             --> call_console_drivers (here yet console_lock is not released)
		          --> uart_console_write

Hence convert prints from omap_device_enable/disable to pr_debug.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/plat-omap/omap_device.c |    8 ++++----
 drivers/tty/serial/omap-serial.c |    8 +++++++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 9bbda9a..f7c6dca 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -145,12 +145,12 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
 			odpl->activate_lat_worst = act_lat;
 			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
 				odpl->activate_lat = act_lat;
-				pr_warning("omap_device: %s.%d: new worst case "
+				pr_debug("omap_device: %s.%d: new worst case "
 					   "activate latency %d: %llu\n",
 					   od->pdev.name, od->pdev.id,
 					   od->pm_lat_level, act_lat);
 			} else
-				pr_warning("omap_device: %s.%d: activate "
+				pr_debug("omap_device: %s.%d: activate "
 					   "latency %d higher than exptected. "
 					   "(%llu > %d)\n",
 					   od->pdev.name, od->pdev.id,
@@ -213,12 +213,12 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
 			odpl->deactivate_lat_worst = deact_lat;
 			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
 				odpl->deactivate_lat = deact_lat;
-				pr_warning("omap_device: %s.%d: new worst case "
+				pr_debug("omap_device: %s.%d: new worst case "
 					   "deactivate latency %d: %llu\n",
 					   od->pdev.name, od->pdev.id,
 					   od->pm_lat_level, deact_lat);
 			} else
-				pr_warning("omap_device: %s.%d: deactivate "
+				pr_debug("omap_device: %s.%d: deactivate "
 					   "latency %d higher than exptected. "
 					   "(%llu > %d)\n",
 					   od->pdev.name, od->pdev.id,
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 633dfb4..7d8ca45 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1007,7 +1007,10 @@ serial_omap_console_write(struct console *co, const char *s,
 	struct uart_omap_port *up = serial_omap_console_ports[co->index];
 	unsigned long flags;
 	unsigned int ier;
-	int locked = 1;
+	int console_lock = 0, locked = 1;
+
+	if (console_trylock())
+		console_lock = 1;
 
 	local_irq_save(flags);
 	if (up->port.sysrq)
@@ -1043,6 +1046,9 @@ serial_omap_console_write(struct console *co, const char *s,
 	if (up->msr_saved_flags)
 		check_modem_status(up);
 
+	if (console_lock)
+		console_unlock();
+
 	serial_omap_port_disable(up);
 	if (locked)
 		spin_unlock(&up->port.lock);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 06/12] Serial: OMAP2+: Move erratum handling from serial.c
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (4 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file Govindraj.R
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Move the erratum handling mechanism from serial.c to driver file
and utilise the same func. in driver file.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 drivers/tty/serial/omap-serial.c |   58 ++++++++++++++++++++++++++++++++++---
 1 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 7d8ca45..b275321 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -52,6 +52,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
 static void serial_omap_rx_timeout(unsigned long uart_no);
 static int serial_omap_start_rxdma(struct uart_omap_port *up);
+static void omap_uart_mdr1_errataset(struct uart_omap_port *up);
 
 static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
 {
@@ -806,7 +807,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_out(up, UART_MCR, up->mcr);
 
 	/* Protocol, Baud Rate, and Interrupt Settings */
-	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+		omap_uart_mdr1_errataset(up);
+	else
+		serial_out(up, UART_OMAP_MDR1, up->mdr1);
+
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
 	up->efr = serial_in(up, UART_EFR);
@@ -831,7 +836,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	else
 		up->mdr1 = UART_OMAP_MDR1_16X_MODE;
 
-	serial_out(up, UART_OMAP_MDR1, up->mdr1)
+	if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+		omap_uart_mdr1_errataset(up);
+	else
+		serial_out(up, UART_OMAP_MDR1, up->mdr1);
 
 	/* Hardware Flow Control Configuration */
 
@@ -1434,11 +1442,48 @@ static int serial_omap_remove(struct platform_device *dev)
 	return 0;
 }
 
+/*
+ * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
+ * The access to uart register after MDR1 Access
+ * causes UART to corrupt data.
+ *
+ * Need a delay =
+ * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
+ * give 10 times as much
+ */
+static void omap_uart_mdr1_errataset(struct uart_omap_port *up)
+{
+	u8 timeout = 255;
+
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	udelay(2);
+	serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
+			UART_FCR_CLEAR_RCVR);
+	/*
+	 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+	 * TX_FIFO_E bit is 1.
+	 */
+	while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
+				(UART_LSR_THRE | UART_LSR_DR))) {
+		timeout--;
+		if (!timeout) {
+			/* Should *never* happen. we warn and carry on */
+			dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n",
+						serial_in(up, UART_LSR));
+			break;
+		}
+		udelay(1);
+	}
+}
+
 static void omap_uart_restore_context(struct uart_omap_port *up)
 {
 	u16 efr = 0;
 
-	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+		omap_uart_mdr1_errataset(up);
+	else
+		serial_out(up, UART_OMAP_MDR1, up->mdr1);
 	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
 	efr = serial_in(up, UART_EFR);
 	serial_out(up, UART_EFR, UART_EFR_ECB);
@@ -1455,8 +1500,11 @@ static void omap_uart_restore_context(struct uart_omap_port *up)
 	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
 	serial_out(up, UART_EFR, efr);
 	serial_out(up, UART_LCR, UART_LCR_WLEN8);
-	/* UART 16x mode */
-	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+		omap_uart_mdr1_errataset(up);
+	else
+		/* UART 16x mode */
+		serial_out(up, UART_OMAP_MDR1, up->mdr1);
 }
 
 static int omap_serial_runtime_suspend(struct device *dev)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (5 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 06/12] Serial: OMAP2+: Move erratum handling from serial.c Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-04  9:55   ` Tony Lindgren
  2011-04-29 12:39 ` [PATCH v2 08/12] Serial: OMAP2+: Make the RX_TIMEOUT for DMA configurable for each UART Govindraj.R
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Deepak K, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak, Jon Hunter, Govindraj.R

From: Deepak K <deepak.k@ti.com>

The following UART parameters are defined within the UART driver:

1). Whether the UART uses DMA (dma_enabled), by default set to 0
2). The size of dma buffer (set to 4096 bytes)
3). The time after which the dma should stop if no more data is received.
4). The auto suspend delay that will be passed for pm_runtime_autosuspend
    where uart will be disabled after timeout

Different UARTs may be used for different purpose such as the console,
for interfacing bluetooth chip, for interfacing to a modem chip, etc.
Therefore, it is necessary to be able to customize the above settings
for a given board on a per UART basis.

This change allows these parameters to be configured from the board file
and allows the parameters to be configured for each UART independently.

If a board does not define its own custom parameters for the UARTs, then
use the default parameters in the structure "omap_serial_default_info".
The default parameters are defined to be the same as the current settings
in the UART driver to avoid breaking the UART for any board. By default,
make all boards use the default UART parameters.

Signed-off-by: Deepak K <deepak.k@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/board-2430sdp.c           |    3 +-
 arch/arm/mach-omap2/board-3430sdp.c           |    9 ++++---
 arch/arm/mach-omap2/board-4430sdp.c           |   11 +++++----
 arch/arm/mach-omap2/board-am3517evm.c         |    3 +-
 arch/arm/mach-omap2/board-apollon.c           |    3 +-
 arch/arm/mach-omap2/board-cm-t35.c            |    3 +-
 arch/arm/mach-omap2/board-cm-t3517.c          |    3 +-
 arch/arm/mach-omap2/board-devkit8000.c        |    3 +-
 arch/arm/mach-omap2/board-generic.c           |    3 +-
 arch/arm/mach-omap2/board-h4.c                |    3 +-
 arch/arm/mach-omap2/board-igep0020.c          |    3 +-
 arch/arm/mach-omap2/board-igep0030.c          |    3 +-
 arch/arm/mach-omap2/board-ldp.c               |    3 +-
 arch/arm/mach-omap2/board-n8x0.c              |    9 ++++---
 arch/arm/mach-omap2/board-omap3beagle.c       |    3 +-
 arch/arm/mach-omap2/board-omap3evm.c          |    3 +-
 arch/arm/mach-omap2/board-omap3logic.c        |    3 +-
 arch/arm/mach-omap2/board-omap3pandora.c      |    3 +-
 arch/arm/mach-omap2/board-omap3stalker.c      |    3 +-
 arch/arm/mach-omap2/board-omap3touchbook.c    |    3 +-
 arch/arm/mach-omap2/board-omap4panda.c        |   11 +++++----
 arch/arm/mach-omap2/board-overo.c             |    3 +-
 arch/arm/mach-omap2/board-rm680.c             |    3 +-
 arch/arm/mach-omap2/board-rx51.c              |    3 +-
 arch/arm/mach-omap2/board-ti8168evm.c         |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c  |    3 +-
 arch/arm/mach-omap2/serial.c                  |   28 +++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap-serial.h |   14 +++++++++--
 arch/arm/plat-omap/include/plat/serial.h      |    6 +++-
 drivers/tty/serial/omap-serial.c              |    8 ++----
 30 files changed, 109 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 1fa6bb8..88f969b 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -38,6 +38,7 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 #include <plat/gpmc-smc91x.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -250,7 +251,7 @@ static void __init omap_2430sdp_init(void)
 	omap2430_i2c_init();
 
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
-	omap_serial_init();
+	omap_serial_init(NULL);
 	omap2_hsmmc_init(mmc);
 	omap2_usbfs_init(&sdp2430_usb_config);
 
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9afd087..7912174 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -32,6 +32,7 @@
 #include <asm/mach/map.h>
 
 #include <plat/mcspi.h>
+#include <plat/omap-serial.h>
 #include <plat/board.h>
 #include <plat/usb.h>
 #include <plat/common.h>
@@ -739,16 +740,16 @@ static struct omap_board_data serial3_data = {
 
 static inline void board_serial_init(void)
 {
-	omap_serial_init_port(&serial1_data);
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
+	omap_serial_init_port(&serial1_data, NULL);
+	omap_serial_init_port(&serial2_data, NULL);
+	omap_serial_init_port(&serial3_data, NULL);
 }
 #else
 #define board_mux	NULL
 
 static inline void board_serial_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
 #endif
 
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 56702c5..c7651bd 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -37,6 +37,7 @@
 #include <plat/mmc.h>
 #include <plat/omap4-keypad.h>
 #include <plat/display.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -762,18 +763,18 @@ static inline void board_serial_init(void)
 	bdata.pads_cnt	= 0;
 	bdata.id	= 0;
 	/* pass dummy data for UART1 */
-	omap_serial_init_port(&bdata);
+	omap_serial_init_port(&bdata, NULL);
 
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-	omap_serial_init_port(&serial4_data);
+	omap_serial_init_port(&serial2_data, NULL);
+	omap_serial_init_port(&serial3_data, NULL);
+	omap_serial_init_port(&serial4_data, NULL);
 }
 #else
 #define board_mux	NULL
 
 static inline void board_serial_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
  #endif
 
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index ce7d5e6..9b9ad68 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -36,6 +36,7 @@
 #include <plat/usb.h>
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "control.h"
@@ -490,7 +491,7 @@ static void __init am3517_evm_init(void)
 
 	am3517_evm_i2c_init();
 	omap_display_init(&am3517_evm_dss_data);
-	omap_serial_init();
+	omap_serial_init(NULL);
 
 	/* Configure GPIO for EHCI port */
 	omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index f4f8374..0e1075a 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -39,6 +39,7 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "control.h"
@@ -342,7 +343,7 @@ static void __init omap_apollon_init(void)
 	 * if not needed.
 	 */
 	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
 
 static void __init omap_apollon_map_io(void)
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index b5772c1..7e5df0a 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -48,6 +48,7 @@
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
 #include <plat/mcspi.h>
+#include <plat/omap-serial.h>
 
 #include <mach/hardware.h>
 
@@ -729,7 +730,7 @@ static void __init cm_t35_init(void)
 	omap_board_config = cm_t35_config;
 	omap_board_config_size = ARRAY_SIZE(cm_t35_config);
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	cm_t35_init_i2c();
 	cm_t35_init_nand();
 	cm_t35_init_ads7846();
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index a27e3ee..1ba508b 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -43,6 +43,7 @@
 #include <plat/usb.h>
 #include <plat/nand.h>
 #include <plat/gpmc.h>
+#include <plat/omap-serial.h>
 
 #include <mach/am35xx.h>
 
@@ -291,7 +292,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init cm_t3517_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	omap_board_config = cm_t3517_config;
 	omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
 	cm_t3517_init_leds();
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 65f9fde..fcf8c0d 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -47,6 +47,7 @@
 #include <plat/usb.h>
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
+#include <plat/omap-serial.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -786,7 +787,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init devkit8000_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
-	omap_serial_init();
+	omap_serial_init(NULL);
 
 	omap_dm9000_init();
 
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 73e3c31..0974c2a 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -29,6 +29,7 @@
 #include <plat/usb.h>
 #include <plat/board.h>
 #include <plat/common.h>
+#include <plat/omap-serial.h>
 
 static struct omap_board_config_kernel generic_config[] = {
 };
@@ -41,7 +42,7 @@ static void __init omap_generic_init_early(void)
 
 static void __init omap_generic_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 	omap_board_config = generic_config;
 	omap_board_config_size = ARRAY_SIZE(generic_config);
 }
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index bac7933..ef7204b 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -39,6 +39,7 @@
 #include <plat/menelaus.h>
 #include <plat/dma.h>
 #include <plat/gpmc.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "control.h"
@@ -370,7 +371,7 @@ static void __init omap_h4_init(void)
 
 	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
 	omap2_usbfs_init(&h4_usb_config);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	h4_init_flash();
 }
 
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 5b9bde7..b0fd9d6 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -34,6 +34,7 @@
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
 #include <plat/onenand.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -647,7 +648,7 @@ static void __init igep2_init(void)
 	igep2_i2c_init();
 	platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
 	omap_display_init(&igep2_dss_data);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
 
diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c
index 2cf86c3..b12bdcf 100644
--- a/arch/arm/mach-omap2/board-igep0030.c
+++ b/arch/arm/mach-omap2/board-igep0030.c
@@ -31,6 +31,7 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 #include <plat/onenand.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -432,7 +433,7 @@ static void __init igep3_init(void)
 	/* Register I2C busses and drivers */
 	igep3_i2c_init();
 	platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices));
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
 
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ea9f049..93fcbd9 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -40,6 +40,7 @@
 #include <plat/common.h>
 #include <plat/gpmc.h>
 #include <mach/board-zoom.h>
+#include <plat/omap-serial.h>
 
 #include <asm/delay.h>
 #include <plat/usb.h>
@@ -404,7 +405,7 @@ static void __init omap_ldp_init(void)
 	spi_register_board_info(ldp_spi_board_info,
 				ARRAY_SIZE(ldp_spi_board_info));
 	ads7846_dev_init();
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	board_nand_init(ldp_nand_partitions,
 		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index e710cd9..2d526de 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -33,6 +33,7 @@
 #include <plat/onenand.h>
 #include <plat/mmc.h>
 #include <plat/serial.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 
@@ -662,22 +663,22 @@ static inline void board_serial_init(void)
 	bdata.pads_cnt = 0;
 
 	bdata.id = 0;
-	omap_serial_init_port(&bdata);
+	omap_serial_init_port(&bdata, NULL);
 
 	bdata.id = 1;
-	omap_serial_init_port(&bdata);
+	omap_serial_init_port(&bdata, NULL);
 
 	bdata.id = 2;
 	bdata.pads = serial2_pads;
 	bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
-	omap_serial_init_port(&bdata);
+	omap_serial_init_port(&bdata, NULL);
 }
 
 #else
 
 static inline void board_serial_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
 
 #endif
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 33007fd..e2a6758 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -40,6 +40,7 @@
 #include <asm/mach/flash.h>
 
 #include <plat/board.h>
+#include <plat/omap-serial.h>
 #include <plat/common.h>
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
@@ -662,7 +663,7 @@ static void __init omap3_beagle_init(void)
 	platform_add_devices(omap3_beagle_devices,
 			ARRAY_SIZE(omap3_beagle_devices));
 	omap_display_init(&beagle_dss_data);
-	omap_serial_init();
+	omap_serial_init(NULL);
 
 	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
 	gpio_request(170, "DVI_nPD");
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 3fc85c6..803a790 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -46,6 +46,7 @@
 #include <plat/mcspi.h>
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -795,7 +796,7 @@ static void __init omap3_evm_init(void)
 	spi_register_board_info(omap3evm_spi_board_info,
 				ARRAY_SIZE(omap3evm_spi_board_info));
 
-	omap_serial_init();
+	omap_serial_init(NULL);
 
 	/* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
 	usb_nop_xceiv_register();
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index a49e6cf..6fbb8dd 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -44,6 +44,7 @@
 #include <plat/gpmc-smsc911x.h>
 #include <plat/gpmc.h>
 #include <plat/sdrc.h>
+#include <plat/omap-serial.h>
 
 #define OMAP3LOGIC_SMSC911X_CS			1
 
@@ -211,7 +212,7 @@ static void __init omap3logic_init(void)
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3torpedo_fix_pbias_voltage();
 	omap3logic_i2c_init();
-	omap_serial_init();
+	omap_serial_init(NULL);
 	board_mmc_init();
 	board_smsc911x_init();
 
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 07dba88..ef9ba3e 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -48,6 +48,7 @@
 #include <plat/usb.h>
 #include <plat/display.h>
 #include <plat/nand.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -702,7 +703,7 @@ static void __init omap3pandora_init(void)
 	platform_add_devices(omap3pandora_devices,
 			ARRAY_SIZE(omap3pandora_devices));
 	omap_display_init(&pandora_dss_data);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	spi_register_board_info(omap3pandora_spi_board_info,
 			ARRAY_SIZE(omap3pandora_spi_board_info));
 	omap3pandora_ads7846_init();
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 848016c..de234c0 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -41,6 +41,7 @@
 #include <plat/usb.h>
 #include <plat/display.h>
 #include <plat/panel-generic-dpi.h>
+#include <plat/omap-serial.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -605,7 +606,7 @@ static void __init omap3_stalker_init(void)
 	spi_register_board_info(omap3stalker_spi_board_info,
 				ARRAY_SIZE(omap3stalker_spi_board_info));
 
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
 	ads7846_dev_init();
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 127cb17..8acf724 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -48,6 +48,7 @@
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -518,7 +519,7 @@ static void __init omap3_touchbook_init(void)
 	omap3_touchbook_i2c_init();
 	platform_add_devices(omap3_touchbook_devices,
 			ARRAY_SIZE(omap3_touchbook_devices));
-	omap_serial_init();
+	omap_serial_init(NULL);
 
 	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
 	gpio_request(176, "DVI_nPD");
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index f3a7b10..68eb722 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -40,6 +40,7 @@
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
+#include <plat/omap-serial.h>
 #include <plat/panel-generic-dpi.h>
 #include "timer-gp.h"
 
@@ -577,18 +578,18 @@ static inline void board_serial_init(void)
 	bdata.pads_cnt  = 0;
 	bdata.id        = 0;
 	/* pass dummy data for UART1 */
-	omap_serial_init_port(&bdata);
+	omap_serial_init_port(&bdata, NULL);
 
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-	omap_serial_init_port(&serial4_data);
+	omap_serial_init_port(&serial2_data, NULL);
+	omap_serial_init_port(&serial3_data, NULL);
+	omap_serial_init_port(&serial4_data, NULL);
 }
 #else
 #define board_mux	NULL
 
 static inline void board_serial_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
 #endif
 
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 4016166..4944c02 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -52,6 +52,7 @@
 #include <plat/mcspi.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -653,7 +654,7 @@ static void __init overo_init(void)
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	overo_i2c_init();
 	omap_display_init(&overo_dss_data);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	overo_flash_init();
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 2af8b05..f3fa27b 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -27,6 +27,7 @@
 #include <plat/gpmc.h>
 #include <plat/common.h>
 #include <plat/onenand.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -162,7 +163,7 @@ static struct omap_musb_board_data rm680_musb_data = {
 static void __init rm680_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&rm680_musb_data);
 	rm680_peripherals_init();
 }
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index f8ba20a..8340314 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -29,6 +29,7 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 #include <plat/usb.h>
+#include <plat/omap-serial.h>
 
 #include "mux.h"
 #include "pm.h"
@@ -127,7 +128,7 @@ static void __init rx51_init(void)
 	omap_board_config = rx51_config;
 	omap_board_config_size = ARRAY_SIZE(rx51_config);
 	omap3_pm_init_cpuidle(rx51_cpuidle_params);
-	omap_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	rx51_peripherals_init();
 
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index 09fa7bf..90de40d 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -40,7 +40,7 @@ static void __init ti8168_evm_init_irq(void)
 
 static void __init ti8168_evm_init(void)
 {
-	omap_serial_init();
+	omap_serial_init(NULL);
 	omap_board_config = ti8168_evm_config;
 	omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
 }
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 8dee754..e35400c 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -26,6 +26,7 @@
 
 #include <plat/common.h>
 #include <plat/usb.h>
+#include <plat/omap-serial.h>
 
 #include <mach/board-zoom.h>
 
@@ -394,5 +395,5 @@ void __init zoom_peripherals_init(void)
 	platform_device_register(&omap_vwlan_device);
 	usb_musb_init(&musb_board_data);
 	enable_board_wakeup_source();
-	omap_serial_init();
+	omap_serial_init(NULL);
 }
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 314d82f..b1b7ad6 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -44,6 +44,15 @@
 
 static int omap_uart_con_id __initdata = -1;
 
+static struct omap_uart_port_info omap_serial_default_info[] = {
+	{
+		.dma_enabled	= 0,
+		.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
+		.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
+		.auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY,
+	},
+};
+
 static int uart_idle_hwmod(struct omap_device *od)
 {
 	omap_hwmod_idle(od->hwmods[0]);
@@ -307,6 +316,7 @@ core_initcall(omap_serial_early_init);
 /**
  * omap_serial_init_port() - initialize single serial port
  * @bdata: port specific board data pointer
+ * @info: platform specific data pointer
  *
  * This function initialies serial driver for given port only.
  * Platforms can call this function instead of omap_serial_init()
@@ -315,7 +325,8 @@ core_initcall(omap_serial_early_init);
  * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
  * use only one of the two.
  */
-void __init omap_serial_init_port(struct omap_board_data *bdata)
+void __init omap_serial_init_port(struct omap_board_data *bdata,
+			struct omap_uart_port_info *info)
 {
 	struct omap_hwmod *oh;
 	struct omap_device *od;
@@ -333,6 +344,9 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	if (!oh)
 		return;
 
+	if (info == NULL)
+		info = omap_serial_default_info;
+
 	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
 		pr_err("Memory allocation for UART pdata failed\n");
@@ -348,6 +362,10 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
 	pdata->flags = UPF_BOOT_AUTOCONF;
 	pdata->enable_wakeup = omap_uart_wakeup_enable;
+	pdata->dma_enabled = info->dma_enabled;
+	pdata->dma_rx_buf_size = info->dma_rx_buf_size;
+	pdata->dma_rx_timeout = info->dma_rx_timeout;
+	pdata->auto_sus_timeout = info->auto_sus_timeout;
 	if (bdata->id == omap_uart_con_id)
 		pdata->console_uart = true;
 
@@ -366,16 +384,20 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 /**
  * omap_serial_init() - initialize all supported serial ports
+ * @info: platform specific data pointer
  *
  * Initializes all available UARTs as serial ports. Platforms
  * can call this function when they want to have default behaviour
  * for serial ports (e.g initialize them all as serial ports).
  */
-void __init omap_serial_init(void)
+void __init omap_serial_init(struct omap_uart_port_info *info)
 {
 	struct omap_board_data bdata;
 	u8 i;
 
+	if (info == NULL)
+		info = omap_serial_default_info;
+
 	for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
 		bdata.id = i;
 		bdata.flags = 0;
@@ -384,5 +406,7 @@ void __init omap_serial_init(void)
 
 		if (cpu_is_omap44xx() || cpu_is_omap34xx())
 			omap_serial_fill_default_pads(&bdata);
+
+		omap_serial_init_port(&bdata, info);
 	}
 }
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index ac30de8..4e2dcdc 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -51,7 +51,12 @@
 
 #define OMAP_UART_DMA_CH_FREE	-1
 
-#define RX_TIMEOUT		(3 * HZ)
+#define RX_TIMEOUT		(3 * HZ)	/* RX DMA timeout (jiffies) */
+#define DEFAULT_RXDMA_TIMEOUT	1		/* RX DMA polling rate (us) */
+#define DEFAULT_RXDMA_BUFSIZE	4096		/* RX DMA buffer size */
+#define DEFAULT_AUTOSUSPEND_DELAY (30 * HZ) /* Runtime autosuspend (msecs) */
+
+
 #define OMAP_MAX_HSUART_PORTS	4
 
 #define MSR_SAVE_FLAGS		UART_MSR_ANY_DELTA
@@ -64,6 +69,9 @@ struct omap_uart_port_info {
 	upf_t			flags;		/* UPF_* flags */
 	unsigned int		errata;
 	unsigned int		console_uart;
+	unsigned int		dma_rx_buf_size;/* DMA Rx Buffer Size */
+	unsigned int		dma_rx_timeout;	/* DMA RX timeout */
+	unsigned int		auto_sus_timeout; /* Auto_suspend timeout */
 
 	void (*enable_wakeup)(struct platform_device *, bool);
 	void __iomem *wk_st;
@@ -92,8 +100,8 @@ struct uart_omap_dma {
 	spinlock_t		rx_lock;
 	/* timer to poll activity on rx dma */
 	struct timer_list	rx_timer;
-	int			rx_buf_size;
-	int			rx_timeout;
+	unsigned int		rx_buf_size;
+	unsigned int		rx_timeout;
 };
 
 struct uart_omap_port {
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index ab1761a..a18668d 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -103,9 +103,11 @@
 #ifndef __ASSEMBLER__
 
 struct omap_board_data;
+struct omap_uart_port_info;
 
-extern void omap_serial_init(void);
-extern void omap_serial_init_port(struct omap_board_data *bdata);
+extern void omap_serial_init(struct omap_uart_port_info *platform_data);
+extern void omap_serial_init_port(struct omap_board_data *bdata,
+		struct omap_uart_port_info *platform_data);
 #endif
 
 #endif
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index b275321..c525537 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -44,8 +44,6 @@
 #include <plat/omap-serial.h>
 #include <plat/omap_device.h>
 
-#define OMAP_UART_AUTOSUSPEND_DELAY (30 * HZ) /* Value is msecs */
-
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
@@ -1386,8 +1384,8 @@ static int serial_omap_probe(struct platform_device *pdev)
 		up->uart_dma.uart_dma_tx = dma_tx->start;
 		up->uart_dma.uart_dma_rx = dma_rx->start;
 		up->use_dma = 1;
-		up->uart_dma.rx_buf_size = 4096;
-		up->uart_dma.rx_timeout = 2;
+		up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size;
+		up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout;
 		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;
@@ -1396,7 +1394,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev,
-			OMAP_UART_AUTOSUSPEND_DELAY);
+			omap_up_info->auto_sus_timeout);
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_irq_safe(&pdev->dev);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 08/12] Serial: OMAP2+: Make the RX_TIMEOUT for DMA configurable for each UART
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (6 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 09/12] OMAP3: Serial: Remove uart pads from 3430 board file Govindraj.R
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Jon Hunter, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak, Govindraj.R

From: Jon Hunter <jon-hunter@ti.com>

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.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c                  |    2 ++
 arch/arm/plat-omap/include/plat/omap-serial.h |    6 ++++--
 drivers/tty/serial/omap-serial.c              |   15 ++++++++-------
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b1b7ad6..84f3ad1 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -48,6 +48,7 @@ static struct omap_uart_port_info omap_serial_default_info[] = {
 	{
 		.dma_enabled	= 0,
 		.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
+		.dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
 		.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
 		.auto_sus_timeout = DEFAULT_AUTOSUSPEND_DELAY,
 	},
@@ -364,6 +365,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 	pdata->enable_wakeup = omap_uart_wakeup_enable;
 	pdata->dma_enabled = info->dma_enabled;
 	pdata->dma_rx_buf_size = info->dma_rx_buf_size;
+	pdata->dma_rx_poll_rate = info->dma_rx_poll_rate;
 	pdata->dma_rx_timeout = info->dma_rx_timeout;
 	pdata->auto_sus_timeout = info->auto_sus_timeout;
 	if (bdata->id == omap_uart_con_id)
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 4e2dcdc..c5f4dd9 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -51,8 +51,8 @@
 
 #define OMAP_UART_DMA_CH_FREE	-1
 
-#define RX_TIMEOUT		(3 * HZ)	/* RX DMA timeout (jiffies) */
-#define DEFAULT_RXDMA_TIMEOUT	1		/* RX DMA polling rate (us) */
+#define DEFAULT_RXDMA_TIMEOUT	(3 * HZ)	/* RX DMA timeout (jiffies) */
+#define DEFAULT_RXDMA_POLLRATE	1		/* RX DMA polling rate (us) */
 #define DEFAULT_RXDMA_BUFSIZE	4096		/* RX DMA buffer size */
 #define DEFAULT_AUTOSUSPEND_DELAY (30 * HZ) /* Runtime autosuspend (msecs) */
 
@@ -71,6 +71,7 @@ struct omap_uart_port_info {
 	unsigned int		console_uart;
 	unsigned int		dma_rx_buf_size;/* DMA Rx Buffer Size */
 	unsigned int		dma_rx_timeout;	/* DMA RX timeout */
+	unsigned int		dma_rx_poll_rate; /* DMA RX timeout */
 	unsigned int		auto_sus_timeout; /* Auto_suspend timeout */
 
 	void (*enable_wakeup)(struct platform_device *, bool);
@@ -101,6 +102,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;
 };
 
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index c525537..9ed993c 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -48,7 +48,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 omap_uart_mdr1_errataset(struct uart_omap_port *up);
 
@@ -543,7 +543,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,
@@ -1162,7 +1162,7 @@ static int serial_omap_resume(struct device *dev)
 	return 0;
 }
 
-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;
@@ -1172,9 +1172,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);
@@ -1204,7 +1204,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;
 }
@@ -1246,7 +1246,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;
 }
@@ -1386,6 +1386,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;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 09/12] OMAP3: Serial: Remove uart pads from 3430 board file.
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (7 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 08/12] Serial: OMAP2+: Make the RX_TIMEOUT for DMA configurable for each UART Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup Govindraj.R
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

The pad values here are same as the default pad values updated in serial.c file.
Avoid structure duplication and use default pads.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c |  100 +----------------------------------
 1 files changed, 1 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 7912174..7dab960 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -651,106 +651,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
-
-static struct omap_device_pad serial1_pads[] __initdata = {
-	/*
-	 * Note that off output enable is an active low
-	 * signal. So setting this means pin is a
-	 * input enabled in off mode
-	 */
-	OMAP_MUX_STATIC("uart1_cts.uart1_cts",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_rts.uart1_rts",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_rx.uart1_rx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_tx.uart1_tx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial2_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-			 OMAP_PIN_INPUT_PULLUP |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-			 OMAP_PIN_INPUT_PULLDOWN |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial1_data = {
-	.id		= 0,
-	.pads		= serial1_pads,
-	.pads_cnt	= ARRAY_SIZE(serial1_pads),
-};
-
-static struct omap_board_data serial2_data = {
-	.id		= 1,
-	.pads		= serial2_pads,
-	.pads_cnt	= ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data = {
-	.id		= 2,
-	.pads		= serial3_pads,
-	.pads_cnt	= ARRAY_SIZE(serial3_pads),
-};
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init_port(&serial1_data, NULL);
-	omap_serial_init_port(&serial2_data, NULL);
-	omap_serial_init_port(&serial3_data, NULL);
-}
 #else
 #define board_mux	NULL
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init(NULL);
-}
 #endif
 
 /*
@@ -895,7 +797,7 @@ static void __init omap_3430sdp_init(void)
 	spi_register_board_info(sdp3430_spi_board_info,
 				ARRAY_SIZE(sdp3430_spi_board_info));
 	ads7846_dev_init();
-	board_serial_init();
+	omap_serial_init(NULL);
 	usb_musb_init(&musb_board_data);
 	board_smc91x_init();
 	board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup.
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (8 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 09/12] OMAP3: Serial: Remove uart pads from 3430 board file Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-04 23:59   ` Kevin Hilman
  2011-04-29 12:39 ` [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart Govindraj.R
  2011-04-29 12:39 ` [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag Govindraj.R
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Add api to enable io_pad wakeup based on mux dynamic pad and
wake_up enable flag initialized during hwmod_mux.

Use the wakeup flag and pad_remux flag and enable wakeup capability
for the pad having these flags enabled.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c              |   34 +++++++++++++++++++++++++
 arch/arm/mach-omap2/serial.c                  |    6 ++++
 arch/arm/plat-omap/include/plat/omap_device.h |    1 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
 arch/arm/plat-omap/omap_device.c              |   26 +++++++++++++++++++
 5 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e034294..4a12336 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2369,3 +2369,37 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
+
+/**
+ * omap_hwmod_enable_ioring_wakeup - Set wakeup bit for iopad ring.
+ * @oh: struct omap_hwmod *
+ * @enable: based on 0 or 1 set or unset wakeup bit.
+ *
+ * traverse through dynamic pads. If pad is enabled then
+ * set wakeup bit for the mux pin. Return error if pads are
+ * not enabled or not available.
+ */
+int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable)
+{
+	struct omap_device_pad *pad;
+	int ret = -EINVAL, j;
+	int val = 0;
+
+	/* Enable pin mux to make pad wake-up capable */
+	if (enable)
+		val = OMAP_WAKEUP_EN;
+	else
+		val = ~OMAP_WAKEUP_EN;
+
+	if (oh->mux->enabled) {
+		for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
+			pad = oh->mux->pads_dynamic[j];
+			if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+				pad->idle = pad->enable | val;
+				ret = 0;
+			}
+		}
+	}
+
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 84f3ad1..5b2bdf8 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -212,6 +212,12 @@ static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
 			v &= ~up->wk_mask;
 		__raw_writel(v, up->wk_en);
 	}
+
+	/* Enable or clear io-pad wakeup */
+	if (enable)
+		omap_device_enable_ioring_wakeup(pdev, true);
+	else
+		omap_device_enable_ioring_wakeup(pdev, false);
 }
 
 static void omap_uart_idle_init(struct omap_uart_port_info *uart,
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..ce8e3e8 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -117,6 +117,7 @@ int omap_device_enable_hwmods(struct omap_device *od);
 int omap_device_disable_clocks(struct omap_device *od);
 int omap_device_enable_clocks(struct omap_device *od);
 
+int omap_device_enable_ioring_wakeup(struct platform_device *pdev, bool enable);
 
 /*
  * Entries should be kept in latency order ascending
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c..b7f8d1b 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -601,6 +601,7 @@ int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
 u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
+int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable);
 
 /*
  * Chip variant-specific hwmod init routines - XXX should be converted
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f7c6dca..7df74ba 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -742,6 +742,32 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
 	return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
 }
 
+/**
+ * omap_device_enable_ioring_wakeup - Set wakeup bit for iopad ring.
+ * @pdev: platform_device for which wakeup needs to be set.
+ * @enable: based on 0 or 1 set or unset wakeup bit.
+ *
+ * Caller should ensure this is called if device_may_wakeup(dev) is true
+ * traverse through each hwmod and check each available pads
+ * if pad is enabled then set wakeup bit for the mux pin.
+ * Return error if pads are not enabled or not available.
+ * If pad is not enabled for the given device then return NULL.
+ */
+int omap_device_enable_ioring_wakeup(struct platform_device *pdev, bool enable)
+{
+	int ret = -EINVAL, i;
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+
+	od = _find_by_pdev(pdev);
+	for (i = 0; i < od->hwmods_cnt; i++) {
+		oh = od->hwmods[i];
+		ret = omap_hwmod_enable_ioring_wakeup(oh, enable);
+	}
+
+	return ret;
+}
+
 /*
  * Public functions intended for use in omap_device_pm_latency
  * .activate_func and .deactivate_func function pointers
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (9 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-05  0:11   ` Kevin Hilman
  2011-04-29 12:39 ` [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag Govindraj.R
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

Use resume idle call from prcm_irq to enable uart_port from low power states.
Add api to check pad wakeup status which will we used from uart_resume func.
to enable back uart port if a wakeup event occurred.

UART_Resume func. can be removed once we have irq_chaining functionality
available.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/mux.c                     |   23 +++++++++++++++++++++++
 arch/arm/mach-omap2/mux.h                     |   13 +++++++++++++
 arch/arm/mach-omap2/omap_hwmod.c              |   13 +++++++++++++
 arch/arm/mach-omap2/pm24xx.c                  |    2 ++
 arch/arm/mach-omap2/pm34xx.c                  |    2 ++
 arch/arm/mach-omap2/serial.c                  |   23 +++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/omap-serial.h |    2 ++
 arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
 arch/arm/plat-omap/include/plat/serial.h      |    1 +
 drivers/tty/serial/omap-serial.c              |   23 +++++++++++++++++++++++
 10 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index a4ab1e3..7149671 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -348,6 +348,29 @@ err1:
 	return NULL;
 }
 
+/* Gets the wakeup status of given pad from omap-hwmod.
+ * Returns the wake_up status bit of available pad mux pin
+ */
+bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)
+{
+	int i;
+	unsigned int val;
+	u8 ret = 0;
+
+	for (i = 0; i < hmux->nr_pads; i++) {
+		struct omap_device_pad *pad = &hmux->pads[i];
+
+		val = omap_mux_read(pad->partition,
+					pad->mux->reg_offset);
+		if (val & OMAP_WAKEUP_EVENT) {
+			ret = 1;
+			break;
+		}
+	}
+
+	return ret;
+}
+
 /* Assumes the calling function takes care of locking */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 137f321..379fb6e 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -225,8 +225,21 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
  */
 void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
 
+
+/**
+ * omap_hwmod_mux_wakeup - omap hwmod check given pad had wakeup event
+ * @hmux:		Pads for a hwmod
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux);
 #else
 
+static inline bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)
+{
+	return 0;
+}
+
 static inline int omap_mux_init_gpio(int gpio, int val)
 {
 	return 0;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 4a12336..86cb8c4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2403,3 +2403,16 @@ int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable)
 
 	return ret;
 }
+
+/**
+ * omap_hwmod_pad_wakeup_status - get pad wakeup status if mux is available.
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the wake_up status bit of available pad mux pin.
+ */
+int omap_hmwod_pad_wakeup_status(struct omap_hwmod *oh)
+{
+	if (oh->mux)
+		return omap_hwmod_mux_wakeup(oh->mux);
+	return -EINVAL;
+}
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index c405bda..ba58a1d 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -137,6 +137,8 @@ static void omap2_enter_full_retention(void)
 			   OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
 			   OMAP_SDRC_REGADDR(SDRC_POWER));
 
+	omap_uart_resume_idle();
+
 no_sleep:
 	if (omap2_pm_debug) {
 		unsigned long long tmp;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ce0ecdc..3960330 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -216,6 +216,8 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 
 	wkst = omap2_prm_read_mod_reg(module, wkst_off);
 	wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
+
+	c += omap_uart_resume_idle();
 	if (wkst) {
 		iclk = omap2_cm_read_mod_reg(module, iclk_off);
 		fclk = omap2_cm_read_mod_reg(module, fclk_off);
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 5b2bdf8..d4ef370 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -199,6 +199,28 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 	}
 }
 
+/* TBD: Will be removed once we have irq-chaing mechanism */
+static bool omap_uart_chk_wakeup(struct platform_device *pdev)
+{
+	struct omap_uart_port_info *up = pdev->dev.platform_data;
+	struct omap_device *od;
+	u32 wkst = 0;
+	bool ret = false;
+
+	od = to_omap_device(pdev);
+	if (omap_hmwod_pad_wakeup_status(od->hwmods[0]))
+		ret = true;
+
+	/* Check for normal UART wakeup (and clear it) */
+	wkst = __raw_readl(up->wk_st) & up->wk_mask;
+	if (wkst) {
+		__raw_writel(wkst, up->wk_st);
+		ret = true;
+	}
+
+	return ret;
+}
+
 static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
 {
 	struct omap_uart_port_info *up = pdev->dev.platform_data;
@@ -369,6 +391,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
 	pdata->flags = UPF_BOOT_AUTOCONF;
 	pdata->enable_wakeup = omap_uart_wakeup_enable;
+	pdata->chk_wakeup = omap_uart_chk_wakeup;
 	pdata->dma_enabled = info->dma_enabled;
 	pdata->dma_rx_buf_size = info->dma_rx_buf_size;
 	pdata->dma_rx_poll_rate = info->dma_rx_poll_rate;
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index c5f4dd9..b5117bd 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -75,6 +75,7 @@ struct omap_uart_port_info {
 	unsigned int		auto_sus_timeout; /* Auto_suspend timeout */
 
 	void (*enable_wakeup)(struct platform_device *, bool);
+	bool (*chk_wakeup)(struct platform_device *);
 	void __iomem *wk_st;
 	void __iomem *wk_en;
 	u32 wk_mask;
@@ -132,6 +133,7 @@ struct uart_omap_port {
 	unsigned long		port_activity;
 	unsigned int		errata;
 	void (*enable_wakeup)(struct platform_device *, bool);
+	bool (*chk_wakeup)(struct platform_device *);
 };
 
 #endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b7f8d1b..6e60708 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -603,6 +603,7 @@ u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable);
 
+int omap_hmwod_pad_wakeup_status(struct omap_hwmod *oh);
 /*
  * Chip variant-specific hwmod init routines - XXX should be converted
  * to use initcalls once the initial boot ordering is straightened out
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index a18668d..f2e4ae3 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -108,6 +108,7 @@ struct omap_uart_port_info;
 extern void omap_serial_init(struct omap_uart_port_info *platform_data);
 extern void omap_serial_init_port(struct omap_board_data *bdata,
 		struct omap_uart_port_info *platform_data);
+extern u32 omap_uart_resume_idle(void);
 #endif
 
 #endif
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 9ed993c..eea478c 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -43,6 +43,7 @@
 #include <plat/dmtimer.h>
 #include <plat/omap-serial.h>
 #include <plat/omap_device.h>
+#include <plat/serial.h>
 
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
@@ -108,6 +109,27 @@ static inline void serial_omap_port_enable(struct uart_omap_port *up)
 	pm_runtime_get_sync(&up->pdev->dev);
 }
 
+/* TBD: Should be removed once we irq-chaining mechanism in place */
+u32 omap_uart_resume_idle()
+{
+	int i;
+	u32 ret = 0;
+
+	for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
+		struct uart_omap_port *up = ui[i];
+
+		if (!up)
+			continue;
+
+		if (up->chk_wakeup(up->pdev)) {
+			serial_omap_port_enable(up);
+			serial_omap_port_disable(up);
+			ret++;
+		}
+	}
+	return ret;
+}
+
 static void serial_omap_stop_rxdma(struct uart_omap_port *up)
 {
 	if (up->uart_dma.rx_dma_used) {
@@ -1379,6 +1401,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 	up->uart_dma.uart_base = mem->start;
 	up->errata = omap_up_info->errata;
 	up->enable_wakeup = omap_up_info->enable_wakeup;
+	up->chk_wakeup = omap_up_info->chk_wakeup;
 
 	if (omap_up_info->dma_enabled) {
 		up->uart_dma.uart_dma_tx = dma_tx->start;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag.
  2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
                   ` (10 preceding siblings ...)
  2011-04-29 12:39 ` [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart Govindraj.R
@ 2011-04-29 12:39 ` Govindraj.R
  2011-05-05 17:32   ` Kevin Hilman
  11 siblings, 1 reply; 40+ messages in thread
From: Govindraj.R @ 2011-04-29 12:39 UTC (permalink / raw)
  To: linux-omap, linux-serial, linux-arm-kernel
  Cc: Govindraj.R, Tony Lindgren, Benoit Cousson, Kevin Hilman,
	Paul Walmsley, Rajendra Nayak

For omap2 cpu_idle thread will not be available
and uart_clock cutting happens only in suspend path.

Prior to this patch the uart_clock was cut using prepare/resume
calls since these funcs are no more available with runtime
changes use no_async_wake flag to keep clock active during bootup
otherwise uart port will disabled during boot-up and cannot be
enabled back.
Also based on this flag we can disable uart port during suspend
and enable back during resume.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c                  |    7 +++++++
 arch/arm/plat-omap/include/plat/omap-serial.h |    3 +++
 drivers/tty/serial/omap-serial.c              |   14 ++++++++++++++
 3 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index d4ef370..1af9fd5 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -245,6 +245,12 @@ static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
 static void omap_uart_idle_init(struct omap_uart_port_info *uart,
 				unsigned short num)
 {
+	/* On omap2 no cpu_idle and async wakeup from prcm_module.
+	 * This flag can be used to cut clocks only in suspend path.
+	 * to avoid boot break due to aggressive clock cutting from
+	 * omap-serial driver.
+	 */
+	uart->no_async_wake = true;
 	if (cpu_is_omap34xx()) {
 		u32 mod = num > 1 ? OMAP3430_PER_MOD : CORE_MOD;
 		u32 wk_mask = 0;
@@ -266,6 +272,7 @@ static void omap_uart_idle_init(struct omap_uart_port_info *uart,
 			break;
 		}
 		uart->wk_mask = wk_mask;
+		uart->no_async_wake = false;
 	} else if (cpu_is_omap24xx()) {
 		u32 wk_mask = 0;
 		u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index b5117bd..1de5bc4 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -79,6 +79,7 @@ struct omap_uart_port_info {
 	void __iomem *wk_st;
 	void __iomem *wk_en;
 	u32 wk_mask;
+	bool			no_async_wake;
 };
 
 struct uart_omap_dma {
@@ -134,6 +135,8 @@ struct uart_omap_port {
 	unsigned int		errata;
 	void (*enable_wakeup)(struct platform_device *, bool);
 	bool (*chk_wakeup)(struct platform_device *);
+
+	bool			no_async_wake;
 };
 
 #endif /* __OMAP_SERIAL_H__ */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index eea478c..59f548f 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1168,6 +1168,13 @@ static int serial_omap_suspend(struct device *dev)
 		uart_suspend_port(&serial_omap_reg, &up->port);
 		console_trylock();
 		serial_omap_pm(&up->port, 3, 0);
+
+		/* OMAP2 dont have cpu_idle thread and async wakeup from prcm.
+		 * For such socs clocks will be kept active from probe and
+		 * cut only in suspend path.
+		 */
+		if (up->no_async_wake)
+			serial_omap_port_disable(up);
 	}
 	return 0;
 }
@@ -1179,6 +1186,9 @@ static int serial_omap_resume(struct device *dev)
 	if (up) {
 		uart_resume_port(&serial_omap_reg, &up->port);
 		console_unlock();
+
+		if (up->no_async_wake)
+			serial_omap_port_enable(up);
 	}
 
 	return 0;
@@ -1402,6 +1412,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 	up->errata = omap_up_info->errata;
 	up->enable_wakeup = omap_up_info->enable_wakeup;
 	up->chk_wakeup = omap_up_info->chk_wakeup;
+	up->no_async_wake = omap_up_info->no_async_wake;
 
 	if (omap_up_info->dma_enabled) {
 		up->uart_dma.uart_dma_tx = dma_tx->start;
@@ -1430,6 +1441,9 @@ static int serial_omap_probe(struct platform_device *pdev)
 		serial_omap_port_disable(up);
 	}
 
+	if (up->no_async_wake)
+		serial_omap_port_enable(up);
+
 	ui[pdev->id] = up;
 	serial_omap_add_console_port(up);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* OMAP2+: UART: Remove uart clock handling code from serial.c
  2011-04-29 12:39 ` [PATCH v2 02/12] OMAP2+: UART: Remove uart clock handling code from serial.c Govindraj.R
@ 2011-04-29 13:20   ` Alan Cox
  0 siblings, 0 replies; 40+ messages in thread
From: Alan Cox @ 2011-04-29 13:20 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Kevin Hilman, Paul Walmsley, Rajendra Nayak

On Fri, 29 Apr 2011 18:09:46 +0530
"Govindraj.R" <govindraj.raja@ti.com> wrote:

> Cleanup serial.c file in preparation to addition of runtime api's in omap-serial
> file. Remove all clock handling mechanism as this will be taken care with
> pm runtime api's in omap-serial.c file itself.
> 
> 1.) Remove omap-device enable and disable. We can can use get_sync/put_sync api's
> 2.) Remove context save/restore can be done with runtime_resume callback for
>     get_sync call. No need to save context as all reg details available in
>     uart_port structure can be used for restore, so add missing regs in
>     uart port struct.
> 3.) Add func to identify console uart.
> 4.) Erratum handling informed as flag to driver and func to handle erratum
>     can be moved to omap-serial driver itself.
> 
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

The tty parts of this look fine, the OMAP bits I have no idea.

So for the tty bits with my serial maintainer hat on

Acked-by: Alan Cox <alan@linux.intel.com>

but its mostly up to the ARM/OMAP people

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file
  2011-04-29 12:39 ` [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file Govindraj.R
@ 2011-05-04  9:55   ` Tony Lindgren
  2011-05-04 10:06     ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-05-04  9:55 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Deepak K,
	Benoit Cousson, Kevin Hilman, Paul Walmsley, Rajendra Nayak,
	Jon Hunter

* Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
> @@ -250,7 +251,7 @@ static void __init omap_2430sdp_init(void)
>  	omap2430_i2c_init();
>  
>  	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
> -	omap_serial_init();
> +	omap_serial_init(NULL);
>  	omap2_hsmmc_init(mmc);
>  	omap2_usbfs_init(&sdp2430_usb_config);
...
  
>  static inline void board_serial_init(void)
>  {
> -	omap_serial_init();
> +	omap_serial_init(NULL);
>  }

This change seems like "crazy churn" and probably not needed
if it's always null. Boards using platform_data can use
omap_serial_init_port instead, right?  

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts.
  2011-04-29 12:39 ` [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts Govindraj.R
@ 2011-05-04 10:00   ` Tony Lindgren
  2011-05-04 10:34     ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-05-04 10:00 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Benoit Cousson,
	Kevin Hilman, Paul Walmsley, Rajendra Nayak

* Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
> Add default mux data for all uarts if mux info is not passed from
> board file to avoid breaking any board support.

This should only happen if omap_serial_init is called,
then boards can still use platform data with omap_serial_init_port.
 
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -66,6 +66,129 @@ static struct omap_device_pm_latency omap_uart_latency[] = {
>  	},
>  };
>  
> +#ifdef CONFIG_OMAP_MUX
> +static struct omap_device_pad default_uart1_pads[] __initdata = {
> +	{
> +		.name	= "uart1_cts.uart1_cts",
> +		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart1_rts.uart1_rts",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart1_tx.uart1_tx",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart1_rx.uart1_rx",
> +		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
> +		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
> +	},
> +};
> +
> +static struct omap_device_pad default_uart2_pads[] __initdata = {
> +	{
> +		.name	= "uart2_cts.uart2_cts",
> +		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart2_rts.uart2_rts",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart2_tx.uart2_tx",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart2_rx.uart2_rx",
> +		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
> +		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
> +	},
> +};
> +
> +static struct omap_device_pad default_uart3_pads[] __initdata = {
> +	{
> +		.name	= "uart3_cts_rctx.uart3_cts_rctx",
> +		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart3_rts_sd.uart3_rts_sd",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart3_tx_irtx.uart3_tx_irtx",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart3_rx_irrx.uart3_rx_irrx",
> +		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
> +		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
> +	},
> +};
> +
> +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
> +	{
> +		.name   = "gpmc_wait2.uart4_tx",
> +		.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "gpmc_wait3.uart4_rx",
> +		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
> +		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE2,
> +	},
> +};
> +
> +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
> +	{
> +		.name	= "uart4_tx.uart4_tx",
> +		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
> +	},
> +	{
> +		.name	= "uart4_rx.uart4_rx",
> +		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
> +		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
> +	},

Looks like you could easily allocate the struct and use sprintf
to generate this as needed to avoid duplication.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-04-29 12:39 ` [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage Govindraj.R
@ 2011-05-04 10:02   ` Tony Lindgren
  2011-05-04 10:09     ` Russell King - ARM Linux
  2011-05-04 10:19     ` Govindraj
  2011-05-04 20:43   ` Kevin Hilman
  1 sibling, 2 replies; 40+ messages in thread
From: Tony Lindgren @ 2011-05-04 10:02 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Benoit Cousson,
	Kevin Hilman, Paul Walmsley, Rajendra Nayak

* Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
>
> Also during bootup console_lock is not available.
>        --> uart_add_one_port
> 	   --> console_register
> 	       --> console_lock
> 	        --> console_unlock
> 	             --> call_console_drivers (here yet console_lock is not released)
> 		          --> uart_console_write
> 
> Hence convert prints from omap_device_enable/disable to pr_debug.

This sounds like a hack considering we have things working with
pr_debug currently.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file
  2011-05-04  9:55   ` Tony Lindgren
@ 2011-05-04 10:06     ` Govindraj
  2011-05-04 10:25       ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Govindraj @ 2011-05-04 10:06 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Deepak K, Benoit Cousson, Kevin Hilman, Paul Walmsley,
	Rajendra Nayak, Jon Hunter

On Wed, May 4, 2011 at 3:25 PM, Tony Lindgren <tony@atomide.com> wrote:
> * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
>> @@ -250,7 +251,7 @@ static void __init omap_2430sdp_init(void)
>>       omap2430_i2c_init();
>>
>>       platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
>> -     omap_serial_init();
>> +     omap_serial_init(NULL);
>>       omap2_hsmmc_init(mmc);
>>       omap2_usbfs_init(&sdp2430_usb_config);
> ...
>
>>  static inline void board_serial_init(void)
>>  {
>> -     omap_serial_init();
>> +     omap_serial_init(NULL);
>>  }
>
> This change seems like "crazy churn" and probably not needed
> if it's always null. Boards using platform_data can use
> omap_serial_init_port instead, right?

We can intiliaze only one uart port with omap_serial_init_port.

omap_serial_init initializes all uart port.

During any client device integration using dma mode
(for example Bluetooth) we can pass the dma config
params based on the board & client device.

--
Govindraj.R


>
> Tony
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-05-04 10:02   ` Tony Lindgren
@ 2011-05-04 10:09     ` Russell King - ARM Linux
  2011-05-04 10:19     ` Govindraj
  1 sibling, 0 replies; 40+ messages in thread
From: Russell King - ARM Linux @ 2011-05-04 10:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Govindraj.R, Kevin Hilman, Paul Walmsley, Benoit Cousson,
	Rajendra Nayak, linux-serial, linux-omap, linux-arm-kernel

On Wed, May 04, 2011 at 03:02:33AM -0700, Tony Lindgren wrote:
> * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
> >
> > Also during bootup console_lock is not available.
> >        --> uart_add_one_port
> > 	   --> console_register
> > 	       --> console_lock
> > 	        --> console_unlock
> > 	             --> call_console_drivers (here yet console_lock is not released)
> > 		          --> uart_console_write
> > 
> > Hence convert prints from omap_device_enable/disable to pr_debug.
> 
> This sounds like a hack considering we have things working with
> pr_debug currently.

It also highlights a different problem: stuffing subsystems full of
debug, and keeping it way after the subsystem has been brought to a
working state not only adds code bloat but also can cause additional
bugs.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-05-04 10:02   ` Tony Lindgren
  2011-05-04 10:09     ` Russell King - ARM Linux
@ 2011-05-04 10:19     ` Govindraj
  1 sibling, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-04 10:19 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Benoit Cousson, Kevin Hilman, Paul Walmsley, Rajendra Nayak

On Wed, May 4, 2011 at 3:32 PM, Tony Lindgren <tony@atomide.com> wrote:
> * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
>>
>> Also during bootup console_lock is not available.
>>        --> uart_add_one_port
>>          --> console_register
>>              --> console_lock
>>               --> console_unlock
>>                    --> call_console_drivers (here yet console_lock is not released)
>>                         --> uart_console_write
>>
>> Hence convert prints from omap_device_enable/disable to pr_debug.
>
> This sounds like a hack considering we have things working with
> pr_debug currently.

The reason it works currently is because we are aquiring console
lock in omap_serial_init since with the patch series cleanup and
things are moving to driver I see this issue.

The issue is due to recursive prints because of get_sync/put_sync
printing active/deactivate latency from omap_device layer.

During printk -> uart_console_write -->
we do get_sync and if clock is cut and omap_device_enable
gets called and omap_device_enable trying to pr_warn
activate latency.
Here we end up in recursive lock up from printk.

--
Thanks,
Govindraj.R

>
> Tony
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file
  2011-05-04 10:06     ` Govindraj
@ 2011-05-04 10:25       ` Tony Lindgren
  2011-05-04 10:39         ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-05-04 10:25 UTC (permalink / raw)
  To: Govindraj
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Deepak K, Benoit Cousson, Kevin Hilman, Paul Walmsley,
	Rajendra Nayak, Jon Hunter

* Govindraj <govindraj.ti@gmail.com> [110504 03:03]:
> On Wed, May 4, 2011 at 3:25 PM, Tony Lindgren <tony@atomide.com> wrote:
> > * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
> >> @@ -250,7 +251,7 @@ static void __init omap_2430sdp_init(void)
> >>       omap2430_i2c_init();
> >>
> >>       platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
> >> -     omap_serial_init();
> >> +     omap_serial_init(NULL);
> >>       omap2_hsmmc_init(mmc);
> >>       omap2_usbfs_init(&sdp2430_usb_config);
> > ...
> >
> >>  static inline void board_serial_init(void)
> >>  {
> >> -     omap_serial_init();
> >> +     omap_serial_init(NULL);
> >>  }
> >
> > This change seems like "crazy churn" and probably not needed
> > if it's always null. Boards using platform_data can use
> > omap_serial_init_port instead, right?
> 
> We can intiliaze only one uart port with omap_serial_init_port.
> 
> omap_serial_init initializes all uart port.
> 
> During any client device integration using dma mode
> (for example Bluetooth) we can pass the dma config
> params based on the board & client device.

But you're changing all omap_serial_init() calls to
omap_serial_init(NULL) so there are no users for that.

It should be a separate patch if it's needed.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts.
  2011-05-04 10:00   ` Tony Lindgren
@ 2011-05-04 10:34     ` Govindraj
  0 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-04 10:34 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Benoit Cousson, Kevin Hilman, Paul Walmsley, Rajendra Nayak

On Wed, May 4, 2011 at 3:30 PM, Tony Lindgren <tony@atomide.com> wrote:
> * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
>> Add default mux data for all uarts if mux info is not passed from
>> board file to avoid breaking any board support.
>
> This should only happen if omap_serial_init is called,
> then boards can still use platform data with omap_serial_init_port.

Yes correct thats how its designed with this patch series.
One can use omap_serial_init to initialize all uarts
or use omap_serial_init_port for individual uart.

Default pads are filled only if board uses omap_serial_init(NULL);
to initialize all uarts.

>
>> --- a/arch/arm/mach-omap2/serial.c
>> +++ b/arch/arm/mach-omap2/serial.c
>> @@ -66,6 +66,129 @@ static struct omap_device_pm_latency omap_uart_latency[] = {
>>       },
>>  };
>>
>> +#ifdef CONFIG_OMAP_MUX
>> +static struct omap_device_pad default_uart1_pads[] __initdata = {
>> +     {
>> +             .name   = "uart1_cts.uart1_cts",
>> +             .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart1_rts.uart1_rts",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart1_tx.uart1_tx",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart1_rx.uart1_rx",
>> +             .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
>> +             .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
>> +     },
>> +};
>> +
>> +static struct omap_device_pad default_uart2_pads[] __initdata = {
>> +     {
>> +             .name   = "uart2_cts.uart2_cts",
>> +             .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart2_rts.uart2_rts",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart2_tx.uart2_tx",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart2_rx.uart2_rx",
>> +             .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
>> +             .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
>> +     },
>> +};
>> +
>> +static struct omap_device_pad default_uart3_pads[] __initdata = {
>> +     {
>> +             .name   = "uart3_cts_rctx.uart3_cts_rctx",
>> +             .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart3_rts_sd.uart3_rts_sd",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart3_tx_irtx.uart3_tx_irtx",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart3_rx_irrx.uart3_rx_irrx",
>> +             .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
>> +             .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
>> +     },
>> +};
>> +
>> +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
>> +     {
>> +             .name   = "gpmc_wait2.uart4_tx",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "gpmc_wait3.uart4_rx",
>> +             .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
>> +             .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
>> +     },
>> +};
>> +
>> +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
>> +     {
>> +             .name   = "uart4_tx.uart4_tx",
>> +             .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
>> +     },
>> +     {
>> +             .name   = "uart4_rx.uart4_rx",
>> +             .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
>> +             .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
>> +     },
>
> Looks like you could easily allocate the struct and use sprintf
> to generate this as needed to avoid duplication.

Only uart1/2 have common name

* uart3 having different naming pins
* uart4 doesnt have cts/rts
* uart4 on 3630 uses gpmc.wait2
* rx requires wakeup enable flag

So would again give me a function with switch case for uart1/2/3/4
which is very similar to above structs.

Thats the reson I kept individual structs.
Also becomes easy if we need to disable or avoid a
individual uart pad.

--
Thanks,
Govindraj.R


>
> Tony
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file
  2011-05-04 10:25       ` Tony Lindgren
@ 2011-05-04 10:39         ` Govindraj
  0 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-04 10:39 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Deepak K, Benoit Cousson, Kevin Hilman, Paul Walmsley,
	Rajendra Nayak, Jon Hunter

On Wed, May 4, 2011 at 3:55 PM, Tony Lindgren <tony@atomide.com> wrote:
> * Govindraj <govindraj.ti@gmail.com> [110504 03:03]:
>> On Wed, May 4, 2011 at 3:25 PM, Tony Lindgren <tony@atomide.com> wrote:
>> > * Govindraj.R <govindraj.raja@ti.com> [110429 05:39]:
>> >> @@ -250,7 +251,7 @@ static void __init omap_2430sdp_init(void)
>> >>       omap2430_i2c_init();
>> >>
>> >>       platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
>> >> -     omap_serial_init();
>> >> +     omap_serial_init(NULL);
>> >>       omap2_hsmmc_init(mmc);
>> >>       omap2_usbfs_init(&sdp2430_usb_config);
>> > ...
>> >
>> >>  static inline void board_serial_init(void)
>> >>  {
>> >> -     omap_serial_init();
>> >> +     omap_serial_init(NULL);
>> >>  }
>> >
>> > This change seems like "crazy churn" and probably not needed
>> > if it's always null. Boards using platform_data can use
>> > omap_serial_init_port instead, right?
>>
>> We can intiliaze only one uart port with omap_serial_init_port.
>>
>> omap_serial_init initializes all uart port.
>>
>> During any client device integration using dma mode
>> (for example Bluetooth) we can pass the dma config
>> params based on the board & client device.
>
> But you're changing all omap_serial_init() calls to
> omap_serial_init(NULL) so there are no users for that.
>
> It should be a separate patch if it's needed.
>

Agree.

Will add seperate func. in serial.c file for board that need to pass these
params and retain the old func. omap_serial_init() syntax to avoid all the
additions in board-*.c files.

--
Thanks,
Govindraj.R

> Tony
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver
  2011-04-29 12:39 ` [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver Govindraj.R
@ 2011-05-04 20:35   ` Kevin Hilman
  2011-05-04 21:05     ` Paul Walmsley
                       ` (2 more replies)
  0 siblings, 3 replies; 40+ messages in thread
From: Kevin Hilman @ 2011-05-04 20:35 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Paul Walmsley, Rajendra Nayak

"Govindraj.R" <govindraj.raja@ti.com> writes:

> Adapts omap-serial driver to use pm_runtime api's.
>
> 1.) Populate reg values to uart port which can be used for context restore.
> 2.) Moving context_restore func to driver from serial.c
> 3.) Adding port_enable/disable func to enable/disable given uart port.
>     enable port using get_sync and disable using autosuspend.
> 4.) using runtime irq safe api to make get_sync be called from irq context.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> ---
>  arch/arm/mach-omap2/serial.c                  |   16 ++
>  arch/arm/plat-omap/include/plat/omap-serial.h |    2 +
>  drivers/tty/serial/omap-serial.c              |  211 ++++++++++++++++++++++---
>  3 files changed, 203 insertions(+), 26 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index 8c1a4c7..314d82f 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -189,6 +189,21 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
>  	}
>  }
>  
> +static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
> +{
> +	struct omap_uart_port_info *up = pdev->dev.platform_data;
> +
> +	/* Set or clear wake-enable bit */
> +	if (up->wk_en && up->wk_mask) {
> +		u32 v = __raw_readl(up->wk_en);
> +		if (enable)
> +			v |= up->wk_mask;
> +		else
> +			v &= ~up->wk_mask;
> +		__raw_writel(v, up->wk_en);
> +	}
> +}

Rather than having the driver do this via the PRCM, can you do an
experiment?  Can you try to leave the module-level wakeup enabled all
the time in the PRCM, and the driver can then enable/disable
module-level wakeups simply by toggling ENAWAKEUP in the module's
SYSCONFIG?  If that works, than you can just use
omap_hwmod_enable_wakeup() for this and not need the above function.

>  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>  				unsigned short num)
>  {
> @@ -332,6 +347,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
>  
>  	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
>  	pdata->flags = UPF_BOOT_AUTOCONF;
> +	pdata->enable_wakeup = omap_uart_wakeup_enable;
>  	if (bdata->id == omap_uart_con_id)
>  		pdata->console_uart = true;
>  
> diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
> index 2ca885b..ac30de8 100644
> --- a/arch/arm/plat-omap/include/plat/omap-serial.h
> +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
> @@ -65,6 +65,7 @@ struct omap_uart_port_info {
>  	unsigned int		errata;
>  	unsigned int		console_uart;
>  
> +	void (*enable_wakeup)(struct platform_device *, bool);
>  	void __iomem *wk_st;
>  	void __iomem *wk_en;
>  	u32 wk_mask;
> @@ -120,6 +121,7 @@ struct uart_omap_port {
>  	char			name[20];
>  	unsigned long		port_activity;
>  	unsigned int		errata;
> +	void (*enable_wakeup)(struct platform_device *, bool);
>  };
>  
>  #endif /* __OMAP_SERIAL_H__ */
> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index 47cadf4..633dfb4 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -37,10 +37,14 @@
>  #include <linux/clk.h>
>  #include <linux/serial_core.h>
>  #include <linux/irq.h>
> +#include <linux/pm_runtime.h>
>  
>  #include <plat/dma.h>
>  #include <plat/dmtimer.h>
>  #include <plat/omap-serial.h>
> +#include <plat/omap_device.h>
> +
> +#define OMAP_UART_AUTOSUSPEND_DELAY (30 * HZ) /* Value is msecs */
>  
>  static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
>  
> @@ -94,6 +98,17 @@ serial_omap_get_divisor(struct uart_port *port, unsigned int baud)
>  	return port->uartclk/(baud * divisor);
>  }
>  
> +static inline void serial_omap_port_disable(struct uart_omap_port *up)
> +{
> +	pm_runtime_mark_last_busy(&up->pdev->dev);
> +	pm_runtime_put_autosuspend(&up->pdev->dev);
> +}
> +
> +static inline void serial_omap_port_enable(struct uart_omap_port *up)
> +{
> +	pm_runtime_get_sync(&up->pdev->dev);
> +}
> +
>  static void serial_omap_stop_rxdma(struct uart_omap_port *up)
>  {
>  	if (up->uart_dma.rx_dma_used) {
> @@ -110,8 +125,11 @@ static void serial_omap_enable_ms(struct uart_port *port)
>  	struct uart_omap_port *up = (struct uart_omap_port *)port;
>  
>  	dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id);
> +
> +	serial_omap_port_enable(up);
>  	up->ier |= UART_IER_MSI;
>  	serial_out(up, UART_IER, up->ier);
> +	serial_omap_port_disable(up);
>  }
>  
>  static void serial_omap_stop_tx(struct uart_port *port)
> @@ -131,21 +149,26 @@ static void serial_omap_stop_tx(struct uart_port *port)
>  		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
>  	}
>  
> +	serial_omap_port_enable(up);
>  	if (up->ier & UART_IER_THRI) {
>  		up->ier &= ~UART_IER_THRI;
>  		serial_out(up, UART_IER, up->ier);
>  	}
> +
> +	serial_omap_port_disable(up);
>  }
>  
>  static void serial_omap_stop_rx(struct uart_port *port)
>  {
>  	struct uart_omap_port *up = (struct uart_omap_port *)port;
>  
> +	serial_omap_port_enable(up);
>  	if (up->use_dma)
>  		serial_omap_stop_rxdma(up);
>  	up->ier &= ~UART_IER_RLSI;
>  	up->port.read_status_mask &= ~UART_LSR_DR;
>  	serial_out(up, UART_IER, up->ier);
> +	serial_omap_port_disable(up);
>  }
>  
>  static inline void receive_chars(struct uart_omap_port *up, int *status)
> @@ -261,8 +284,10 @@ static void serial_omap_start_tx(struct uart_port *port)
>  	unsigned int start;
>  	int ret = 0;
>  
> +	serial_omap_port_enable(up);
>  	if (!up->use_dma) {
>  		serial_omap_enable_ier_thri(up);
> +		serial_omap_port_disable(up);
>  		return;
>  	}
>  
> @@ -354,9 +379,12 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
>  	unsigned int iir, lsr;
>  	unsigned long flags;
>  
> +	serial_omap_port_enable(up);
>  	iir = serial_in(up, UART_IIR);
> -	if (iir & UART_IIR_NO_INT)
> +	if (iir & UART_IIR_NO_INT) {
> +		serial_omap_port_disable(up);
>  		return IRQ_NONE;
> +	}
>  
>  	spin_lock_irqsave(&up->port.lock, flags);
>  	lsr = serial_in(up, UART_LSR);
> @@ -378,6 +406,8 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
>  		transmit_chars(up);
>  
>  	spin_unlock_irqrestore(&up->port.lock, flags);
> +	serial_omap_port_disable(up);
> +
>  	up->port_activity = jiffies;
>  	return IRQ_HANDLED;
>  }
> @@ -388,11 +418,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
>  	unsigned long flags = 0;
>  	unsigned int ret = 0;
>  
> +	serial_omap_port_enable(up);
>  	dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id);
>  	spin_lock_irqsave(&up->port.lock, flags);
>  	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
>  	spin_unlock_irqrestore(&up->port.lock, flags);
> -
> +	serial_omap_port_disable(up);
>  	return ret;
>  }
>  
> @@ -402,7 +433,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)
>  	unsigned char status;
>  	unsigned int ret = 0;
>  
> +	serial_omap_port_enable(up);
>  	status = check_modem_status(up);
> +	serial_omap_port_disable(up);
> +
>  	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);
>  
>  	if (status & UART_MSR_DCD)
> @@ -434,7 +468,9 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
>  		mcr |= UART_MCR_LOOP;
>  
>  	mcr |= up->mcr;
> +	serial_omap_port_enable(up);
>  	serial_out(up, UART_MCR, mcr);
> +	serial_omap_port_disable(up);
>  }
>  
>  static void serial_omap_break_ctl(struct uart_port *port, int break_state)
> @@ -443,6 +479,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
>  	unsigned long flags = 0;
>  
>  	dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id);
> +	serial_omap_port_enable(up);
>  	spin_lock_irqsave(&up->port.lock, flags);
>  	if (break_state == -1)
>  		up->lcr |= UART_LCR_SBC;
> @@ -450,6 +487,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
>  		up->lcr &= ~UART_LCR_SBC;
>  	serial_out(up, UART_LCR, up->lcr);
>  	spin_unlock_irqrestore(&up->port.lock, flags);
> +	serial_omap_port_disable(up);
>  }
>  
>  static int serial_omap_startup(struct uart_port *port)
> @@ -468,6 +506,7 @@ static int serial_omap_startup(struct uart_port *port)
>  
>  	dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id);
>  
> +	serial_omap_port_enable(up);
>  	/*
>  	 * Clear the FIFO buffers and disable them.
>  	 * (they will be reenabled in set_termios())
> @@ -523,6 +562,7 @@ static int serial_omap_startup(struct uart_port *port)
>  	/* Enable module level wake up */
>  	serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP);
>  
> +	serial_omap_port_disable(up);
>  	up->port_activity = jiffies;
>  	return 0;
>  }
> @@ -533,6 +573,8 @@ static void serial_omap_shutdown(struct uart_port *port)
>  	unsigned long flags = 0;
>  
>  	dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id);
> +
> +	serial_omap_port_enable(up);
>  	/*
>  	 * Disable interrupts from this port
>  	 */
> @@ -566,6 +608,7 @@ static void serial_omap_shutdown(struct uart_port *port)
>  			up->uart_dma.rx_buf_dma_phys);
>  		up->uart_dma.rx_buf = NULL;
>  	}
> +	serial_omap_port_disable(up);
>  	free_irq(up->port.irq, up);
>  }
>  
> @@ -671,6 +714,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
>  	quot = serial_omap_get_divisor(port, baud);
>  
> +	up->dll = quot & 0xff;
> +	up->dlh = quot >> 8;
> +	up->mdr1 = UART_OMAP_MDR1_DISABLE;
> +
>  	up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 |
>  			UART_FCR_ENABLE_FIFO;
>  	if (up->use_dma)
> @@ -680,6 +727,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  	 * Ok, we're now changing the port state. Do it with
>  	 * interrupts disabled.
>  	 */
> +	serial_omap_port_enable(up);
>  	spin_lock_irqsave(&up->port.lock, flags);
>  
>  	/*
> @@ -758,8 +806,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  	serial_out(up, UART_MCR, up->mcr);
>  
>  	/* Protocol, Baud Rate, and Interrupt Settings */
> -
> -	serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
> +	serial_out(up, UART_OMAP_MDR1, up->mdr1);
>  	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>  
>  	up->efr = serial_in(up, UART_EFR);
> @@ -769,8 +816,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  	serial_out(up, UART_IER, 0);
>  	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>  
> -	serial_out(up, UART_DLL, quot & 0xff);          /* LS of divisor */
> -	serial_out(up, UART_DLM, quot >> 8);            /* MS of divisor */
> +	serial_out(up, UART_DLL, up->dll);	/* LS of divisor */
> +	serial_out(up, UART_DLM, up->dlh);	/* MS of divisor */
>  
>  	serial_out(up, UART_LCR, 0);
>  	serial_out(up, UART_IER, up->ier);
> @@ -780,9 +827,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  	serial_out(up, UART_LCR, cval);
>  
>  	if (baud > 230400 && baud != 3000000)
> -		serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE);
> +		up->mdr1 = UART_OMAP_MDR1_13X_MODE;
>  	else
> -		serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
> +		up->mdr1 = UART_OMAP_MDR1_16X_MODE;
> +
> +	serial_out(up, UART_OMAP_MDR1, up->mdr1)
>  
>  	/* Hardware Flow Control Configuration */
>  
> @@ -810,6 +859,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
>  		serial_omap_configure_xonxoff(up, termios);
>  
>  	spin_unlock_irqrestore(&up->port.lock, flags);
> +	serial_omap_port_disable(up);
>  	dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
>  }
>  
> @@ -821,6 +871,8 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
>  	unsigned char efr;
>  
>  	dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
> +
> +	serial_omap_port_enable(up);
>  	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>  	efr = serial_in(up, UART_EFR);
>  	serial_out(up, UART_EFR, efr | UART_EFR_ECB);
> @@ -830,6 +882,10 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
>  	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>  	serial_out(up, UART_EFR, efr);
>  	serial_out(up, UART_LCR, 0);
> +	if (state)
> +		pm_runtime_put_sync(&up->pdev->dev);
> +	else
> +		serial_omap_port_disable(up);
>  }
>  
>  static void serial_omap_release_port(struct uart_port *port)
> @@ -907,25 +963,31 @@ static inline void wait_for_xmitr(struct uart_omap_port *up)
>  static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
>  {
>  	struct uart_omap_port *up = (struct uart_omap_port *)port;
> +
> +	serial_omap_port_enable(up);
>  	wait_for_xmitr(up);
>  	serial_out(up, UART_TX, ch);
> +	serial_omap_port_disable(up);
>  }
>  
>  static int serial_omap_poll_get_char(struct uart_port *port)
>  {
>  	struct uart_omap_port *up = (struct uart_omap_port *)port;
> -	unsigned int status = serial_in(up, UART_LSR);
> +	unsigned int status;
>  
> +	serial_omap_port_enable(up);
> +	status = serial_in(up, UART_LSR);
>  	if (!(status & UART_LSR_DR))
>  		return NO_POLL_CHAR;
>  
> -	return serial_in(up, UART_RX);
> +	status = serial_in(up, UART_RX);
> +	serial_omap_port_disable(up);
> +	return status;
>  }
>  
>  #endif /* CONFIG_CONSOLE_POLL */
>  
>  #ifdef CONFIG_SERIAL_OMAP_CONSOLE
> -
>  static struct uart_omap_port *serial_omap_console_ports[4];
>  
>  static struct uart_driver serial_omap_reg;
> @@ -955,6 +1017,8 @@ serial_omap_console_write(struct console *co, const char *s,
>  	else
>  		spin_lock(&up->port.lock);
>  
> +	serial_omap_port_enable(up);
> +
>  	/*
>  	 * First save the IER then disable the interrupts
>  	 */
> @@ -979,6 +1043,7 @@ serial_omap_console_write(struct console *co, const char *s,
>  	if (up->msr_saved_flags)
>  		check_modem_status(up);
>  
> +	serial_omap_port_disable(up);
>  	if (locked)
>  		spin_unlock(&up->port.lock);
>  	local_irq_restore(flags);
> @@ -1061,22 +1126,27 @@ static struct uart_driver serial_omap_reg = {
>  	.cons		= OMAP_CONSOLE,
>  };
>  
> -static int
> -serial_omap_suspend(struct platform_device *pdev, pm_message_t state)
> +static int serial_omap_suspend(struct device *dev)
>  {
> -	struct uart_omap_port *up = platform_get_drvdata(pdev);
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
>  
> -	if (up)
> +	if (up) {
>  		uart_suspend_port(&serial_omap_reg, &up->port);
> +		console_trylock();
> +		serial_omap_pm(&up->port, 3, 0);
> +	}
>  	return 0;
>  }
>  
> -static int serial_omap_resume(struct platform_device *dev)
> +static int serial_omap_resume(struct device *dev)
>  {
> -	struct uart_omap_port *up = platform_get_drvdata(dev);
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
>  
> -	if (up)
> +	if (up) {
>  		uart_resume_port(&serial_omap_reg, &up->port);
> +		console_unlock();
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1097,6 +1167,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
>  			serial_omap_stop_rxdma(up);
>  			up->ier |= (UART_IER_RDI | UART_IER_RLSI);
>  			serial_out(up, UART_IER, up->ier);
> +			serial_omap_port_disable(up);
>  		}
>  		return;
>  	}
> @@ -1128,6 +1199,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
>  
>  static void uart_rx_dma_callback(int lch, u16 ch_status, void *data)
>  {
> +	struct uart_omap_port *up = (struct uart_omap_port *)data;
> +
> +	serial_omap_port_disable(up);
>  	return;
>  }
>  
> @@ -1135,6 +1209,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
>  {
>  	int ret = 0;
>  
> +	serial_omap_port_enable(up);
>  	if (up->uart_dma.rx_dma_channel == -1) {
>  		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
>  				"UART Rx DMA",
> @@ -1214,6 +1289,7 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
>  		serial_omap_stop_tx(&up->port);
>  		up->uart_dma.tx_dma_used = false;
>  		spin_unlock(&(up->uart_dma.tx_lock));
> +		serial_omap_port_disable(up);
>  	} else {
>  		omap_stop_dma(up->uart_dma.tx_dma_channel);
>  		serial_omap_continue_tx(up);
> @@ -1224,9 +1300,10 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
>  
>  static int serial_omap_probe(struct platform_device *pdev)
>  {
> -	struct uart_omap_port	*up;
> +	struct uart_omap_port	*up = NULL;
>  	struct resource		*mem, *irq, *dma_tx, *dma_rx;
>  	struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data;
> +	struct omap_device *od;
>  	int ret = -ENOSPC;
>  
>  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -1276,12 +1353,20 @@ static int serial_omap_probe(struct platform_device *pdev)
>  	up->port.ops = &serial_omap_pops;
>  	up->port.line = pdev->id;
>  
> -	up->port.membase = omap_up_info->membase;
> -	up->port.mapbase = omap_up_info->mapbase;
> +	up->port.mapbase = mem->start;
> +	up->port.membase = ioremap(mem->start, mem->end - mem->start);
> +
> +	if (!up->port.membase) {
> +		dev_err(&pdev->dev, "can't ioremap UART\n");
> +		ret = -ENOMEM;
> +		goto err1;
> +	}
> +
>  	up->port.flags = omap_up_info->flags;
> -	up->port.irqflags = omap_up_info->irqflags;
>  	up->port.uartclk = omap_up_info->uartclk;
>  	up->uart_dma.uart_base = mem->start;
> +	up->errata = omap_up_info->errata;
> +	up->enable_wakeup = omap_up_info->enable_wakeup;
>  
>  	if (omap_up_info->dma_enabled) {
>  		up->uart_dma.uart_dma_tx = dma_tx->start;
> @@ -1295,18 +1380,36 @@ static int serial_omap_probe(struct platform_device *pdev)
>  		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
>  	}
>  
> +	pm_runtime_use_autosuspend(&pdev->dev);
> +	pm_runtime_set_autosuspend_delay(&pdev->dev,
> +			OMAP_UART_AUTOSUSPEND_DELAY);
> +
> +	pm_runtime_enable(&pdev->dev);
> +	pm_runtime_irq_safe(&pdev->dev);
> +
> +	if (omap_up_info->console_uart) {
> +		od = to_omap_device(up->pdev);
> +		omap_hwmod_idle(od->hwmods[0]);

Driver should have know knowlege of the underlying hwmod.  

I assume this is here because of the usage of HWMOD_INIT_NO_IDLE and
HWMOD_INIT_NO_RESET, right?  With proper runtime PM, we should be able to
remove the need for using those flags.

Kevin

> +		serial_omap_port_enable(up);
> +		serial_omap_port_disable(up);
> +	}
> +
>  	ui[pdev->id] = up;
>  	serial_omap_add_console_port(up);
>  
>  	ret = uart_add_one_port(&serial_omap_reg, &up->port);
>  	if (ret != 0)
> -		goto do_release_region;
> +		goto err1;
>  
> +	dev_set_drvdata(&pdev->dev, up);
>  	platform_set_drvdata(pdev, up);
> +
>  	return 0;
>  err:
>  	dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
>  				pdev->id, __func__, ret);
> +err1:
> +	kfree(up);
>  do_release_region:
>  	release_mem_region(mem->start, (mem->end - mem->start) + 1);
>  	return ret;
> @@ -1318,20 +1421,76 @@ static int serial_omap_remove(struct platform_device *dev)
>  
>  	platform_set_drvdata(dev, NULL);
>  	if (up) {
> +		pm_runtime_disable(&up->pdev->dev);
>  		uart_remove_one_port(&serial_omap_reg, &up->port);
>  		kfree(up);
>  	}
>  	return 0;
>  }
>  
> +static void omap_uart_restore_context(struct uart_omap_port *up)
> +{
> +	u16 efr = 0;
> +
> +	serial_out(up, UART_OMAP_MDR1, up->mdr1);
> +	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> +	efr = serial_in(up, UART_EFR);
> +	serial_out(up, UART_EFR, UART_EFR_ECB);
> +	serial_out(up, UART_LCR, 0x0); /* Operational mode */
> +	serial_out(up, UART_IER, 0x0);
> +	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> +	serial_out(up, UART_DLL, up->dll);
> +	serial_out(up, UART_DLM, up->dlh);
> +	serial_out(up, UART_LCR, 0x0); /* Operational mode */
> +	serial_out(up, UART_IER, up->ier);
> +	serial_out(up, UART_FCR, up->fcr);
> +	serial_out(up, UART_LCR, 0x80);
> +	serial_out(up, UART_MCR, up->mcr);
> +	serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> +	serial_out(up, UART_EFR, efr);
> +	serial_out(up, UART_LCR, UART_LCR_WLEN8);
> +	/* UART 16x mode */
> +	serial_out(up, UART_OMAP_MDR1, up->mdr1);
> +}
> +
> +static int omap_serial_runtime_suspend(struct device *dev)
> +{
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
> +
> +	if (!up)
> +		goto done;
> +
> +	if (device_may_wakeup(dev))
> +		up->enable_wakeup(up->pdev, true);
> +	else
> +		up->enable_wakeup(up->pdev, false);
> +done:
> +	return 0;
> +}
> +
> +static int omap_serial_runtime_resume(struct device *dev)
> +{
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
> +
> +	if (up)
> +		omap_uart_restore_context(up);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops omap_serial_dev_pm_ops = {
> +	.suspend = serial_omap_suspend,
> +	.resume	= serial_omap_resume,
> +	.runtime_suspend = omap_serial_runtime_suspend,
> +	.runtime_resume = omap_serial_runtime_resume,
> +};
> +
>  static struct platform_driver serial_omap_driver = {
>  	.probe          = serial_omap_probe,
>  	.remove         = serial_omap_remove,
> -
> -	.suspend	= serial_omap_suspend,
> -	.resume		= serial_omap_resume,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> +		.pm = &omap_serial_dev_pm_ops,
>  	},
>  };

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-04-29 12:39 ` [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage Govindraj.R
  2011-05-04 10:02   ` Tony Lindgren
@ 2011-05-04 20:43   ` Kevin Hilman
  2011-05-05 10:25     ` Govindraj
  1 sibling, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-04 20:43 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Paul Walmsley, Rajendra Nayak

"Govindraj.R" <govindraj.raja@ti.com> writes:

> Acquire console lock before enabling and writing to console-uart
> to avoid any recursive prints from console write.
> for ex:
> 	--> printk
> 	  --> uart_console_write
> 	    --> get_sync
> 	      --> printk from omap_device enable
> 		--> uart_console write

By this time, since the device's runtime PM hooks have been called, the
device's rutime PM state should be set to RPM_SUSPENDING (not yet
RPM_SUSPENDED).  

In addition to the console lock, you should be able to use that flag to
avoid console writes while the console is in the process of suspending.

> Also during bootup console_lock is not available.
>        --> uart_add_one_port
> 	   --> console_register
> 	       --> console_lock
> 	        --> console_unlock
> 	             --> call_console_drivers (here yet console_lock is not released)
> 		          --> uart_console_write
>
> Hence convert prints from omap_device_enable/disable to pr_debug.

And what if you add 'debug' to your kernel command line?  IOW, you're
only solving the problem if you debug printk's are not going to the
console.

You're also not solving the problem that will happen down the road when
someone else adds a printk to low-level code in order to debug something
deep in the idle sequence.  

The recursive locking needs to be solved, not avoided. 

Kevin

> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> ---
>  arch/arm/plat-omap/omap_device.c |    8 ++++----
>  drivers/tty/serial/omap-serial.c |    8 +++++++-
>  2 files changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 9bbda9a..f7c6dca 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -145,12 +145,12 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
>  			odpl->activate_lat_worst = act_lat;
>  			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
>  				odpl->activate_lat = act_lat;
> -				pr_warning("omap_device: %s.%d: new worst case "
> +				pr_debug("omap_device: %s.%d: new worst case "
>  					   "activate latency %d: %llu\n",
>  					   od->pdev.name, od->pdev.id,
>  					   od->pm_lat_level, act_lat);
>  			} else
> -				pr_warning("omap_device: %s.%d: activate "
> +				pr_debug("omap_device: %s.%d: activate "
>  					   "latency %d higher than exptected. "
>  					   "(%llu > %d)\n",
>  					   od->pdev.name, od->pdev.id,
> @@ -213,12 +213,12 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
>  			odpl->deactivate_lat_worst = deact_lat;
>  			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
>  				odpl->deactivate_lat = deact_lat;
> -				pr_warning("omap_device: %s.%d: new worst case "
> +				pr_debug("omap_device: %s.%d: new worst case "
>  					   "deactivate latency %d: %llu\n",
>  					   od->pdev.name, od->pdev.id,
>  					   od->pm_lat_level, deact_lat);
>  			} else
> -				pr_warning("omap_device: %s.%d: deactivate "
> +				pr_debug("omap_device: %s.%d: deactivate "
>  					   "latency %d higher than exptected. "
>  					   "(%llu > %d)\n",
>  					   od->pdev.name, od->pdev.id,
> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index 633dfb4..7d8ca45 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -1007,7 +1007,10 @@ serial_omap_console_write(struct console *co, const char *s,
>  	struct uart_omap_port *up = serial_omap_console_ports[co->index];
>  	unsigned long flags;
>  	unsigned int ier;
> -	int locked = 1;
> +	int console_lock = 0, locked = 1;
> +
> +	if (console_trylock())
> +		console_lock = 1;
>  
>  	local_irq_save(flags);
>  	if (up->port.sysrq)
> @@ -1043,6 +1046,9 @@ serial_omap_console_write(struct console *co, const char *s,
>  	if (up->msr_saved_flags)
>  		check_modem_status(up);
>  
> +	if (console_lock)
> +		console_unlock();
> +
>  	serial_omap_port_disable(up);
>  	if (locked)
>  		spin_unlock(&up->port.lock);

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver
  2011-05-04 20:35   ` Kevin Hilman
@ 2011-05-04 21:05     ` Paul Walmsley
  2011-05-05  5:48     ` Raja, Govindraj
  2011-05-05  5:55     ` Govindraj
  2 siblings, 0 replies; 40+ messages in thread
From: Paul Walmsley @ 2011-05-04 21:05 UTC (permalink / raw)
  To: Govindraj.R
  Cc: Kevin Hilman, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Rajendra Nayak

Hi Govindraj,

On Wed, 4 May 2011, Kevin Hilman wrote:

> "Govindraj.R" <govindraj.raja@ti.com> writes:
> 
> > +++ b/arch/arm/mach-omap2/serial.c
> > @@ -189,6 +189,21 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
> >  	}
> >  }
> >  
> > +static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
> > +{
> > +	struct omap_uart_port_info *up = pdev->dev.platform_data;
> > +
> > +	/* Set or clear wake-enable bit */
> > +	if (up->wk_en && up->wk_mask) {
> > +		u32 v = __raw_readl(up->wk_en);
> > +		if (enable)
> > +			v |= up->wk_mask;
> > +		else
> > +			v &= ~up->wk_mask;
> > +		__raw_writel(v, up->wk_en);
> > +	}
> > +}

To be a little more direct: there should be no PRCM register interactions 
in the driver, absolutely none.  This stuff needs to go through 
omap_device/omap_hwmod functions if it's really needed.


- Paul

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup.
  2011-04-29 12:39 ` [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup Govindraj.R
@ 2011-05-04 23:59   ` Kevin Hilman
  2011-05-05  5:58     ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-04 23:59 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Paul Walmsley, Rajendra Nayak

"Govindraj.R" <govindraj.raja@ti.com> writes:

> Add api to enable io_pad wakeup based on mux dynamic pad and

s/api/API/
s/io_pad/IO pad/

> wake_up enable flag initialized during hwmod_mux.
>
> Use the wakeup flag and pad_remux flag and enable wakeup capability
> for the pad having these flags enabled.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

This patch (except for the serial.c hange) isn't really dependent on the
rest of this series, and should be a separate patch to be merged by
Paul.

Some other comments below...

> ---
>  arch/arm/mach-omap2/omap_hwmod.c              |   34 +++++++++++++++++++++++++
>  arch/arm/mach-omap2/serial.c                  |    6 ++++
>  arch/arm/plat-omap/include/plat/omap_device.h |    1 +
>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
>  arch/arm/plat-omap/omap_device.c              |   26 +++++++++++++++++++
>  5 files changed, 68 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index e034294..4a12336 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2369,3 +2369,37 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
>  
>  	return 0;
>  }
> +
> +/**
> + * omap_hwmod_enable_ioring_wakeup - Set wakeup bit for iopad ring.
> + * @oh: struct omap_hwmod *
> + * @enable: based on 0 or 1 set or unset wakeup bit.

more specifically, when true, set wakeup bit, when false, clear wakeup bit

> + * traverse through dynamic pads. If pad is enabled then
> + * set wakeup bit for the mux pin. Return error if pads are
> + * not enabled or not available.
> + */

The comment here should be clearer about when the bit actually gets
set.  Specifically, this function doesn't actually write the value out,
but instead it configures the value which will be used during the hwmod 
idle transition.

Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-04-29 12:39 ` [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart Govindraj.R
@ 2011-05-05  0:11   ` Kevin Hilman
  2011-05-05 11:46     ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-05  0:11 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Paul Walmsley, Rajendra Nayak

"Govindraj.R" <govindraj.raja@ti.com> writes:

> Use resume idle call from prcm_irq to enable uart_port from low power states.
> Add api to check pad wakeup status which will we used from uart_resume func.
> to enable back uart port if a wakeup event occurred.
>
> UART_Resume func. can be removed once we have irq_chaining functionality
> available.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

The part adding a new hwmod API needs to be separated out into a
separate patch which is not dependent on the rest of this series.

> ---
>  arch/arm/mach-omap2/mux.c                     |   23 +++++++++++++++++++++++
>  arch/arm/mach-omap2/mux.h                     |   13 +++++++++++++
>  arch/arm/mach-omap2/omap_hwmod.c              |   13 +++++++++++++
>  arch/arm/mach-omap2/pm24xx.c                  |    2 ++
>  arch/arm/mach-omap2/pm34xx.c                  |    2 ++
>  arch/arm/mach-omap2/serial.c                  |   23 +++++++++++++++++++++++
>  arch/arm/plat-omap/include/plat/omap-serial.h |    2 ++
>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
>  arch/arm/plat-omap/include/plat/serial.h      |    1 +
>  drivers/tty/serial/omap-serial.c              |   23 +++++++++++++++++++++++
>  10 files changed, 103 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
> index a4ab1e3..7149671 100644
> --- a/arch/arm/mach-omap2/mux.c
> +++ b/arch/arm/mach-omap2/mux.c
> @@ -348,6 +348,29 @@ err1:
>  	return NULL;
>  }
>  
> +/* Gets the wakeup status of given pad from omap-hwmod.
> + * Returns the wake_up status bit of available pad mux pin
> + */

fix multi-line comment style

> +bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)

The name here should be more descriptive: like _get_wake_status or
something.

> +{
> +	int i;
> +	unsigned int val;
> +	u8 ret = 0;
> +
> +	for (i = 0; i < hmux->nr_pads; i++) {
> +		struct omap_device_pad *pad = &hmux->pads[i];
> +
> +		val = omap_mux_read(pad->partition,
> +					pad->mux->reg_offset);
> +		if (val & OMAP_WAKEUP_EVENT) {
> +			ret = 1;
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
>  /* Assumes the calling function takes care of locking */
>  void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
>  {
> diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
> index 137f321..379fb6e 100644
> --- a/arch/arm/mach-omap2/mux.h
> +++ b/arch/arm/mach-omap2/mux.h
> @@ -225,8 +225,21 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
>   */
>  void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
>  
> +
> +/**
> + * omap_hwmod_mux_wakeup - omap hwmod check given pad had wakeup event
> + * @hmux:		Pads for a hwmod
> + *
> + * Called only from omap_hwmod.c, do not use.
> + */

Please put the kerneldoc comments in the C file instead of the header.

> +bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux);
>  #else
>  
> +static inline bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)
> +{
> +	return 0;
> +}
> +
>  static inline int omap_mux_init_gpio(int gpio, int val)
>  {
>  	return 0;
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 4a12336..86cb8c4 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2403,3 +2403,16 @@ int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable)
>  
>  	return ret;
>  }
> +
> +/**
> + * omap_hwmod_pad_wakeup_status - get pad wakeup status if mux is available.

How about _get_pad_wakeup_status()

> + * @oh: struct omap_hwmod *
> + *
> + * Returns the wake_up status bit of available pad mux pin.

or on error... ?

> + */
> +int omap_hmwod_pad_wakeup_status(struct omap_hwmod *oh)
> +{
> +	if (oh->mux)
> +		return omap_hwmod_mux_wakeup(oh->mux);
> +	return -EINVAL;
> +}
> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
> index c405bda..ba58a1d 100644
> --- a/arch/arm/mach-omap2/pm24xx.c
> +++ b/arch/arm/mach-omap2/pm24xx.c
> @@ -137,6 +137,8 @@ static void omap2_enter_full_retention(void)
>  			   OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
>  			   OMAP_SDRC_REGADDR(SDRC_POWER));
>  
> +	omap_uart_resume_idle();
> +
>  no_sleep:
>  	if (omap2_pm_debug) {
>  		unsigned long long tmp;
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index ce0ecdc..3960330 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -216,6 +216,8 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
>  
>  	wkst = omap2_prm_read_mod_reg(module, wkst_off);
>  	wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
> +
> +	c += omap_uart_resume_idle();

No...

[...]

> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index 9ed993c..eea478c 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -43,6 +43,7 @@
>  #include <plat/dmtimer.h>
>  #include <plat/omap-serial.h>
>  #include <plat/omap_device.h>
> +#include <plat/serial.h>
>  
>  static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
>  
> @@ -108,6 +109,27 @@ static inline void serial_omap_port_enable(struct uart_omap_port *up)
>  	pm_runtime_get_sync(&up->pdev->dev);
>  }
>  
> +/* TBD: Should be removed once we irq-chaining mechanism in place */

...indeed...

> +u32 omap_uart_resume_idle()
> +{
> +	int i;
> +	u32 ret = 0;
> +
> +	for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
> +		struct uart_omap_port *up = ui[i];
> +
> +		if (!up)
> +			continue;
> +
> +		if (up->chk_wakeup(up->pdev)) {
> +			serial_omap_port_enable(up);
> +			serial_omap_port_disable(up);
> +			ret++;
> +		}
> +	}
> +	return ret;
> +}

... this is just putting back basically the same thing that was removed in
patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
is no different than having it in the idle path.

I thought I understood that you had the SW IRQ triggering working, so
this part should not be necessary.  

Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver
  2011-05-04 20:35   ` Kevin Hilman
  2011-05-04 21:05     ` Paul Walmsley
@ 2011-05-05  5:48     ` Raja, Govindraj
  2011-05-05  5:55     ` Govindraj
  2 siblings, 0 replies; 40+ messages in thread
From: Raja, Govindraj @ 2011-05-05  5:48 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Paul Walmsley, Benoit Cousson, Tony Lindgren, Rajendra Nayak,
	linux-serial, linux-omap, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 7635 bytes --]

On Thu, May 5, 2011 at 2:05 AM, Kevin Hilman <khilman@ti.com> wrote:

> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
> > Adapts omap-serial driver to use pm_runtime api's.
> >
> > 1.) Populate reg values to uart port which can be used for context
> restore.
> > 2.) Moving context_restore func to driver from serial.c
> > 3.) Adding port_enable/disable func to enable/disable given uart port.
> >     enable port using get_sync and disable using autosuspend.
> > 4.) using runtime irq safe api to make get_sync be called from irq
> context.
> >
> > Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> > ---
> >  arch/arm/mach-omap2/serial.c                  |   16 ++
> >  arch/arm/plat-omap/include/plat/omap-serial.h |    2 +
> >  drivers/tty/serial/omap-serial.c              |  211
> ++++++++++++++++++++++---
> >  3 files changed, 203 insertions(+), 26 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> > index 8c1a4c7..314d82f 100644
> > --- a/arch/arm/mach-omap2/serial.c
> > +++ b/arch/arm/mach-omap2/serial.c
> > @@ -189,6 +189,21 @@ static void omap_serial_fill_default_pads(struct
> omap_board_data *bdata)
> >       }
> >  }
> >
> > +static void omap_uart_wakeup_enable(struct platform_device *pdev, bool
> enable)
> > +{
> > +     struct omap_uart_port_info *up = pdev->dev.platform_data;
> > +
> > +     /* Set or clear wake-enable bit */
> > +     if (up->wk_en && up->wk_mask) {
> > +             u32 v = __raw_readl(up->wk_en);
> > +             if (enable)
> > +                     v |= up->wk_mask;
> > +             else
> > +                     v &= ~up->wk_mask;
> > +             __raw_writel(v, up->wk_en);
> > +     }
> > +}
>
> Rather than having the driver do this via the PRCM, can you do an
> experiment?  Can you try to leave the module-level wakeup enabled all
> the time in the PRCM, and the driver can then enable/disable
> module-level wakeups simply by toggling ENAWAKEUP in the module's
> SYSCONFIG?  If that works, than you can just use
> omap_hwmod_enable_wakeup() for this and not need the above function.
>


If we leave PRCM uart module level bit enabled all time and we disable
wakeup using sysfs

echo disabled > /sys/devices/platform/omap/omap_uart.0/power/wakeup

it wakes up after clock disable, however unsetting the bit ensures
it doesn't
wakeup after uart clocks are cut.

As Paul suggested, How about adding omap_device/omap_hwmod function
to set and unset the bit?

Using

.module_bit = OMAP3430_EN_UART1_SHIFT,

from hwmod data?



>
> >  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
> >                               unsigned short num)
> >  {
> > @@ -332,6 +347,7 @@ void __init omap_serial_init_port(struct
> omap_board_data *bdata)
> >
> >       pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
> >       pdata->flags = UPF_BOOT_AUTOCONF;
> > +     pdata->enable_wakeup = omap_uart_wakeup_enable;
> >       if (bdata->id == omap_uart_con_id)
> >               pdata->console_uart = true;
> >
>
>
<<SNIP>>


> > +     pm_runtime_use_autosuspend(&pdev->dev);
> > +     pm_runtime_set_autosuspend_delay(&pdev->dev,
> > +                     OMAP_UART_AUTOSUSPEND_DELAY);
> > +
> > +     pm_runtime_enable(&pdev->dev);
> > +     pm_runtime_irq_safe(&pdev->dev);
> > +
> > +     if (omap_up_info->console_uart) {
> > +             od = to_omap_device(up->pdev);
> > +             omap_hwmod_idle(od->hwmods[0]);
>
> Driver should have know knowlege of the underlying hwmod.
>
> I assume this is here because of the usage of HWMOD_INIT_NO_IDLE and
> HWMOD_INIT_NO_RESET, right?


   Yes correct.



>  With proper runtime PM, we should be able to
> remove the need for using those flags.
>


For omap-uart used for earlyprintk's the early_console driver will
use printch from debug macro to print through uart.

During omap-hwmod is getting initialized

--> _setup
   --> _idle
    ---> _disable_clocks

at this point of time while printch is happening and
hwmod disables uart clocks I dont have uart-console
driver available which can enable clocks back.

So I have to use those flags when earlyprintk is enabled.

--
Thanks,
Govindraj.R




>
> Kevin
>
> > +             serial_omap_port_enable(up);
> > +             serial_omap_port_disable(up);
> > +     }
> > +
> >       ui[pdev->id] = up;
> >       serial_omap_add_console_port(up);
> >
> >       ret = uart_add_one_port(&serial_omap_reg, &up->port);
> >       if (ret != 0)
> > -             goto do_release_region;
> > +             goto err1;
> >
> > +     dev_set_drvdata(&pdev->dev, up);
> >       platform_set_drvdata(pdev, up);
> > +
> >       return 0;
> >  err:
> >       dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
> >                               pdev->id, __func__, ret);
> > +err1:
> > +     kfree(up);
> >  do_release_region:
> >       release_mem_region(mem->start, (mem->end - mem->start) + 1);
> >       return ret;
> > @@ -1318,20 +1421,76 @@ static int serial_omap_remove(struct
> platform_device *dev)
> >
> >       platform_set_drvdata(dev, NULL);
> >       if (up) {
> > +             pm_runtime_disable(&up->pdev->dev);
> >               uart_remove_one_port(&serial_omap_reg, &up->port);
> >               kfree(up);
> >       }
> >       return 0;
> >  }
> >
> > +static void omap_uart_restore_context(struct uart_omap_port *up)
> > +{
> > +     u16 efr = 0;
> > +
> > +     serial_out(up, UART_OMAP_MDR1, up->mdr1);
> > +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> > +     efr = serial_in(up, UART_EFR);
> > +     serial_out(up, UART_EFR, UART_EFR_ECB);
> > +     serial_out(up, UART_LCR, 0x0); /* Operational mode */
> > +     serial_out(up, UART_IER, 0x0);
> > +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> > +     serial_out(up, UART_DLL, up->dll);
> > +     serial_out(up, UART_DLM, up->dlh);
> > +     serial_out(up, UART_LCR, 0x0); /* Operational mode */
> > +     serial_out(up, UART_IER, up->ier);
> > +     serial_out(up, UART_FCR, up->fcr);
> > +     serial_out(up, UART_LCR, 0x80);
> > +     serial_out(up, UART_MCR, up->mcr);
> > +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
> > +     serial_out(up, UART_EFR, efr);
> > +     serial_out(up, UART_LCR, UART_LCR_WLEN8);
> > +     /* UART 16x mode */
> > +     serial_out(up, UART_OMAP_MDR1, up->mdr1);
> > +}
> > +
> > +static int omap_serial_runtime_suspend(struct device *dev)
> > +{
> > +     struct uart_omap_port *up = dev_get_drvdata(dev);
> > +
> > +     if (!up)
> > +             goto done;
> > +
> > +     if (device_may_wakeup(dev))
> > +             up->enable_wakeup(up->pdev, true);
> > +     else
> > +             up->enable_wakeup(up->pdev, false);
> > +done:
> > +     return 0;
> > +}
> > +
> > +static int omap_serial_runtime_resume(struct device *dev)
> > +{
> > +     struct uart_omap_port *up = dev_get_drvdata(dev);
> > +
> > +     if (up)
> > +             omap_uart_restore_context(up);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct dev_pm_ops omap_serial_dev_pm_ops = {
> > +     .suspend = serial_omap_suspend,
> > +     .resume = serial_omap_resume,
> > +     .runtime_suspend = omap_serial_runtime_suspend,
> > +     .runtime_resume = omap_serial_runtime_resume,
> > +};
> > +
> >  static struct platform_driver serial_omap_driver = {
> >       .probe          = serial_omap_probe,
> >       .remove         = serial_omap_remove,
> > -
> > -     .suspend        = serial_omap_suspend,
> > -     .resume         = serial_omap_resume,
> >       .driver         = {
> >               .name   = DRIVER_NAME,
> > +             .pm = &omap_serial_dev_pm_ops,
> >       },
> >  };
>

[-- Attachment #1.2: Type: text/html, Size: 12072 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver
  2011-05-04 20:35   ` Kevin Hilman
  2011-05-04 21:05     ` Paul Walmsley
  2011-05-05  5:48     ` Raja, Govindraj
@ 2011-05-05  5:55     ` Govindraj
  2 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-05  5:55 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 2:05 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Adapts omap-serial driver to use pm_runtime api's.
>>
>> 1.) Populate reg values to uart port which can be used for context restore.
>> 2.) Moving context_restore func to driver from serial.c
>> 3.) Adding port_enable/disable func to enable/disable given uart port.
>>     enable port using get_sync and disable using autosuspend.
>> 4.) using runtime irq safe api to make get_sync be called from irq context.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>> ---
>>  arch/arm/mach-omap2/serial.c                  |   16 ++
>>  arch/arm/plat-omap/include/plat/omap-serial.h |    2 +
>>  drivers/tty/serial/omap-serial.c              |  211 ++++++++++++++++++++++---
>>  3 files changed, 203 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
>> index 8c1a4c7..314d82f 100644
>> --- a/arch/arm/mach-omap2/serial.c
>> +++ b/arch/arm/mach-omap2/serial.c
>> @@ -189,6 +189,21 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
>>       }
>>  }
>>
>> +static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
>> +{
>> +     struct omap_uart_port_info *up = pdev->dev.platform_data;
>> +
>> +     /* Set or clear wake-enable bit */
>> +     if (up->wk_en && up->wk_mask) {
>> +             u32 v = __raw_readl(up->wk_en);
>> +             if (enable)
>> +                     v |= up->wk_mask;
>> +             else
>> +                     v &= ~up->wk_mask;
>> +             __raw_writel(v, up->wk_en);
>> +     }
>> +}
>
> Rather than having the driver do this via the PRCM, can you do an
> experiment?  Can you try to leave the module-level wakeup enabled all
> the time in the PRCM, and the driver can then enable/disable
> module-level wakeups simply by toggling ENAWAKEUP in the module's
> SYSCONFIG?  If that works, than you can just use
> omap_hwmod_enable_wakeup() for this and not need the above function.
>

If we leave PRCM uart module level bit enabled all time and we disable
wakeup using sysfs

echo disabled > /sys/devices/platform/omap/omap_uart.0/power/wakeup

it wakes up after clock disable, however unsetting the bit ensures it doesn't
wakeup after uart clocks are cut.

As Paul suggested, How about adding omap_device/omap_hwmod function
to set and unset the bit?

Using

.module_bit = OMAP3430_EN_UART1_SHIFT,

from hwmod data?


>>  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>>                               unsigned short num)
>>  {
>> @@ -332,6 +347,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
>>
>>       pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
>>       pdata->flags = UPF_BOOT_AUTOCONF;
>> +     pdata->enable_wakeup = omap_uart_wakeup_enable;
>>       if (bdata->id == omap_uart_con_id)
>>               pdata->console_uart = true;

<<SNIP>>

>> +     pm_runtime_use_autosuspend(&pdev->dev);
>> +     pm_runtime_set_autosuspend_delay(&pdev->dev,
>> +                     OMAP_UART_AUTOSUSPEND_DELAY);
>> +
>> +     pm_runtime_enable(&pdev->dev);
>> +     pm_runtime_irq_safe(&pdev->dev);
>> +
>> +     if (omap_up_info->console_uart) {
>> +             od = to_omap_device(up->pdev);
>> +             omap_hwmod_idle(od->hwmods[0]);
>
> Driver should have know knowlege of the underlying hwmod.
>
> I assume this is here because of the usage of HWMOD_INIT_NO_IDLE and
> HWMOD_INIT_NO_RESET, right?

 Yes correct.

> With proper runtime PM, we should be able to remove the need for using those flags.


For omap-uart used for earlyprintk's the early_console driver will
use printch from debug macro to print through uart.

During omap-hwmod is getting initialized

--> _setup
   --> _idle
    ---> _disable_clocks

at this point of time while printch is happening and
hwmod disables uart clocks I dont have uart-console
driver available which can enable clocks back.

So I have to use those flags when earlyprintk is enabled.

--
Thanks,
Govindraj.R


>
> Kevin
>
>> +             serial_omap_port_enable(up);
>> +             serial_omap_port_disable(up);
>> +     }
>> +
>>       ui[pdev->id] = up;
>>       serial_omap_add_console_port(up);
>>
>>       ret = uart_add_one_port(&serial_omap_reg, &up->port);
>>       if (ret != 0)
>> -             goto do_release_region;
>> +             goto err1;
>>
>> +     dev_set_drvdata(&pdev->dev, up);
>>       platform_set_drvdata(pdev, up);
>> +
>>       return 0;
>>  err:
>>       dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n",
>>                               pdev->id, __func__, ret);
>> +err1:
>> +     kfree(up);
>>  do_release_region:
>>       release_mem_region(mem->start, (mem->end - mem->start) + 1);
>>       return ret;
>> @@ -1318,20 +1421,76 @@ static int serial_omap_remove(struct platform_device *dev)
>>
>>       platform_set_drvdata(dev, NULL);
>>       if (up) {
>> +             pm_runtime_disable(&up->pdev->dev);
>>               uart_remove_one_port(&serial_omap_reg, &up->port);
>>               kfree(up);
>>       }
>>       return 0;
>>  }
>>
>> +static void omap_uart_restore_context(struct uart_omap_port *up)
>> +{
>> +     u16 efr = 0;
>> +
>> +     serial_out(up, UART_OMAP_MDR1, up->mdr1);
>> +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
>> +     efr = serial_in(up, UART_EFR);
>> +     serial_out(up, UART_EFR, UART_EFR_ECB);
>> +     serial_out(up, UART_LCR, 0x0); /* Operational mode */
>> +     serial_out(up, UART_IER, 0x0);
>> +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
>> +     serial_out(up, UART_DLL, up->dll);
>> +     serial_out(up, UART_DLM, up->dlh);
>> +     serial_out(up, UART_LCR, 0x0); /* Operational mode */
>> +     serial_out(up, UART_IER, up->ier);
>> +     serial_out(up, UART_FCR, up->fcr);
>> +     serial_out(up, UART_LCR, 0x80);
>> +     serial_out(up, UART_MCR, up->mcr);
>> +     serial_out(up, UART_LCR, 0xBF); /* Config B mode */
>> +     serial_out(up, UART_EFR, efr);
>> +     serial_out(up, UART_LCR, UART_LCR_WLEN8);
>> +     /* UART 16x mode */
>> +     serial_out(up, UART_OMAP_MDR1, up->mdr1);
>> +}
>> +
>> +static int omap_serial_runtime_suspend(struct device *dev)
>> +{
>> +     struct uart_omap_port *up = dev_get_drvdata(dev);
>> +
>> +     if (!up)
>> +             goto done;
>> +
>> +     if (device_may_wakeup(dev))
>> +             up->enable_wakeup(up->pdev, true);
>> +     else
>> +             up->enable_wakeup(up->pdev, false);
>> +done:
>> +     return 0;
>> +}
>> +
>> +static int omap_serial_runtime_resume(struct device *dev)
>> +{
>> +     struct uart_omap_port *up = dev_get_drvdata(dev);
>> +
>> +     if (up)
>> +             omap_uart_restore_context(up);
>> +
>> +     return 0;
>> +}
>> +
>> +static const struct dev_pm_ops omap_serial_dev_pm_ops = {
>> +     .suspend = serial_omap_suspend,
>> +     .resume = serial_omap_resume,
>> +     .runtime_suspend = omap_serial_runtime_suspend,
>> +     .runtime_resume = omap_serial_runtime_resume,
>> +};
>> +
>>  static struct platform_driver serial_omap_driver = {
>>       .probe          = serial_omap_probe,
>>       .remove         = serial_omap_remove,
>> -
>> -     .suspend        = serial_omap_suspend,
>> -     .resume         = serial_omap_resume,
>>       .driver         = {
>>               .name   = DRIVER_NAME,
>> +             .pm = &omap_serial_dev_pm_ops,
>>       },
>>  };
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup.
  2011-05-04 23:59   ` Kevin Hilman
@ 2011-05-05  5:58     ` Govindraj
  0 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-05  5:58 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 5:29 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Add api to enable io_pad wakeup based on mux dynamic pad and
>
> s/api/API/
> s/io_pad/IO pad/

will update.

>
>> wake_up enable flag initialized during hwmod_mux.
>>
>> Use the wakeup flag and pad_remux flag and enable wakeup capability
>> for the pad having these flags enabled.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> This patch (except for the serial.c hange) isn't really dependent on the
> rest of this series, and should be a separate patch to be merged by
> Paul.
>

Yes. fine will post out hwmod API additions as separate patch.

> Some other comments below...
>
>> ---
>>  arch/arm/mach-omap2/omap_hwmod.c              |   34 +++++++++++++++++++++++++
>>  arch/arm/mach-omap2/serial.c                  |    6 ++++
>>  arch/arm/plat-omap/include/plat/omap_device.h |    1 +
>>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
>>  arch/arm/plat-omap/omap_device.c              |   26 +++++++++++++++++++
>>  5 files changed, 68 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
>> index e034294..4a12336 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>> @@ -2369,3 +2369,37 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
>>
>>       return 0;
>>  }
>> +
>> +/**
>> + * omap_hwmod_enable_ioring_wakeup - Set wakeup bit for iopad ring.
>> + * @oh: struct omap_hwmod *
>> + * @enable: based on 0 or 1 set or unset wakeup bit.
>
> more specifically, when true, set wakeup bit, when false, clear wakeup bit

ok.

>
>> + * traverse through dynamic pads. If pad is enabled then
>> + * set wakeup bit for the mux pin. Return error if pads are
>> + * not enabled or not available.
>> + */
>
> The comment here should be clearer about when the bit actually gets
> set.  Specifically, this function doesn't actually write the value out,
> but instead it configures the value which will be used during the hwmod
> idle transition.
>

Yes correct. Will update the comments.

> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-05-04 20:43   ` Kevin Hilman
@ 2011-05-05 10:25     ` Govindraj
  2011-05-05 14:52       ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Govindraj @ 2011-05-05 10:25 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 2:13 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Acquire console lock before enabling and writing to console-uart
>> to avoid any recursive prints from console write.
>> for ex:
>>       --> printk
>>         --> uart_console_write
>>           --> get_sync
>>             --> printk from omap_device enable
>>               --> uart_console write
>
> By this time, since the device's runtime PM hooks have been called, the
> device's rutime PM state should be set to RPM_SUSPENDING (not yet
> RPM_SUSPENDED).
>
> In addition to the console lock, you should be able to use that flag to
> avoid console writes while the console is in the process of suspending.
>

Yes RPM_SUSPENDING check helps along with console lock

<< Changes as below >>
---------------
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 59f548f..71964c3 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1040,6 +1040,18 @@ serial_omap_console_write(struct console *co,
const char *s,
        if (console_trylock())
                console_lock = 1;

+       /*
+        * If console_lock is not available and we are in suspending
+        * state then we can avoid the console usage scenario
+        * as this may introduce recursive prints.
+        * Basically this scenario occurs during boot while
+        * printing debug bootlogs.
+        */
+
+       if (!console_lock &&
+               up->pdev->dev.power.runtime_status == RPM_SUSPENDING)
+               return;
+
        local_irq_save(flags);
        if (up->port.sysrq)
                locked = 0;

------------

Is it ok to check the RPM_SUSPENDING flag in driver ?
I can't find any API currently available under runtime.h to use.


>> Also during bootup console_lock is not available.
>>        --> uart_add_one_port
>>          --> console_register
>>              --> console_lock
>>               --> console_unlock
>>                    --> call_console_drivers (here yet console_lock is not released)
>>                         --> uart_console_write
>>
>> Hence convert prints from omap_device_enable/disable to pr_debug.
>
> And what if you add 'debug' to your kernel command line?  IOW, you're
> only solving the problem if you debug printk's are not going to the
> console.
>

yes correct issue will re-surface during boot-up once we have debug enabled
and all pr_debugs with omap_device_enable trying to use console_write.

--
Thanks,
Govindraj.R

> You're also not solving the problem that will happen down the road when
> someone else adds a printk to low-level code in order to debug something
> deep in the idle sequence.
>
> The recursive locking needs to be solved, not avoided.
>
> Kevin
>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>> ---
>>  arch/arm/plat-omap/omap_device.c |    8 ++++----
>>  drivers/tty/serial/omap-serial.c |    8 +++++++-
>>  2 files changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
>> index 9bbda9a..f7c6dca 100644
>> --- a/arch/arm/plat-omap/omap_device.c
>> +++ b/arch/arm/plat-omap/omap_device.c
>> @@ -145,12 +145,12 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
>>                       odpl->activate_lat_worst = act_lat;
>>                       if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
>>                               odpl->activate_lat = act_lat;
>> -                             pr_warning("omap_device: %s.%d: new worst case "
>> +                             pr_debug("omap_device: %s.%d: new worst case "
>>                                          "activate latency %d: %llu\n",
>>                                          od->pdev.name, od->pdev.id,
>>                                          od->pm_lat_level, act_lat);
>>                       } else
>> -                             pr_warning("omap_device: %s.%d: activate "
>> +                             pr_debug("omap_device: %s.%d: activate "
>>                                          "latency %d higher than exptected. "
>>                                          "(%llu > %d)\n",
>>                                          od->pdev.name, od->pdev.id,
>> @@ -213,12 +213,12 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
>>                       odpl->deactivate_lat_worst = deact_lat;
>>                       if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
>>                               odpl->deactivate_lat = deact_lat;
>> -                             pr_warning("omap_device: %s.%d: new worst case "
>> +                             pr_debug("omap_device: %s.%d: new worst case "
>>                                          "deactivate latency %d: %llu\n",
>>                                          od->pdev.name, od->pdev.id,
>>                                          od->pm_lat_level, deact_lat);
>>                       } else
>> -                             pr_warning("omap_device: %s.%d: deactivate "
>> +                             pr_debug("omap_device: %s.%d: deactivate "
>>                                          "latency %d higher than exptected. "
>>                                          "(%llu > %d)\n",
>>                                          od->pdev.name, od->pdev.id,
>> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
>> index 633dfb4..7d8ca45 100644
>> --- a/drivers/tty/serial/omap-serial.c
>> +++ b/drivers/tty/serial/omap-serial.c
>> @@ -1007,7 +1007,10 @@ serial_omap_console_write(struct console *co, const char *s,
>>       struct uart_omap_port *up = serial_omap_console_ports[co->index];
>>       unsigned long flags;
>>       unsigned int ier;
>> -     int locked = 1;
>> +     int console_lock = 0, locked = 1;
>> +
>> +     if (console_trylock())
>> +             console_lock = 1;
>>
>>       local_irq_save(flags);
>>       if (up->port.sysrq)
>> @@ -1043,6 +1046,9 @@ serial_omap_console_write(struct console *co, const char *s,
>>       if (up->msr_saved_flags)
>>               check_modem_status(up);
>>
>> +     if (console_lock)
>> +             console_unlock();
>> +
>>       serial_omap_port_disable(up);
>>       if (locked)
>>               spin_unlock(&up->port.lock);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-05-05  0:11   ` Kevin Hilman
@ 2011-05-05 11:46     ` Govindraj
  2011-05-05 14:58       ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Govindraj @ 2011-05-05 11:46 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 5:41 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Use resume idle call from prcm_irq to enable uart_port from low power states.
>> Add api to check pad wakeup status which will we used from uart_resume func.
>> to enable back uart port if a wakeup event occurred.
>>
>> UART_Resume func. can be removed once we have irq_chaining functionality
>> available.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> The part adding a new hwmod API needs to be separated out into a
> separate patch which is not dependent on the rest of this series.
>

ok. fine

>> ---
>>  arch/arm/mach-omap2/mux.c                     |   23 +++++++++++++++++++++++
>>  arch/arm/mach-omap2/mux.h                     |   13 +++++++++++++
>>  arch/arm/mach-omap2/omap_hwmod.c              |   13 +++++++++++++
>>  arch/arm/mach-omap2/pm24xx.c                  |    2 ++
>>  arch/arm/mach-omap2/pm34xx.c                  |    2 ++
>>  arch/arm/mach-omap2/serial.c                  |   23 +++++++++++++++++++++++
>>  arch/arm/plat-omap/include/plat/omap-serial.h |    2 ++
>>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1 +
>>  arch/arm/plat-omap/include/plat/serial.h      |    1 +
>>  drivers/tty/serial/omap-serial.c              |   23 +++++++++++++++++++++++
>>  10 files changed, 103 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
>> index a4ab1e3..7149671 100644
>> --- a/arch/arm/mach-omap2/mux.c
>> +++ b/arch/arm/mach-omap2/mux.c
>> @@ -348,6 +348,29 @@ err1:
>>       return NULL;
>>  }
>>
>> +/* Gets the wakeup status of given pad from omap-hwmod.
>> + * Returns the wake_up status bit of available pad mux pin
>> + */
>
> fix multi-line comment style
>

ok.

>> +bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)
>
> The name here should be more descriptive: like _get_wake_status or
> something.
>
>> +{
>> +     int i;
>> +     unsigned int val;
>> +     u8 ret = 0;
>> +
>> +     for (i = 0; i < hmux->nr_pads; i++) {
>> +             struct omap_device_pad *pad = &hmux->pads[i];
>> +
>> +             val = omap_mux_read(pad->partition,
>> +                                     pad->mux->reg_offset);
>> +             if (val & OMAP_WAKEUP_EVENT) {
>> +                     ret = 1;
>> +                     break;
>> +             }
>> +     }
>> +
>> +     return ret;
>> +}
>> +
>>  /* Assumes the calling function takes care of locking */
>>  void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
>>  {
>> diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
>> index 137f321..379fb6e 100644
>> --- a/arch/arm/mach-omap2/mux.h
>> +++ b/arch/arm/mach-omap2/mux.h
>> @@ -225,8 +225,21 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
>>   */
>>  void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
>>
>> +
>> +/**
>> + * omap_hwmod_mux_wakeup - omap hwmod check given pad had wakeup event
>> + * @hmux:            Pads for a hwmod
>> + *
>> + * Called only from omap_hwmod.c, do not use.
>> + */
>
> Please put the kerneldoc comments in the C file instead of the header.
>

ok.

>> +bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux);
>>  #else
>>
>> +static inline bool omap_hwmod_mux_wakeup(struct omap_hwmod_mux_info *hmux)
>> +{
>> +     return 0;
>> +}
>> +
>>  static inline int omap_mux_init_gpio(int gpio, int val)
>>  {
>>       return 0;
>> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
>> index 4a12336..86cb8c4 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>> @@ -2403,3 +2403,16 @@ int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh, bool enable)
>>
>>       return ret;
>>  }
>> +
>> +/**
>> + * omap_hwmod_pad_wakeup_status - get pad wakeup status if mux is available.
>
> How about _get_pad_wakeup_status()
>

Yes fine will update.

>> + * @oh: struct omap_hwmod *
>> + *
>> + * Returns the wake_up status bit of available pad mux pin.
>
> or on error... ?

-EINVAL. Will update the comments.

>
>> + */
>> +int omap_hmwod_pad_wakeup_status(struct omap_hwmod *oh)
>> +{
>> +     if (oh->mux)
>> +             return omap_hwmod_mux_wakeup(oh->mux);
>> +     return -EINVAL;
>> +}
>> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
>> index c405bda..ba58a1d 100644
>> --- a/arch/arm/mach-omap2/pm24xx.c
>> +++ b/arch/arm/mach-omap2/pm24xx.c
>> @@ -137,6 +137,8 @@ static void omap2_enter_full_retention(void)
>>                          OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
>>                          OMAP_SDRC_REGADDR(SDRC_POWER));
>>
>> +     omap_uart_resume_idle();
>> +
>>  no_sleep:
>>       if (omap2_pm_debug) {
>>               unsigned long long tmp;
>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>> index ce0ecdc..3960330 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -216,6 +216,8 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
>>
>>       wkst = omap2_prm_read_mod_reg(module, wkst_off);
>>       wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
>> +
>> +     c += omap_uart_resume_idle();
>
> No...
>
> [...]
>
>> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
>> index 9ed993c..eea478c 100644
>> --- a/drivers/tty/serial/omap-serial.c
>> +++ b/drivers/tty/serial/omap-serial.c
>> @@ -43,6 +43,7 @@
>>  #include <plat/dmtimer.h>
>>  #include <plat/omap-serial.h>
>>  #include <plat/omap_device.h>
>> +#include <plat/serial.h>
>>
>>  static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
>>
>> @@ -108,6 +109,27 @@ static inline void serial_omap_port_enable(struct uart_omap_port *up)
>>       pm_runtime_get_sync(&up->pdev->dev);
>>  }
>>
>> +/* TBD: Should be removed once we irq-chaining mechanism in place */
>
> ...indeed...
>
>> +u32 omap_uart_resume_idle()
>> +{
>> +     int i;
>> +     u32 ret = 0;
>> +
>> +     for (i = 0; i < OMAP_MAX_HSUART_PORTS; i++) {
>> +             struct uart_omap_port *up = ui[i];
>> +
>> +             if (!up)
>> +                     continue;
>> +
>> +             if (up->chk_wakeup(up->pdev)) {
>> +                     serial_omap_port_enable(up);
>> +                     serial_omap_port_disable(up);
>> +                     ret++;
>> +             }
>> +     }
>> +     return ret;
>> +}
>
> ... this is just putting back basically the same thing that was removed in
> patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
> is no different than having it in the idle path.
>
> I thought I understood that you had the SW IRQ triggering working, so
> this part should not be necessary.

Actually I tried few experiments but couldn't get it working.

Tried below but didn't help.

------------------------------------
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3960330..2c1dfc2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
irq, void *dev_id)
        do {
                if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
                                     OMAP3430_IO_ST_MASK)) {
+#if 1
+                       /*
+                        * EXP-1: SET UART1 SOFT IRQ BIT
+                        * 3430 -SDP UART1 console.
+                        * M_IRQ_72, INTCPS_ISR_SET
+                        * 0x4820 0090 + (0x20 * n)
+                        * bit-8 n = 2
+                        */
+                       __raw_writel(0x100 , 0x482000D0);
+#endif
                        c = _prcm_int_handle_wakeup();

                        /*

-----------------------------------

Currently we are planning to integrate irq_chaining patches
on top uart_runtime patches which is work-in-progress.
Will remove resume_idle once we have irq_chaining patches available.

--
Thanks,
Govindraj.R

>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage.
  2011-05-05 10:25     ` Govindraj
@ 2011-05-05 14:52       ` Kevin Hilman
  0 siblings, 0 replies; 40+ messages in thread
From: Kevin Hilman @ 2011-05-05 14:52 UTC (permalink / raw)
  To: Govindraj
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

Govindraj <govindraj.ti@gmail.com> writes:

> On Thu, May 5, 2011 at 2:13 AM, Kevin Hilman <khilman@ti.com> wrote:
>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>
>>> Acquire console lock before enabling and writing to console-uart
>>> to avoid any recursive prints from console write.
>>> for ex:
>>>       --> printk
>>>         --> uart_console_write
>>>           --> get_sync
>>>             --> printk from omap_device enable
>>>               --> uart_console write
>>
>> By this time, since the device's runtime PM hooks have been called, the
>> device's rutime PM state should be set to RPM_SUSPENDING (not yet
>> RPM_SUSPENDED).
>>
>> In addition to the console lock, you should be able to use that flag to
>> avoid console writes while the console is in the process of suspending.
>>
>
> Yes RPM_SUSPENDING check helps along with console lock

Great!

> << Changes as below >>
> ---------------
> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index 59f548f..71964c3 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -1040,6 +1040,18 @@ serial_omap_console_write(struct console *co,
> const char *s,
>         if (console_trylock())
>                 console_lock = 1;
>
> +       /*
> +        * If console_lock is not available and we are in suspending
> +        * state then we can avoid the console usage scenario
> +        * as this may introduce recursive prints.
> +        * Basically this scenario occurs during boot while
> +        * printing debug bootlogs.
> +        */
> +
> +       if (!console_lock &&
> +               up->pdev->dev.power.runtime_status == RPM_SUSPENDING)
> +               return;
> +
>         local_irq_save(flags);
>         if (up->port.sysrq)
>                 locked = 0;
>
> ------------
>
> Is it ok to check the RPM_SUSPENDING flag in driver ?
> I can't find any API currently available under runtime.h to use.

I would propose a new API in pm_runtime.h similar to
pm_runtime_suspended() that checks for this.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-05-05 11:46     ` Govindraj
@ 2011-05-05 14:58       ` Kevin Hilman
  2011-05-06  9:16         ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-05 14:58 UTC (permalink / raw)
  To: Govindraj
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

Govindraj <govindraj.ti@gmail.com> writes:

[...]

>>
>> ... this is just putting back basically the same thing that was removed in
>> patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
>> is no different than having it in the idle path.
>>
>> I thought I understood that you had the SW IRQ triggering working, so
>> this part should not be necessary.
>
> Actually I tried few experiments but couldn't get it working.

What exactly is not working?   The interrupt is not firing at all?  The
driver's ISR is not being called? 

> Tried below but didn't help.
>
> ------------------------------------
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 3960330..2c1dfc2 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
> irq, void *dev_id)
>         do {
>                 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
>                                      OMAP3430_IO_ST_MASK)) {
> +#if 1
> +                       /*
> +                        * EXP-1: SET UART1 SOFT IRQ BIT
> +                        * 3430 -SDP UART1 console.
> +                        * M_IRQ_72, INTCPS_ISR_SET
> +                        * 0x4820 0090 + (0x20 * n)
> +                        * bit-8 n = 2
> +                        */
> +                       __raw_writel(0x100 , 0x482000D0);
> +#endif
>                         c = _prcm_int_handle_wakeup();
>
>                         /*
>
> -----------------------------------
>
> Currently we are planning to integrate irq_chaining patches
> on top uart_runtime patches which is work-in-progress.
> Will remove resume_idle once we have irq_chaining patches available.

Well, I'm not OK with $SUBJECT patch as it is since it's just moving an
ugly hack from serial.c to the PRCM ISR.  If the hack is going to stay,
then it should stay where it is until it can be fixed for real.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag.
  2011-04-29 12:39 ` [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag Govindraj.R
@ 2011-05-05 17:32   ` Kevin Hilman
  2011-05-06  9:34     ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-05 17:32 UTC (permalink / raw)
  To: Govindraj.R
  Cc: linux-omap, linux-serial, linux-arm-kernel, Tony Lindgren,
	Benoit Cousson, Paul Walmsley, Rajendra Nayak

"Govindraj.R" <govindraj.raja@ti.com> writes:

> For omap2 cpu_idle thread will not be available

Why not?

> and uart_clock cutting happens only in suspend path.

Aren't clocks also cut after runtime PM autosuspend?

> Prior to this patch the uart_clock was cut using prepare/resume
> calls since these funcs are no more available with runtime
> changes use no_async_wake flag to keep clock active during bootup
> otherwise uart port will disabled during boot-up and cannot be
> enabled back.

This doesn't just keep clock active during bootup, but it keeps clock
active always, except during suspend.

> Also based on this flag we can disable uart port during suspend
> and enable back during resume.

I think disabling UART port during suspend should already be part of an
earlier patch.  This patch should then only make it conditional.

> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> ---
>  arch/arm/mach-omap2/serial.c                  |    7 +++++++
>  arch/arm/plat-omap/include/plat/omap-serial.h |    3 +++
>  drivers/tty/serial/omap-serial.c              |   14 ++++++++++++++
>  3 files changed, 24 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index d4ef370..1af9fd5 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -245,6 +245,12 @@ static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
>  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>  				unsigned short num)
>  {
> +	/* On omap2 no cpu_idle and async wakeup from prcm_module.

Please remove comments about CPU idle, as the need for this has nothing
to do with CPU idle.

> +	 * This flag can be used to cut clocks only in suspend path.
> +	 * to avoid boot break due to aggressive clock cutting from
> +	 * omap-serial driver.
> +	 */

fix multi-line comment style throughout

> +	uart->no_async_wake = true;

If needed (which I still don't think I understand), for readability sake
this flag should be called 'has_async_wake', and default to false.  It
should then be set to true on available SoCs.

Kevin

>  	if (cpu_is_omap34xx()) {
>  		u32 mod = num > 1 ? OMAP3430_PER_MOD : CORE_MOD;
>  		u32 wk_mask = 0;
> @@ -266,6 +272,7 @@ static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>  			break;
>  		}
>  		uart->wk_mask = wk_mask;
> +		uart->no_async_wake = false;
>  	} else if (cpu_is_omap24xx()) {
>  		u32 wk_mask = 0;
>  		u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
> diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
> index b5117bd..1de5bc4 100644
> --- a/arch/arm/plat-omap/include/plat/omap-serial.h
> +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
> @@ -79,6 +79,7 @@ struct omap_uart_port_info {
>  	void __iomem *wk_st;
>  	void __iomem *wk_en;
>  	u32 wk_mask;
> +	bool			no_async_wake;
>  };
>  
>  struct uart_omap_dma {
> @@ -134,6 +135,8 @@ struct uart_omap_port {
>  	unsigned int		errata;
>  	void (*enable_wakeup)(struct platform_device *, bool);
>  	bool (*chk_wakeup)(struct platform_device *);
> +
> +	bool			no_async_wake;
>  };
>  
>  #endif /* __OMAP_SERIAL_H__ */
> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index eea478c..59f548f 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -1168,6 +1168,13 @@ static int serial_omap_suspend(struct device *dev)
>  		uart_suspend_port(&serial_omap_reg, &up->port);
>  		console_trylock();
>  		serial_omap_pm(&up->port, 3, 0);
> +
> +		/* OMAP2 dont have cpu_idle thread and async wakeup from prcm.
> +		 * For such socs clocks will be kept active from probe and
> +		 * cut only in suspend path.
> +		 */
> +		if (up->no_async_wake)
> +			serial_omap_port_disable(up);
>  	}
>  	return 0;
>  }
> @@ -1179,6 +1186,9 @@ static int serial_omap_resume(struct device *dev)
>  	if (up) {
>  		uart_resume_port(&serial_omap_reg, &up->port);
>  		console_unlock();
> +
> +		if (up->no_async_wake)
> +			serial_omap_port_enable(up);
>  	}
>  
>  	return 0;
> @@ -1402,6 +1412,7 @@ static int serial_omap_probe(struct platform_device *pdev)
>  	up->errata = omap_up_info->errata;
>  	up->enable_wakeup = omap_up_info->enable_wakeup;
>  	up->chk_wakeup = omap_up_info->chk_wakeup;
> +	up->no_async_wake = omap_up_info->no_async_wake;
>  
>  	if (omap_up_info->dma_enabled) {
>  		up->uart_dma.uart_dma_tx = dma_tx->start;
> @@ -1430,6 +1441,9 @@ static int serial_omap_probe(struct platform_device *pdev)
>  		serial_omap_port_disable(up);
>  	}
>  
> +	if (up->no_async_wake)
> +		serial_omap_port_enable(up);
> +
>  	ui[pdev->id] = up;
>  	serial_omap_add_console_port(up);

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-05-05 14:58       ` Kevin Hilman
@ 2011-05-06  9:16         ` Govindraj
  2011-05-06 15:55           ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Govindraj @ 2011-05-06  9:16 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 8:28 PM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
> [...]
>
>>>
>>> ... this is just putting back basically the same thing that was removed in
>>> patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
>>> is no different than having it in the idle path.
>>>
>>> I thought I understood that you had the SW IRQ triggering working, so
>>> this part should not be necessary.
>>
>> Actually I tried few experiments but couldn't get it working.
>
> What exactly is not working?   The interrupt is not firing at all?  The
> driver's ISR is not being called?
>

It throws a oops as here

http://pastebin.com/5bcPjAA0

Reproduced with below [EXP-1] change + below kernel.

git://gitorious.org/uart_runtime/pm.git
[Has uart runtime patches based on pm-core branch]

>> Tried below but didn't help.
>>
>> ------------------------------------
>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>> index 3960330..2c1dfc2 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
>> irq, void *dev_id)
>>         do {
>>                 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
>>                                      OMAP3430_IO_ST_MASK)) {
>> +#if 1
>> +                       /*
>> +                        * EXP-1: SET UART1 SOFT IRQ BIT
>> +                        * 3430 -SDP UART1 console.
>> +                        * M_IRQ_72, INTCPS_ISR_SET
>> +                        * 0x4820 0090 + (0x20 * n)
>> +                        * bit-8 n = 2
>> +                        */
>> +                       __raw_writel(0x100 , 0x482000D0);
>> +#endif
>>                         c = _prcm_int_handle_wakeup();
>>
>>                         /*
>>
>> -----------------------------------
>>
>> Currently we are planning to integrate irq_chaining patches
>> on top uart_runtime patches which is work-in-progress.
>> Will remove resume_idle once we have irq_chaining patches available.
>
> Well, I'm not OK with $SUBJECT patch as it is since it's just moving an
> ugly hack from serial.c to the PRCM ISR.  If the hack is going to stay,
> then it should stay where it is until it can be fixed for real.

Now with runtime changes we are cutting clocks independently
whereas prior to this we where cutting clocks only in sram_idle path.

With runtime changes:
1.) Once we cut uart clocks and send a char to uart it directs wakeup_irq to
prcm_irq_handler the one way to wakeup uart from there was to check
uart mod wakeup status bits if wakeup event occurred then wakeup the
particular uart.
2.) Moving this resume back to sram path will break module wakeup after
uart clocks are disabled(using put_sync)

Thats the reason I have moved this to prcm_irq path to ensure
once auto-suspend happens after inactivity period we have resume_call
to wakeup uart port.

--
Thanks,
Govindraj.R

>
> Kevin
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag.
  2011-05-05 17:32   ` Kevin Hilman
@ 2011-05-06  9:34     ` Govindraj
  0 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-06  9:34 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

On Thu, May 5, 2011 at 11:02 PM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> For omap2 cpu_idle thread will not be available
>
> Why not?
>
>> and uart_clock cutting happens only in suspend path.
>
> Aren't clocks also cut after runtime PM autosuspend?
>
>> Prior to this patch the uart_clock was cut using prepare/resume
>> calls since these funcs are no more available with runtime
>> changes use no_async_wake flag to keep clock active during bootup
>> otherwise uart port will disabled during boot-up and cannot be
>> enabled back.
>
> This doesn't just keep clock active during bootup, but it keeps clock
> active always, except during suspend.
>
>> Also based on this flag we can disable uart port during suspend
>> and enable back during resume.
>
> I think disabling UART port during suspend should already be part of an
> earlier patch.  This patch should then only make it conditional.
>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>> ---
>>  arch/arm/mach-omap2/serial.c                  |    7 +++++++
>>  arch/arm/plat-omap/include/plat/omap-serial.h |    3 +++
>>  drivers/tty/serial/omap-serial.c              |   14 ++++++++++++++
>>  3 files changed, 24 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
>> index d4ef370..1af9fd5 100644
>> --- a/arch/arm/mach-omap2/serial.c
>> +++ b/arch/arm/mach-omap2/serial.c
>> @@ -245,6 +245,12 @@ static void omap_uart_wakeup_enable(struct platform_device *pdev, bool enable)
>>  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>>                               unsigned short num)
>>  {
>> +     /* On omap2 no cpu_idle and async wakeup from prcm_module.
>
> Please remove comments about CPU idle, as the need for this has nothing
> to do with CPU idle.
>
>> +      * This flag can be used to cut clocks only in suspend path.
>> +      * to avoid boot break due to aggressive clock cutting from
>> +      * omap-serial driver.
>> +      */
>
> fix multi-line comment style throughout
>
>> +     uart->no_async_wake = true;
>
> If needed (which I still don't think I understand),

Looking into the pm24xx.c code what I understood is..

(1) omap2_enter_full_retention was cutting and enabling the uart
clocks back whether in idle patch or in suspend path.

(2) since we cut clocks outside this retention path I don't know
how to wake back uart as don't see any irq_handlers servicing
wake-up events in pm24xx.c
[Correct me if I am missing something here.]

(3) Since there was no async wakeup mechanism I could see
on pm24xx.c so one approach was to use of these flags.
[If I cut clocks during boot using put_sync in uart code since no
wakeup mechanism will break boot]

(4) For socs with no aync wakeup we are keeping clocks active from
probe and disabling/enabling clocks in suspend/resume hooks.

> for readability sake
> this flag should be called 'has_async_wake', and default to false.  It
> should then be set to true on available SoCs.

Yes sure I can rename the flag and use above approach.

--
Thanks,
Govindraj.R


>
> Kevin
>
>>       if (cpu_is_omap34xx()) {
>>               u32 mod = num > 1 ? OMAP3430_PER_MOD : CORE_MOD;
>>               u32 wk_mask = 0;
>> @@ -266,6 +272,7 @@ static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>>                       break;
>>               }
>>               uart->wk_mask = wk_mask;
>> +             uart->no_async_wake = false;
>>       } else if (cpu_is_omap24xx()) {
>>               u32 wk_mask = 0;
>>               u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
>> diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
>> index b5117bd..1de5bc4 100644
>> --- a/arch/arm/plat-omap/include/plat/omap-serial.h
>> +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
>> @@ -79,6 +79,7 @@ struct omap_uart_port_info {
>>       void __iomem *wk_st;
>>       void __iomem *wk_en;
>>       u32 wk_mask;
>> +     bool                    no_async_wake;
>>  };
>>
>>  struct uart_omap_dma {
>> @@ -134,6 +135,8 @@ struct uart_omap_port {
>>       unsigned int            errata;
>>       void (*enable_wakeup)(struct platform_device *, bool);
>>       bool (*chk_wakeup)(struct platform_device *);
>> +
>> +     bool                    no_async_wake;
>>  };
>>
>>  #endif /* __OMAP_SERIAL_H__ */
>> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
>> index eea478c..59f548f 100644
>> --- a/drivers/tty/serial/omap-serial.c
>> +++ b/drivers/tty/serial/omap-serial.c
>> @@ -1168,6 +1168,13 @@ static int serial_omap_suspend(struct device *dev)
>>               uart_suspend_port(&serial_omap_reg, &up->port);
>>               console_trylock();
>>               serial_omap_pm(&up->port, 3, 0);
>> +
>> +             /* OMAP2 dont have cpu_idle thread and async wakeup from prcm.
>> +              * For such socs clocks will be kept active from probe and
>> +              * cut only in suspend path.
>> +              */
>> +             if (up->no_async_wake)
>> +                     serial_omap_port_disable(up);
>>       }
>>       return 0;
>>  }
>> @@ -1179,6 +1186,9 @@ static int serial_omap_resume(struct device *dev)
>>       if (up) {
>>               uart_resume_port(&serial_omap_reg, &up->port);
>>               console_unlock();
>> +
>> +             if (up->no_async_wake)
>> +                     serial_omap_port_enable(up);
>>       }
>>
>>       return 0;
>> @@ -1402,6 +1412,7 @@ static int serial_omap_probe(struct platform_device *pdev)
>>       up->errata = omap_up_info->errata;
>>       up->enable_wakeup = omap_up_info->enable_wakeup;
>>       up->chk_wakeup = omap_up_info->chk_wakeup;
>> +     up->no_async_wake = omap_up_info->no_async_wake;
>>
>>       if (omap_up_info->dma_enabled) {
>>               up->uart_dma.uart_dma_tx = dma_tx->start;
>> @@ -1430,6 +1441,9 @@ static int serial_omap_probe(struct platform_device *pdev)
>>               serial_omap_port_disable(up);
>>       }
>>
>> +     if (up->no_async_wake)
>> +             serial_omap_port_enable(up);
>> +
>>       ui[pdev->id] = up;
>>       serial_omap_add_console_port(up);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-05-06  9:16         ` Govindraj
@ 2011-05-06 15:55           ` Kevin Hilman
  2011-05-09 12:23             ` Govindraj
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-05-06 15:55 UTC (permalink / raw)
  To: Govindraj
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak

Govindraj <govindraj.ti@gmail.com> writes:

> On Thu, May 5, 2011 at 8:28 PM, Kevin Hilman <khilman@ti.com> wrote:
>> Govindraj <govindraj.ti@gmail.com> writes:
>>
>> [...]
>>
>>>>
>>>> ... this is just putting back basically the same thing that was removed in
>>>> patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
>>>> is no different than having it in the idle path.
>>>>
>>>> I thought I understood that you had the SW IRQ triggering working, so
>>>> this part should not be necessary.
>>>
>>> Actually I tried few experiments but couldn't get it working.
>>
>> What exactly is not working?   The interrupt is not firing at all?  The
>> driver's ISR is not being called?
>>
>
> It throws a oops as here
>
> http://pastebin.com/5bcPjAA0

This doesn't help understand what exactly is not working.  This needs
to be debugged further to understand the root cause.

A quick glance at the oops shows a fault when accessing a *physical*
address within the INTC.  The MMU is enabled here, and HW accesss should
be using a virtual address.  

Also, early in the boot there are a pile of other errors coming from the
clock framework suggesting that this kernel has some other basic
problems as well.

> Reproduced with below [EXP-1] change + below kernel.
>
> git://gitorious.org/uart_runtime/pm.git
> [Has uart runtime patches based on pm-core branch]
>
>>> Tried below but didn't help.
>>>
>>> ------------------------------------
>>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>>> index 3960330..2c1dfc2 100644
>>> --- a/arch/arm/mach-omap2/pm34xx.c
>>> +++ b/arch/arm/mach-omap2/pm34xx.c
>>> @@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
>>> irq, void *dev_id)
>>>         do {
>>>                 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
>>>                                      OMAP3430_IO_ST_MASK)) {
>>> +#if 1
>>> +                       /*
>>> +                        * EXP-1: SET UART1 SOFT IRQ BIT
>>> +                        * 3430 -SDP UART1 console.
>>> +                        * M_IRQ_72, INTCPS_ISR_SET
>>> +                        * 0x4820 0090 + (0x20 * n)
>>> +                        * bit-8 n = 2
>>> +                        */
>>> +                       __raw_writel(0x100 , 0x482000D0);
>>> +#endif
>>>                         c = _prcm_int_handle_wakeup();
>>>
>>>                         /*
>>>
>>> -----------------------------------
>>>
>>> Currently we are planning to integrate irq_chaining patches
>>> on top uart_runtime patches which is work-in-progress.
>>> Will remove resume_idle once we have irq_chaining patches available.
>>
>> Well, I'm not OK with $SUBJECT patch as it is since it's just moving an
>> ugly hack from serial.c to the PRCM ISR.  If the hack is going to stay,
>> then it should stay where it is until it can be fixed for real.
>
> Now with runtime changes we are cutting clocks independently
> whereas prior to this we where cutting clocks only in sram_idle path.
>
> With runtime changes:
> 1.) Once we cut uart clocks and send a char to uart it directs wakeup_irq to
> prcm_irq_handler the one way to wakeup uart from there was to check
> uart mod wakeup status bits if wakeup event occurred then wakeup the
> particular uart.
> 2.) Moving this resume back to sram path will break module wakeup after
> uart clocks are disabled(using put_sync)
>
> Thats the reason I have moved this to prcm_irq path to ensure
> once auto-suspend happens after inactivity period we have resume_call
> to wakeup uart port.

I understand, but the point is that this approach is still the same as
the previous hack (check for UART wakeup on *every* wakeup event.)

What is needed is to further investigate using SW triggered IRQs can be
done for these wakeup events so we can get away from the above approach
all together.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart
  2011-05-06 15:55           ` Kevin Hilman
@ 2011-05-09 12:23             ` Govindraj
  0 siblings, 0 replies; 40+ messages in thread
From: Govindraj @ 2011-05-09 12:23 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Govindraj.R, linux-omap, linux-serial, linux-arm-kernel,
	Tony Lindgren, Benoit Cousson, Paul Walmsley, Rajendra Nayak,
	Mahadeva, Avinash

On Fri, May 6, 2011 at 9:25 PM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
>> On Thu, May 5, 2011 at 8:28 PM, Kevin Hilman <khilman@ti.com> wrote:
>>> Govindraj <govindraj.ti@gmail.com> writes:
>>>
>>> [...]
>>>
>>>>>
>>>>> ... this is just putting back basically the same thing that was removed in
>>>>> patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
>>>>> is no different than having it in the idle path.
>>>>>
>>>>> I thought I understood that you had the SW IRQ triggering working, so
>>>>> this part should not be necessary.
>>>>
>>>> Actually I tried few experiments but couldn't get it working.
>>>
>>> What exactly is not working?   The interrupt is not firing at all?  The
>>> driver's ISR is not being called?
>>>
>>
>> It throws a oops as here
>>
>> http://pastebin.com/5bcPjAA0
>
> This doesn't help understand what exactly is not working.  This needs
> to be debugged further to understand the root cause.
>
> A quick glance at the oops shows a fault when accessing a *physical*
> address within the INTC.  The MMU is enabled here, and HW accesss should
> be using a virtual address.

Today we could get console_uart booted with irq_patches + uart_runtime
shared by Avinash [Irq_chaining + some local hacks, still not clean patches]

But AFAIK looks like still soft irq method is not generic as we dont
have any similar mechanism for omap4 so how to keep it consistent.

So Shall we retain resume method until we have a generic approach ?

--
Thanks,
Govindraj.R


>
> Also, early in the boot there are a pile of other errors coming from the
> clock framework suggesting that this kernel has some other basic
> problems as well.
>
>> Reproduced with below [EXP-1] change + below kernel.
>>
>> git://gitorious.org/uart_runtime/pm.git
>> [Has uart runtime patches based on pm-core branch]
>>
>>>> Tried below but didn't help.
>>>>
>>>> ------------------------------------
>>>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>>>> index 3960330..2c1dfc2 100644
>>>> --- a/arch/arm/mach-omap2/pm34xx.c
>>>> +++ b/arch/arm/mach-omap2/pm34xx.c
>>>> @@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
>>>> irq, void *dev_id)
>>>>         do {
>>>>                 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
>>>>                                      OMAP3430_IO_ST_MASK)) {
>>>> +#if 1
>>>> +                       /*
>>>> +                        * EXP-1: SET UART1 SOFT IRQ BIT
>>>> +                        * 3430 -SDP UART1 console.
>>>> +                        * M_IRQ_72, INTCPS_ISR_SET
>>>> +                        * 0x4820 0090 + (0x20 * n)
>>>> +                        * bit-8 n = 2
>>>> +                        */
>>>> +                       __raw_writel(0x100 , 0x482000D0);
>>>> +#endif
>>>>                         c = _prcm_int_handle_wakeup();
>>>>
>>>>                         /*
>>>>
>>>> -----------------------------------
>>>>
>>>> Currently we are planning to integrate irq_chaining patches
>>>> on top uart_runtime patches which is work-in-progress.
>>>> Will remove resume_idle once we have irq_chaining patches available.
>>>
>>> Well, I'm not OK with $SUBJECT patch as it is since it's just moving an
>>> ugly hack from serial.c to the PRCM ISR.  If the hack is going to stay,
>>> then it should stay where it is until it can be fixed for real.
>>
>> Now with runtime changes we are cutting clocks independently
>> whereas prior to this we where cutting clocks only in sram_idle path.
>>
>> With runtime changes:
>> 1.) Once we cut uart clocks and send a char to uart it directs wakeup_irq to
>> prcm_irq_handler the one way to wakeup uart from there was to check
>> uart mod wakeup status bits if wakeup event occurred then wakeup the
>> particular uart.
>> 2.) Moving this resume back to sram path will break module wakeup after
>> uart clocks are disabled(using put_sync)
>>
>> Thats the reason I have moved this to prcm_irq path to ensure
>> once auto-suspend happens after inactivity period we have resume_call
>> to wakeup uart port.
>
> I understand, but the point is that this approach is still the same as
> the previous hack (check for UART wakeup on *every* wakeup event.)
>
> What is needed is to further investigate using SW triggered IRQs can be
> done for these wakeup events so we can get away from the above approach
> all together.
>
> Kevin
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2011-05-09 12:23 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-29 12:39 [PATCH v2 00/12] OMAP2+: Serial: Runtime adaptation + cleanup Govindraj.R
2011-04-29 12:39 ` [PATCH v2 01/12] OMAP2+: UART: Remove certain uart calls from sram_idle Govindraj.R
2011-04-29 12:39 ` [PATCH v2 02/12] OMAP2+: UART: Remove uart clock handling code from serial.c Govindraj.R
2011-04-29 13:20   ` Alan Cox
2011-04-29 12:39 ` [PATCH v2 03/12] OMAP2+: Serial: Add default mux for all uarts Govindraj.R
2011-05-04 10:00   ` Tony Lindgren
2011-05-04 10:34     ` Govindraj
2011-04-29 12:39 ` [PATCH v2 04/12] Serial: OMAP: Add runtime pm support for omap-serial driver Govindraj.R
2011-05-04 20:35   ` Kevin Hilman
2011-05-04 21:05     ` Paul Walmsley
2011-05-05  5:48     ` Raja, Govindraj
2011-05-05  5:55     ` Govindraj
2011-04-29 12:39 ` [PATCH v2 05/12] OMAP: Serial: Hold console lock for console usage Govindraj.R
2011-05-04 10:02   ` Tony Lindgren
2011-05-04 10:09     ` Russell King - ARM Linux
2011-05-04 10:19     ` Govindraj
2011-05-04 20:43   ` Kevin Hilman
2011-05-05 10:25     ` Govindraj
2011-05-05 14:52       ` Kevin Hilman
2011-04-29 12:39 ` [PATCH v2 06/12] Serial: OMAP2+: Move erratum handling from serial.c Govindraj.R
2011-04-29 12:39 ` [PATCH v2 07/12] OMAP: Serial: Allow UART parameters to be configured from board file Govindraj.R
2011-05-04  9:55   ` Tony Lindgren
2011-05-04 10:06     ` Govindraj
2011-05-04 10:25       ` Tony Lindgren
2011-05-04 10:39         ` Govindraj
2011-04-29 12:39 ` [PATCH v2 08/12] Serial: OMAP2+: Make the RX_TIMEOUT for DMA configurable for each UART Govindraj.R
2011-04-29 12:39 ` [PATCH v2 09/12] OMAP3: Serial: Remove uart pads from 3430 board file Govindraj.R
2011-04-29 12:39 ` [PATCH v2 10/12] OMAP2+: hwmod: Add api to enable io_ring wakeup Govindraj.R
2011-05-04 23:59   ` Kevin Hilman
2011-05-05  5:58     ` Govindraj
2011-04-29 12:39 ` [PATCH v2 11/12] OMAP: Serial: Use resume call from prcm to enable uart Govindraj.R
2011-05-05  0:11   ` Kevin Hilman
2011-05-05 11:46     ` Govindraj
2011-05-05 14:58       ` Kevin Hilman
2011-05-06  9:16         ` Govindraj
2011-05-06 15:55           ` Kevin Hilman
2011-05-09 12:23             ` Govindraj
2011-04-29 12:39 ` [PATCH v2 12/12] OMAP2: Serial: Add no async wake flag Govindraj.R
2011-05-05 17:32   ` Kevin Hilman
2011-05-06  9:34     ` Govindraj

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).