linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
@ 2011-09-30 11:01 Govindraj.R
  2011-09-30 11:01 ` [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status Govindraj.R
                   ` (8 more replies)
  0 siblings, 9 replies; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Add API to enable IO pad wakeup capability based on mux dynamic pad and
wake_up enable flag available from hwmod_mux initialization.

Use the wakeup_enable flag and enable wakeup capability
for the given pads. Wakeup capability will be enabled/disabled
during hwmod idle transition based on whether wakeup_flag is
set or cleared.

Call the omap_hwmod_set_ioring_wakeup from hwmod_wakeup_enable/disable.

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

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 84cc0bd..e751dd9 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2062,6 +2062,34 @@ static int __init omap_hwmod_setup_all(void)
 core_initcall(omap_hwmod_setup_all);
 
 /**
+ * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
+ * @oh: struct omap_hwmod *
+ * @set: bool value indicating to set or clear wakeup status.
+ *
+ * Set or Clear wakeup flag for the io_pad.
+ */
+static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
+{
+	struct omap_device_pad *pad;
+	int ret = -EINVAL, j;
+
+	if (oh->mux && 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) {
+				if (set_wake)
+					pad->idle |= OMAP_WAKEUP_EN;
+				else
+					pad->idle &= ~OMAP_WAKEUP_EN;
+				ret = 0;
+			}
+		}
+	}
+
+	return ret;
+}
+
+/**
  * omap_hwmod_enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -2393,6 +2421,35 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
 {
 	return _del_initiator_dep(oh, init_oh);
 }
+/**
+ * omap_hwmod_enable_ioring_wakeup - Set wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * set wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Enable pad wake-up capability */
+	return omap_hwmod_set_ioring_wakeup(oh, true);
+}
+
+/**
+ * omap_hwmod_disable_ioring_wakeup - Clear wakeup flag for iopad.
+ * @oh: struct omap_hwmod *
+ *
+ * Traverse through dynamic pads, if pad is enabled then
+ * clear wakeup enable bit flag for the mux pin. Wakeup pad bit
+ * will be set during hwmod idle transistion.
+ * Return error if pads are not enabled or not available.
+ */
+int omap_hwmod_disable_ioring_wakeup(struct omap_hwmod *oh)
+{
+	/* Disable pad wakeup capability */
+	return omap_hwmod_set_ioring_wakeup(oh, false);
+}
 
 /**
  * omap_hwmod_enable_wakeup - allow device to wake up the system
@@ -2419,6 +2476,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_enable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_enable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
@@ -2449,6 +2507,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
 	v = oh->_sysc_cache;
 	_disable_wakeup(oh, &v);
 	_write_sysconfig(v, oh);
+	omap_hwmod_disable_ioring_wakeup(oh);
 	spin_unlock_irqrestore(&oh->_lock, flags);
 
 	return 0;
-- 
1.7.4.1

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-01 14:33   ` Rajendra Nayak
  2011-09-30 11:01 ` [PATCH v6 03/16] OMAP2+: UART: cleanup + remove uart pm specific API Govindraj.R
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Add API to determine IO-PAD wakeup event status for a given
hwmod dynamic_mux pad.

Wake up event set will be cleared on pad mux_read.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/mux.c                    |   30 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/mux.h                    |   13 +++++++++++
 arch/arm/mach-omap2/omap_hwmod.c             |    7 ++++++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
 4 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 655e948..fb75aae 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -351,6 +351,36 @@ err1:
 	return NULL;
 }
 
+/**
+ * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Gets the wakeup status of given pad from omap-hwmod.
+ * Returns true if wakeup capability is set and wakeup event occurred.
+ * Returns false if wakeup event has not occurred or pads are not available.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
+{
+	int i;
+	unsigned int val;
+	u8 ret = false;
+
+	for (i = 0; i < hmux->nr_pads; i++) {
+		struct omap_device_pad *pad = &hmux->pads[i];
+
+		if (pad->flags & OMAP_DEVICE_PAD_WAKEUP) {
+			val = omap_mux_read(pad->partition,
+					pad->mux->reg_offset);
+			if (val & OMAP_WAKEUP_EVENT) {
+				ret = true;
+				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 2132308..8b2150a 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_get_wake_status - omap hwmod check pad wakeup
+ * @hmux:		Pads for a hwmod
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
 #else
 
+static inline bool
+omap_hwmod_mux_get_wake_status(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 e751dd9..a8b24d7 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2724,3 +2724,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
 
 	return 0;
 }
+
+int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
+{
+	if (oh && oh->mux)
+		return omap_hwmod_mux_get_wake_status(oh->mux);
+	return -EINVAL;
+}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 0e329ca..9a6195c 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -607,6 +607,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_pad_get_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
-- 
1.7.4.1

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

* [PATCH v6 03/16] OMAP2+: UART: cleanup + remove uart pm specific API
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
  2011-09-30 11:01 ` [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-09-30 11:01 ` [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support Govindraj.R
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

In preparation to UART runtime conversion remove uart specific calls
from pm24xx/34xx files and their definition from serial.c
These func calls will no more be used with upcoming uart runtime design.

1.) omap_uart_prepare_suspend :- can be taken care with driver suspend hooks.
2.) omap_uart_enable_irqs :- Used to enable/disable uart irq's in suspend
    path from PM code, this is removed as same is handled by
    uart_suspend_port/uart_resume_port in omap-serial driver which will
    do an port_shutdown on suspend freeing irq and port_startup on resume
    enabling back irq.
3.) Remove prepare_idle/resume_idle calls used to gate uart clocks.
    UART clocks can be gated within driver using runtime funcs
    and be woken up using irq_chaining from omap_prm driver.
4.) Remove console_locking from idle path as clock gating is done withing
    driver itself with runtime API.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/pm24xx.c             |   18 --------
 arch/arm/mach-omap2/pm34xx.c             |   23 ----------
 arch/arm/mach-omap2/serial.c             |   65 ------------------------------
 arch/arm/plat-omap/include/plat/serial.h |    4 --
 4 files changed, 0 insertions(+), 110 deletions(-)

diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index bf089e7..a75f764 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -30,7 +30,6 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
-#include <linux/console.h>
 
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
@@ -133,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;
@@ -317,7 +300,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 7255d9b..344d412 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,7 +28,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/console.h>
 #include <trace/events/power.h>
 
 #include <asm/suspend.h>
@@ -379,18 +378,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();
@@ -398,8 +388,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();
@@ -446,8 +434,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,
@@ -461,14 +447,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 ||
@@ -531,7 +511,6 @@ static int omap3_pm_suspend(void)
 			goto restore;
 	}
 
-	omap_uart_prepare_suspend();
 	omap3_intc_suspend();
 
 	omap_sram_idle();
@@ -578,14 +557,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/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 3d1c1d3..62d15ad 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -389,51 +389,6 @@ static void omap_uart_idle_timer(unsigned long 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;
@@ -552,26 +507,6 @@ static void omap_uart_idle_init(struct omap_uart_state *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)
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index de3b10c..fc8b60c 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -111,10 +111,6 @@ 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.4.1

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

* [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
  2011-09-30 11:01 ` [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status Govindraj.R
  2011-09-30 11:01 ` [PATCH v6 03/16] OMAP2+: UART: cleanup + remove uart pm specific API Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-04 21:42   ` Kevin Hilman
  2011-09-30 11:01 ` [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart Govindraj.R
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

We had been using traditional 8250 driver as uart console driver
prior to omap-serial driver. Since we have omap-serial driver
in mainline kernel for some time now it has been used as default
uart console driver on omap2+ platforms. Remove 8250 support for
omap-uarts.

Serial_in and serial_out override for 8250 serial driver is also
removed. Empty fifo read fix is already taken care with omap-serial
driver with data ready bit check from LSR reg before reading RX fifo.
Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr
in omap-serial driver.

Remove headers that were necessary to support 8250 support
and remove all config bindings done to keep 8250 backward compatibility
while adding omap-serial driver. Remove omap_uart_reset needed for
8250 autoconf.

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

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 62d15ad..4ab90bf 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -19,23 +19,17 @@
  */
 #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>
@@ -47,10 +41,8 @@
 #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)
 
 /*
@@ -157,19 +149,6 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
 	__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)
 
 /*
@@ -555,41 +534,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *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)
-{
-	if (UART_RX == offset) {
-		unsigned int lsr;
-		lsr = __serial_read_reg(up, UART_LSR);
-		if (!(lsr & UART_LSR_DR))
-			return -EPERM;
-	}
-
-	return __serial_read_reg(up, offset);
-}
-
-static void serial_out_override(struct uart_port *up, int offset, int value)
-{
-	unsigned int status, tmout = 10000;
-
-	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);
-}
-#endif
-
 static int __init omap_serial_early_init(void)
 {
 	int i = 0;
@@ -650,15 +594,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	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
 
 	if (WARN_ON(!bdata))
 		return;
@@ -673,51 +609,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	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;
-
-	if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
-		p->serial_in = serial_in_override;
-		p->serial_out = serial_out_override;
-	}
-
-	pdata = &ports[0];
-	pdata_size = 2 * sizeof(struct plat_serial8250_port);
-#else
-
 	name = DRIVER_NAME;
 
 	omap_up.dma_enabled = uart->dma_enabled;
@@ -729,7 +620,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	pdata = &omap_up;
 	pdata_size = sizeof(struct omap_uart_port_info);
-#endif
 
 	if (WARN_ON(!oh))
 		return;
@@ -762,7 +652,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	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);
 
-- 
1.7.4.1

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

* [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (2 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-10 22:30   ` Kevin Hilman
  2011-09-30 11:01 ` [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct Govindraj.R
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Currently we use a shared irq handler to identify uart activity and then
trigger a timer. Based the timeout value set from sysfs the timer used to
expire. If no uart-activity was detected timer-expiry func sets can_sleep
flag. Based on this we will disable the uart clocks in idle path.

Since the clock gating mechanism is outside the uart driver, we currently
use this mechanism. In preparation to runtime implementation for omap-serial
driver we can cleanup this mechanism and use runtime API's to gate uart clocks.

Also remove timer related info from local uart_state struct and remove
the code used to set timeout value from sysfs. Remove un-used function
omap_uart_check_wakeup.

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

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 4ab90bf..c98b9b4 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -58,8 +58,6 @@
 struct omap_uart_state {
 	int num;
 	int can_sleep;
-	struct timer_list timer;
-	u32 timeout;
 
 	void __iomem *wk_st;
 	void __iomem *wk_en;
@@ -67,13 +65,9 @@ struct omap_uart_state {
 	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;
 
@@ -340,32 +334,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *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);
 }
 
 int omap_uart_can_sleep(void)
@@ -389,35 +357,11 @@ int omap_uart_can_sleep(void)
 	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()) {
@@ -479,51 +423,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		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);
-}
-
-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)
@@ -531,7 +432,6 @@ 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 */
 
 static int __init omap_serial_early_init(void)
@@ -615,7 +515,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	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;
 
 	pdata = &omap_up;
@@ -633,7 +532,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_device_disable_idle_on_suspend(pdev);
 	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);
@@ -655,24 +553,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	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)) {
+	    (uart->wk_en && uart->wk_mask))
 		device_init_wakeup(&pdev->dev, true);
-		DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
-	}
 
 	/* Enable the MDR1 errata for OMAP3 */
 	if (cpu_is_omap34xx() && !cpu_is_ti816x())
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2682043..307cd6f 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -61,7 +61,6 @@ struct omap_uart_port_info {
 	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 */
 };
 
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index fc8b60c..a8bc1f1 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -110,7 +110,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);
 #endif
 
 #endif
-- 
1.7.4.1

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

* [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (3 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-10 23:31   ` Kevin Hilman
  2011-09-30 11:01 ` [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts Govindraj.R
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Removing some of the uart info that is maintained in omap_uart_state struct
used for UART PM in serial.c.

Remove omap_uart_state struct dependency from omap_serial_init,
omap_serial_init_port, omap_serial_early_init and omap_uart_idle_init functions.
And populate the same info in omap_uart_port_info struct used as pdata struct.

Added omap_uart_hwmod_lookup function to look up oh by name used
in serial_port_init and omap_serial_early_init functions.

A list of omap_uart_state was maintained one for each uart, the same is removed.
Number of uarts available is maintained in num_uarts field, re-use the same in
omap_serial_init func to register each uart.

Remove omap_info which used details from omap_uart_state and use
a pdata pointer to pass platform specific info to driver.

The mapbase (start_address), membase(io_remap cookie) maintained as part of
uart_state struct and pdata struct are removed as this is handled within
driver. Errata field is also moved to pdata. These changes are done
to cleanup serial.c file and prepare for runtime changes.

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

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index c98b9b4..8c43d1c 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -68,14 +68,6 @@ struct omap_uart_state {
 	int clocked;
 
 	int regshift;
-	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;
 
@@ -90,7 +82,6 @@ struct omap_uart_state {
 #endif
 };
 
-static LIST_HEAD(uart_list);
 static u8 num_uarts;
 
 static int uart_idle_hwmod(struct omap_device *od)
@@ -143,7 +134,19 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
 	__raw_writeb(value, uart->membase + offset);
 }
 
-#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+struct omap_hwmod *omap_uart_hwmod_lookup(int num)
+{
+	struct omap_hwmod *oh;
+	char oh_name[MAX_UART_HWMOD_NAME_LEN];
+
+	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;
+}
+
+#if defined(CONFIG_PM)
 
 /*
  * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
@@ -357,22 +360,17 @@ int omap_uart_can_sleep(void)
 	return can_sleep;
 }
 
-static void omap_uart_idle_init(struct omap_uart_state *uart)
+static void omap_uart_idle_init(struct omap_uart_port_info *uart,
+				unsigned short num)
 {
-	int ret;
-
-	uart->can_sleep = 0;
-	omap_uart_smart_idle_enable(uart, 0);
-
 	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
-		u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
+		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;
@@ -391,12 +389,11 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 			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;
@@ -421,7 +418,6 @@ 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;
 	}
 }
 
@@ -436,26 +432,13 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
 
 static int __init omap_serial_early_init(void)
 {
-	int i = 0;
-
 	do {
-		char oh_name[MAX_UART_HWMOD_NAME_LEN];
 		struct omap_hwmod *oh;
-		struct omap_uart_state *uart;
 
-		snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
-			 "uart%d", i + 1);
-		oh = omap_hwmod_lookup(oh_name);
+		oh = omap_uart_hwmod_lookup(num_uarts);
 		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++;
 
 		/*
@@ -468,7 +451,7 @@ static int __init omap_serial_early_init(void)
 		 * 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;
+		oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
 	} while (1);
 
 	return 0;
@@ -488,57 +471,47 @@ 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 platform_device *pdev;
-	void *pdata = NULL;
+	char *name = DRIVER_NAME;
+	struct omap_uart_port_info *pdata;
 	u32 pdata_size = 0;
-	char *name;
-	struct omap_uart_port_info omap_up;
 
 	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;
-	name = DRIVER_NAME;
+	oh = omap_uart_hwmod_lookup(bdata->id);
+	if (!oh)
+		return;
 
-	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.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("Memory allocation for UART pdata failed\n");
+		return;
+	}
 
-	pdata = &omap_up;
 	pdata_size = sizeof(struct omap_uart_port_info);
+	omap_uart_idle_init(pdata, bdata->id);
 
-	if (WARN_ON(!oh))
-		return;
+	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
+	pdata->flags = UPF_BOOT_AUTOCONF;
+
+	/* Enable the MDR1 errata for OMAP3 */
+	if (cpu_is_omap34xx() && !cpu_is_ti816x())
+		pdata->errata |= UART_ERRATA_i202_MDR1_ACCESS;
 
-	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
-			       omap_uart_latency,
-			       ARRAY_SIZE(omap_uart_latency), false);
+	pdev = omap_device_build(name, bdata->id, oh, pdata,
+				pdata_size, omap_uart_latency,
+				ARRAY_SIZE(omap_uart_latency), false);
 	WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
 	     name, oh->name);
 
-	omap_device_disable_idle_on_suspend(pdev);
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
-	uart->regshift = 2;
-	uart->mapbase = oh->slaves[0]->addr->pa_start;
-	uart->membase = omap_hwmod_get_mpu_rt_va(oh);
-	uart->pdev = pdev;
-
-	oh->dev_attr = uart;
-
 	console_lock(); /* in case the earlycon is on the UART */
 
 	/*
@@ -546,23 +519,18 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	 * on init.  Now that omap_device is ready, ensure full idle
 	 * before doing omap_device_enable().
 	 */
-	omap_hwmod_idle(uart->oh);
+	omap_hwmod_idle(oh);
 
-	omap_device_enable(uart->pdev);
-	omap_uart_idle_init(uart);
-	omap_hwmod_enable_wakeup(uart->oh);
-	omap_device_idle(uart->pdev);
+	omap_device_enable(pdev);
+	omap_hwmod_enable_wakeup(oh);
 
-	omap_uart_block_sleep(uart);
 	console_unlock();
 
-	if ((cpu_is_omap34xx() && uart->padconf) ||
-	    (uart->wk_en && uart->wk_mask))
+	if ((cpu_is_omap34xx() && bdata->pads) ||
+		(pdata->wk_en && pdata->wk_mask))
 		device_init_wakeup(&pdev->dev, true);
 
-	/* Enable the MDR1 errata for OMAP3 */
-	if (cpu_is_omap34xx() && !cpu_is_ti816x())
-		uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
+	kfree(pdata);
 }
 
 /**
@@ -574,11 +542,11 @@ 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 < num_uarts; i++) {
+		bdata.id = i;
 		bdata.flags = 0;
 		bdata.pads = NULL;
 		bdata.pads_cnt = 0;
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 307cd6f..0f061b4 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -59,9 +59,9 @@
 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 */
 	upf_t			flags;		/* UPF_* flags */
+
+	u32			errata;
 };
 
 struct uart_omap_dma {
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 5e713d3..6c2ea54 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1275,10 +1275,16 @@ 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, resource_size(mem));
+
+	if (!up->port.membase) {
+		dev_err(&pdev->dev, "can't ioremap UART\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	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;
 
-- 
1.7.4.1

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

* [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts.
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (4 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-05 19:04   ` Kevin Hilman
  2011-09-30 11:01 ` [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure Govindraj.R
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Prior to this change rx-pad wakeup was done by writing to rx-pad offset value
populated in serial.c idle_init. Now with mux framework support we can use
mux_utilities along with hmwod framework to handle io-pad configuration and
enable rx-pad wake-up mechanism.

Add default mux data for all uart's if mux info is not passed from
board file to avoid breaking any board support.
With the default pads we have populated in serial.c wakeup capability for
rx pads are enabled, this can be used to enable uart_rx io-pad wakeup from
hwmod framework. The pad values in 3430sdp/4430sdp/omap4panda board file
are same as the default pad values populated in serial.c. Remove pad values
from 3430sdp/4430sdp/omap4panda board file and use the default pads
from serial.c file.

Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c    |  100 +----------------
 arch/arm/mach-omap2/board-4430sdp.c    |   68 +-----------
 arch/arm/mach-omap2/board-omap4panda.c |   68 +-----------
 arch/arm/mach-omap2/serial.c           |  192 +++++++++++++++++++++-----------
 4 files changed, 131 insertions(+), 297 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index bd600cf..b12b38f 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -482,106 +482,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 __initdata = {
-	.id		= 0,
-	.pads		= serial1_pads,
-	.pads_cnt	= ARRAY_SIZE(serial1_pads),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-	.id		= 1,
-	.pads		= serial2_pads,
-	.pads_cnt	= ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-	.id		= 2,
-	.pads		= serial3_pads,
-	.pads_cnt	= ARRAY_SIZE(serial3_pads),
-};
-
-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);
-}
 #else
 #define board_mux	NULL
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init();
-}
 #endif
 
 /*
@@ -718,7 +620,7 @@ static void __init omap_3430sdp_init(void)
 	else
 		gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
 	omap_ads7846_init(1, gpio_pendown, 310, NULL);
-	board_serial_init();
+	omap_serial_init();
 	usb_musb_init(NULL);
 	board_smc91x_init();
 	board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index c7cef44..b80e506 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -688,74 +688,8 @@ static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
-static struct omap_device_pad serial2_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-			 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial4_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart4_rx.uart4_rx",
-			 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart4_tx.uart4_tx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-	.id		= 1,
-	.pads		= serial2_pads,
-	.pads_cnt	= ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-	.id		= 2,
-	.pads		= serial3_pads,
-	.pads_cnt	= ARRAY_SIZE(serial3_pads),
-};
-
-static struct omap_board_data serial4_data __initdata = {
-	.id		= 3,
-	.pads		= serial4_pads,
-	.pads_cnt	= ARRAY_SIZE(serial4_pads),
-};
-
-static inline void board_serial_init(void)
-{
-	struct omap_board_data bdata;
-	bdata.flags	= 0;
-	bdata.pads	= NULL;
-	bdata.pads_cnt	= 0;
-	bdata.id	= 0;
-	/* pass dummy data for UART1 */
-	omap_serial_init_port(&bdata);
-
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-	omap_serial_init_port(&serial4_data);
-}
 #else
 #define board_mux	NULL
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init();
-}
  #endif
 
 static void omap4_sdp4430_wifi_mux_init(void)
@@ -808,7 +742,7 @@ static void __init omap_4430sdp_init(void)
 	omap4_i2c_init();
 	omap_sfh7741prox_init();
 	platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
-	board_serial_init();
+	omap_serial_init();
 	omap4_sdp4430_wifi_init();
 	omap4_twl6030_hsmmc_init(mmc);
 
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 9aaa960..1410312 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -370,74 +370,8 @@ static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
-static struct omap_device_pad serial2_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-			 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-			 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial4_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart4_rx.uart4_rx",
-			 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart4_tx.uart4_tx",
-			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-	.id             = 1,
-	.pads           = serial2_pads,
-	.pads_cnt       = ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-	.id             = 2,
-	.pads           = serial3_pads,
-	.pads_cnt       = ARRAY_SIZE(serial3_pads),
-};
-
-static struct omap_board_data serial4_data __initdata = {
-	.id             = 3,
-	.pads           = serial4_pads,
-	.pads_cnt       = ARRAY_SIZE(serial4_pads),
-};
-
-static inline void board_serial_init(void)
-{
-	struct omap_board_data bdata;
-	bdata.flags     = 0;
-	bdata.pads      = NULL;
-	bdata.pads_cnt  = 0;
-	bdata.id        = 0;
-	/* pass dummy data for UART1 */
-	omap_serial_init_port(&bdata);
-
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-	omap_serial_init_port(&serial4_data);
-}
 #else
 #define board_mux	NULL
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init();
-}
 #endif
 
 /* Display DVI */
@@ -568,7 +502,7 @@ static void __init omap4_panda_init(void)
 	omap4_panda_i2c_init();
 	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
 	platform_device_register(&omap_vwlan_device);
-	board_serial_init();
+	omap_serial_init();
 	omap4_twl6030_hsmmc_init(mmc);
 	omap4_ehci_init();
 	usb_musb_init(&musb_board_data);
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 8c43d1c..ca6807c 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -58,11 +58,6 @@
 struct omap_uart_state {
 	int num;
 	int can_sleep;
-
-	void __iomem *wk_st;
-	void __iomem *wk_en;
-	u32 wk_mask;
-	u32 padconf;
 	u32 dma_enabled;
 
 	int clocked;
@@ -360,69 +355,135 @@ int omap_uart_can_sleep(void)
 	return can_sleep;
 }
 
-static void omap_uart_idle_init(struct omap_uart_port_info *uart,
-				unsigned short num)
+#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,
+		.idle	= 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,
+		.idle	= 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,
+		.idle	= 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,
+		.idle	= 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,
+		.idle	= 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)
 {
-	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
-		u32 mod = (num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
-		u32 wk_mask = 0;
-		u32 padconf = 0;
-
-		uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
-		uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
-		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;
-	} else if (cpu_is_omap24xx()) {
-		u32 wk_mask = 0;
-		u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
-
-		switch (num) {
-		case 0:
-			wk_mask = OMAP24XX_ST_UART1_MASK;
-			break;
-		case 1:
-			wk_mask = OMAP24XX_ST_UART2_MASK;
-			break;
-		case 2:
-			wk_en = OMAP24XX_PM_WKEN2;
-			wk_st = OMAP24XX_PM_WKST2;
-			wk_mask = OMAP24XX_ST_UART3_MASK;
-			break;
-		}
-		uart->wk_mask = wk_mask;
-		if (cpu_is_omap2430()) {
-			uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
-			uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
-		} else if (cpu_is_omap2420()) {
-			uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
-			uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
+	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);
 		}
-	} else {
-		uart->wk_en = NULL;
-		uart->wk_st = NULL;
-		uart->wk_mask = 0;
+		break;
+	default:
+		break;
 	}
 }
 
 #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 */
@@ -495,7 +556,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	}
 
 	pdata_size = sizeof(struct omap_uart_port_info);
-	omap_uart_idle_init(pdata, bdata->id);
 
 	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
 	pdata->flags = UPF_BOOT_AUTOCONF;
@@ -526,7 +586,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	console_unlock();
 
-	if ((cpu_is_omap34xx() && bdata->pads) ||
+	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) ||
 		(pdata->wk_en && pdata->wk_mask))
 		device_init_wakeup(&pdev->dev, true);
 
@@ -550,6 +610,10 @@ void __init omap_serial_init(void)
 		bdata.flags = 0;
 		bdata.pads = NULL;
 		bdata.pads_cnt = 0;
+
+		if (cpu_is_omap44xx() || cpu_is_omap34xx())
+			omap_serial_fill_default_pads(&bdata);
+
 		omap_serial_init_port(&bdata);
 
 	}
-- 
1.7.4.1

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

* [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (5 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-10 23:58   ` Kevin Hilman
  2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
  2011-10-01 13:41 ` [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Rajendra Nayak
  8 siblings, 1 reply; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

In preparation to runtime conversion add missing uart regs to
port structure which can be used in context restore.
Also ensuring all uart reg info's are part of port structure.

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

diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 0f061b4..74822b3 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -99,6 +99,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;
 	/*
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 6c2ea54..9a0eac2 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -433,8 +433,9 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	if (mctrl & TIOCM_LOOP)
 		mcr |= UART_MCR_LOOP;
 
-	mcr |= up->mcr;
-	serial_out(up, UART_MCR, mcr);
+	up->mcr = serial_in(up, UART_MCR);
+	up->mcr |= mcr;
+	serial_out(up, UART_MCR, up->mcr);
 }
 
 static void serial_omap_break_ctl(struct uart_port *port, int break_state)
@@ -573,8 +574,6 @@ static inline void
 serial_omap_configure_xonxoff
 		(struct uart_omap_port *up, struct ktermios *termios)
 {
-	unsigned char efr = 0;
-
 	up->lcr = serial_in(up, UART_LCR);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	up->efr = serial_in(up, UART_EFR);
@@ -584,8 +583,7 @@ serial_omap_configure_xonxoff
 	serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]);
 
 	/* clear SW control mode bits */
-	efr = up->efr;
-	efr &= OMAP_UART_SW_CLR;
+	up->efr &= OMAP_UART_SW_CLR;
 
 	/*
 	 * IXON Flag:
@@ -593,7 +591,7 @@ serial_omap_configure_xonxoff
 	 * Transmit XON1, XOFF1
 	 */
 	if (termios->c_iflag & IXON)
-		efr |= OMAP_UART_SW_TX;
+		up->efr |= OMAP_UART_SW_TX;
 
 	/*
 	 * IXOFF Flag:
@@ -601,7 +599,7 @@ serial_omap_configure_xonxoff
 	 * Receiver compares XON1, XOFF1.
 	 */
 	if (termios->c_iflag & IXOFF)
-		efr |= OMAP_UART_SW_RX;
+		up->efr |= OMAP_UART_SW_RX;
 
 	serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
@@ -624,7 +622,7 @@ serial_omap_configure_xonxoff
 	 * load the new software flow control mode IXON or IXOFF
 	 * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
 	 */
-	serial_out(up, UART_EFR, efr | UART_EFR_SCD);
+	serial_out(up, UART_EFR, up->efr | UART_EFR_SCD);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 
 	serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
@@ -671,6 +669,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)
@@ -723,6 +725,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 		up->ier |= UART_IER_MSI;
 	serial_out(up, UART_IER, up->ier);
 	serial_out(up, UART_LCR, cval);		/* reset DLAB */
+	up->lcr = cval;
 
 	/* FIFOs and DMA Settings */
 
@@ -759,7 +762,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	/* 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 +772,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 +783,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 */
 
-- 
1.7.4.1

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (6 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure Govindraj.R
@ 2011-09-30 11:01 ` Govindraj.R
  2011-10-10 23:42   ` Kevin Hilman
                     ` (2 more replies)
  2011-10-01 13:41 ` [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Rajendra Nayak
  8 siblings, 3 replies; 41+ messages in thread
From: Govindraj.R @ 2011-09-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

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

Use runtime runtime API's to handle uart clocks and obtain
device_usage statics. Set runtime API's usage to irq_safe so that
we can use get_sync from irq context. Auto-suspend for port specific
activities and put for reg access. Use device_may_wakeup to check
whether uart has wakeup capabilities and then enable uart runtime
usage for the uart.

Removing save_context/restore_context functions from serial.c
Adding context restore to .runtime_suspend and using reg values from port
structure to restore the uart port context based on context_loss_count.
Maintain internal state machine using wakeups_enabled field for avoiding
repeated enable/disable of uart port wakeup mechanism.

Remove omap_uart_disable_wakeup and modify omap_uart_enable_wakeup
to accept pdev and bool value to enable/disable the uart wakeup mechanism
after uart clock's are cut. omap_hwmod_enable_wakeup is used to set
pad wakeup for the uarts. PM_WKEN reg values are left to default.
Removed omap_uart_enable/disable_clocks in serial.c now clock handling
done with runtime API's.

By default uart autosuspend delay is set to -1 to avoid character loss
if uart's are autoidled and woken up on rx pin.

After boot up UART's can be autoidled by setting autosuspendi delay from sysfs.

echo 3000 > /sys/devices/platform/omap/omap_uart.X/power/autosuspend_delay_ms
X=0,1,2,3 for UART1/2/3/4. Number of uarts available may vary across omap_soc.

Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
---
 arch/arm/mach-omap2/serial.c                  |  206 ++----------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |    5 +
 drivers/tty/serial/omap-serial.c              |  169 +++++++++++++++++++--
 3 files changed, 179 insertions(+), 201 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index ca6807c..6725caf 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -33,6 +33,7 @@
 #include <plat/dma.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/omap-pm.h>
 
 #include "prm2xxx_3xxx.h"
 #include "pm.h"
@@ -41,8 +42,6 @@
 #include "control.h"
 #include "mux.h"
 
-#define UART_OMAP_WER		0x17	/* Wake-up enable register */
-
 #define UART_ERRATA_i202_MDR1_ACCESS	(0x1 << 1)
 
 /*
@@ -57,24 +56,7 @@
 
 struct omap_uart_state {
 	int num;
-	int can_sleep;
 	u32 dma_enabled;
-
-	int clocked;
-
-	int regshift;
-#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 u8 num_uarts;
@@ -101,34 +83,6 @@ 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);
-}
-
 struct omap_hwmod *omap_uart_hwmod_lookup(int num)
 {
 	struct omap_hwmod *oh;
@@ -177,134 +131,8 @@ static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
 		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)
-{
-	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)
 {
@@ -326,14 +154,6 @@ static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
 	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;
-}
-
 int omap_uart_can_sleep(void)
 {
 	struct omap_uart_state *uart;
@@ -483,12 +303,22 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 	}
 }
 
-#else
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
+static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
 {
-	/* Needed to enable UART clocks when built without CONFIG_PM */
-	omap_uart_enable_clocks(uart);
+	struct omap_device *od = to_omap_device(pdev);
+
+	if (!od)
+		return;
+
+	if (enable)
+		omap_hwmod_enable_wakeup(od->hwmods[0]);
+	else
+		omap_hwmod_disable_wakeup(od->hwmods[0]);
 }
+
+#else
+static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
+{}
 #endif /* CONFIG_PM */
 
 static int __init omap_serial_early_init(void)
@@ -559,6 +389,8 @@ 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_enable_wakeup;
+	pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
 
 	/* Enable the MDR1 errata for OMAP3 */
 	if (cpu_is_omap34xx() && !cpu_is_ti816x())
@@ -582,12 +414,10 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_hwmod_idle(oh);
 
 	omap_device_enable(pdev);
-	omap_hwmod_enable_wakeup(oh);
 
 	console_unlock();
 
-	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) ||
-		(pdata->wk_en && pdata->wk_mask))
+	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
 		device_init_wakeup(&pdev->dev, true);
 
 	kfree(pdata);
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 74822b3..8ef81ce 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -62,6 +62,9 @@ struct omap_uart_port_info {
 	upf_t			flags;		/* UPF_* flags */
 
 	u32			errata;
+
+	void (*enable_wakeup)(struct platform_device *, bool);
+	u32 (*get_context_loss_count)(struct device *);
 };
 
 struct uart_omap_dma {
@@ -113,6 +116,8 @@ struct uart_omap_port {
 	unsigned char		msr_saved_flags;
 	char			name[20];
 	unsigned long		port_activity;
+	u32			context_loss_cnt;
+	u8			wakeups_enabled;
 };
 
 #endif /* __OMAP_SERIAL_H__ */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 9a0eac2..43c33da 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -37,11 +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>
 
+#define OMAP_UART_AUTOSUSPEND_DELAY -1
+
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
@@ -102,6 +105,8 @@ static void serial_omap_stop_rxdma(struct uart_omap_port *up)
 		omap_free_dma(up->uart_dma.rx_dma_channel);
 		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
 		up->uart_dma.rx_dma_used = false;
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 	}
 }
 
@@ -110,8 +115,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);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	up->ier |= UART_IER_MSI;
 	serial_out(up, UART_IER, up->ier);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_stop_tx(struct uart_port *port)
@@ -129,23 +137,32 @@ static void serial_omap_stop_tx(struct uart_port *port)
 		omap_stop_dma(up->uart_dma.tx_dma_channel);
 		omap_free_dma(up->uart_dma.tx_dma_channel);
 		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 	}
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	if (up->ier & UART_IER_THRI) {
 		up->ier &= ~UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
 	}
+
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
 static void serial_omap_stop_rx(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	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);
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
 static inline void receive_chars(struct uart_omap_port *up, int *status)
@@ -262,7 +279,10 @@ static void serial_omap_start_tx(struct uart_port *port)
 	int ret = 0;
 
 	if (!up->use_dma) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		serial_omap_enable_ier_thri(up);
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 		return;
 	}
 
@@ -272,6 +292,7 @@ static void serial_omap_start_tx(struct uart_port *port)
 	xmit = &up->port.state->xmit;
 
 	if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		ret = omap_request_dma(up->uart_dma.uart_dma_tx,
 				"UART Tx DMA",
 				(void *)uart_tx_dma_callback, up,
@@ -354,9 +375,13 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 	unsigned int iir, lsr;
 	unsigned long flags;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	iir = serial_in(up, UART_IIR);
-	if (iir & UART_IIR_NO_INT)
+	if (iir & UART_IIR_NO_INT) {
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 		return IRQ_NONE;
+	}
 
 	spin_lock_irqsave(&up->port.lock, flags);
 	lsr = serial_in(up, UART_LSR);
@@ -378,6 +403,9 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 		transmit_chars(up);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
+
 	up->port_activity = jiffies;
 	return IRQ_HANDLED;
 }
@@ -388,11 +416,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
 	unsigned long flags = 0;
 	unsigned int ret = 0;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	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);
-
+	pm_runtime_put(&up->pdev->dev);
 	return ret;
 }
 
@@ -402,7 +431,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)
 	unsigned char status;
 	unsigned int ret = 0;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	status = check_modem_status(up);
+	pm_runtime_put(&up->pdev->dev);
+
 	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);
 
 	if (status & UART_MSR_DCD)
@@ -433,9 +465,11 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	if (mctrl & TIOCM_LOOP)
 		mcr |= UART_MCR_LOOP;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	up->mcr = serial_in(up, UART_MCR);
 	up->mcr |= mcr;
 	serial_out(up, UART_MCR, up->mcr);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_break_ctl(struct uart_port *port, int break_state)
@@ -444,6 +478,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);
+	pm_runtime_get_sync(&up->pdev->dev);
 	spin_lock_irqsave(&up->port.lock, flags);
 	if (break_state == -1)
 		up->lcr |= UART_LCR_SBC;
@@ -451,6 +486,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);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static int serial_omap_startup(struct uart_port *port)
@@ -469,6 +505,7 @@ static int serial_omap_startup(struct uart_port *port)
 
 	dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id);
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	/*
 	 * Clear the FIFO buffers and disable them.
 	 * (they will be reenabled in set_termios())
@@ -524,6 +561,8 @@ 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);
 
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 	up->port_activity = jiffies;
 	return 0;
 }
@@ -534,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);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	/*
 	 * Disable interrupts from this port
 	 */
@@ -567,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;
 	}
+	pm_runtime_put(&up->pdev->dev);
 	free_irq(up->port.irq, up);
 }
 
@@ -682,6 +724,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.
 	 */
+	pm_runtime_get_sync(&up->pdev->dev);
 	spin_lock_irqsave(&up->port.lock, flags);
 
 	/*
@@ -814,6 +857,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);
+	pm_runtime_put(&up->pdev->dev);
 	dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
 }
 
@@ -825,6 +869,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);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	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);
@@ -834,6 +880,7 @@ 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);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_release_port(struct uart_port *port)
@@ -911,19 +958,26 @@ 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;
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	wait_for_xmitr(up);
 	serial_out(up, UART_TX, ch);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 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;
 
+	pm_runtime_get_sync(&up->pdev->dev);
+	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);
+	pm_runtime_put(&up->pdev->dev);
+	return status;
 }
 
 #endif /* CONFIG_CONSOLE_POLL */
@@ -951,6 +1005,8 @@ serial_omap_console_write(struct console *co, const char *s,
 	unsigned int ier;
 	int locked = 1;
 
+	pm_runtime_get_sync(&up->pdev->dev);
+
 	local_irq_save(flags);
 	if (up->port.sysrq)
 		locked = 0;
@@ -983,6 +1039,8 @@ serial_omap_console_write(struct console *co, const char *s,
 	if (up->msr_saved_flags)
 		check_modem_status(up);
 
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 	if (locked)
 		spin_unlock(&up->port.lock);
 	local_irq_restore(flags);
@@ -1065,19 +1123,18 @@ 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)
 		uart_suspend_port(&serial_omap_reg, &up->port);
 	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)
 		uart_resume_port(&serial_omap_reg, &up->port);
@@ -1140,6 +1197,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
 	int ret = 0;
 
 	if (up->uart_dma.rx_dma_channel == -1) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
 				"UART Rx DMA",
 				(void *)uart_rx_dma_callback, up,
@@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
+	if (device_may_wakeup(&pdev->dev)) {
+		pm_runtime_enable(&pdev->dev);
+		pm_runtime_get_sync(&pdev->dev);
+	}
+
 	ui[pdev->id] = up;
 	serial_omap_add_console_port(up);
 
@@ -1312,6 +1380,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 	if (ret != 0)
 		goto do_release_region;
 
+	pm_runtime_put(&pdev->dev);
 	platform_set_drvdata(pdev, up);
 	return 0;
 err:
@@ -1326,22 +1395,96 @@ static int serial_omap_remove(struct platform_device *dev)
 {
 	struct uart_omap_port *up = platform_get_drvdata(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);
 	}
+
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+static void serial_omap_restore_context(struct uart_omap_port *up)
+{
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+	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, UART_LCR_CONF_MODE_B); /* 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, UART_LCR_CONF_MODE_A);
+	serial_out(up, UART_MCR, up->mcr);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+	serial_out(up, UART_EFR, up->efr);
+	serial_out(up, UART_LCR, up->lcr);
+	/* UART 16x mode */
+	serial_out(up, UART_OMAP_MDR1, up->mdr1);
+}
+
+static int serial_omap_runtime_suspend(struct device *dev)
+{
+	struct uart_omap_port *up = dev_get_drvdata(dev);
+	struct omap_uart_port_info *pdata = dev->platform_data;
+
+	if (!up)
+		return -EINVAL;
+
+	if (!pdata->enable_wakeup || !pdata->get_context_loss_count)
+		return 0;
+
+	if (pdata->get_context_loss_count)
+		up->context_loss_cnt = pdata->get_context_loss_count(dev);
+
+	if (device_may_wakeup(dev)) {
+		if (!up->wakeups_enabled) {
+			pdata->enable_wakeup(up->pdev, true);
+			up->wakeups_enabled = true;
+		}
+	} else {
+		if (up->wakeups_enabled) {
+			pdata->enable_wakeup(up->pdev, false);
+			up->wakeups_enabled = false;
+		}
+	}
+
+	return 0;
+}
+
+static int serial_omap_runtime_resume(struct device *dev)
+{
+	struct uart_omap_port *up = dev_get_drvdata(dev);
+	struct omap_uart_port_info *pdata = dev->platform_data;
+
+	if (up) {
+		if (pdata->get_context_loss_count) {
+			u32 loss_cnt = pdata->get_context_loss_count(dev);
+
+			if (up->context_loss_cnt != loss_cnt)
+				serial_omap_restore_context(up);
+		}
+	}
+
 	return 0;
 }
 
+static const struct dev_pm_ops serial_omap_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
+	SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
+				serial_omap_runtime_resume, NULL)
+};
+
 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	= &serial_omap_dev_pm_ops,
 	},
 };
 
-- 
1.7.4.1

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

* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
                   ` (7 preceding siblings ...)
  2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
@ 2011-10-01 13:41 ` Rajendra Nayak
  2011-10-03 15:10   ` Vishwanath Sripathy
  2011-10-04 21:03   ` Kevin Hilman
  8 siblings, 2 replies; 41+ messages in thread
From: Rajendra Nayak @ 2011-10-01 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
> Add API to enable IO pad wakeup capability based on mux dynamic pad and
> wake_up enable flag available from hwmod_mux initialization.
>
> Use the wakeup_enable flag and enable wakeup capability
> for the given pads. Wakeup capability will be enabled/disabled
> during hwmod idle transition based on whether wakeup_flag is
> set or cleared.
>
> Call the omap_hwmod_set_ioring_wakeup from hwmod_wakeup_enable/disable.
>
> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
> ---
>   arch/arm/mach-omap2/omap_hwmod.c |   59 ++++++++++++++++++++++++++++++++++++++
>   1 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 84cc0bd..e751dd9 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2062,6 +2062,34 @@ static int __init omap_hwmod_setup_all(void)
>   core_initcall(omap_hwmod_setup_all);
>
>   /**
> + * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
> + * @oh: struct omap_hwmod *
> + * @set: bool value indicating to set or clear wakeup status.
> + *
> + * Set or Clear wakeup flag for the io_pad.
> + */
> +static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
> +{
> +	struct omap_device_pad *pad;
> +	int ret = -EINVAL, j;
> +
> +	if (oh->mux&&  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) {
> +				if (set_wake)
> +					pad->idle |= OMAP_WAKEUP_EN;
> +				else
> +					pad->idle&= ~OMAP_WAKEUP_EN;

I think apart from enabling/disabling the IO wakeup's at the pad
level, there is also a need to trigger the IO daisy chain control
(Wu clock) by programming the PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
bit and waiting on the PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN) bit,
which is done by the omap3_enable/disable_io_chain function.
This is still done in the cpuidle path, but it makes sense to
move that over here, since it should be done every time a pad
level wakeup is enabled or disabled.

See section 3.5.7.2.2 I/O Wake-Up Mechanism of 36xx TRM revA.

"The I/O wake-up scheme is enabled by triggering the I/O daisy chain 
control (Wu clock) by
programming a dedicated register (PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN) in 
the PRCM module.Software must wait for the I/O daisy chain to complete 
before it transitions the PER domain to a
nonfunctional state. This is done by polling a dedicated status bit in 
the PRCM module
(PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN). This status bit must be cleared by 
software when the bit is
read to 1."

> +				ret = 0;
> +			}
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +/**
>    * omap_hwmod_enable - enable an omap_hwmod
>    * @oh: struct omap_hwmod *
>    *
> @@ -2393,6 +2421,35 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
>   {
>   	return _del_initiator_dep(oh, init_oh);
>   }
> +/**
> + * omap_hwmod_enable_ioring_wakeup - Set wakeup flag for iopad.
> + * @oh: struct omap_hwmod *
> + *
> + * Traverse through dynamic pads, if pad is enabled then
> + * set wakeup enable bit flag for the mux pin. Wakeup pad bit
> + * will be set during hwmod idle transistion.
> + * Return error if pads are not enabled or not available.
> + */
> +int omap_hwmod_enable_ioring_wakeup(struct omap_hwmod *oh)
> +{
> +	/* Enable pad wake-up capability */
> +	return omap_hwmod_set_ioring_wakeup(oh, true);
> +}
> +
> +/**
> + * omap_hwmod_disable_ioring_wakeup - Clear wakeup flag for iopad.
> + * @oh: struct omap_hwmod *
> + *
> + * Traverse through dynamic pads, if pad is enabled then
> + * clear wakeup enable bit flag for the mux pin. Wakeup pad bit
> + * will be set during hwmod idle transistion.
> + * Return error if pads are not enabled or not available.
> + */
> +int omap_hwmod_disable_ioring_wakeup(struct omap_hwmod *oh)
> +{
> +	/* Disable pad wakeup capability */
> +	return omap_hwmod_set_ioring_wakeup(oh, false);
> +}
>
>   /**
>    * omap_hwmod_enable_wakeup - allow device to wake up the system
> @@ -2419,6 +2476,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
>   	v = oh->_sysc_cache;
>   	_enable_wakeup(oh,&v);
>   	_write_sysconfig(v, oh);
> +	omap_hwmod_enable_ioring_wakeup(oh);
>   	spin_unlock_irqrestore(&oh->_lock, flags);
>
>   	return 0;
> @@ -2449,6 +2507,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
>   	v = oh->_sysc_cache;
>   	_disable_wakeup(oh,&v);
>   	_write_sysconfig(v, oh);
> +	omap_hwmod_disable_ioring_wakeup(oh);
>   	spin_unlock_irqrestore(&oh->_lock, flags);
>
>   	return 0;

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-09-30 11:01 ` [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status Govindraj.R
@ 2011-10-01 14:33   ` Rajendra Nayak
  2011-10-03  5:00     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Rajendra Nayak @ 2011-10-01 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
> Add API to determine IO-PAD wakeup event status for a given
> hwmod dynamic_mux pad.
>
> Wake up event set will be cleared on pad mux_read.

Are these api's even getting used in this series?

>
> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
> ---
>   arch/arm/mach-omap2/mux.c                    |   30 ++++++++++++++++++++++++++
>   arch/arm/mach-omap2/mux.h                    |   13 +++++++++++
>   arch/arm/mach-omap2/omap_hwmod.c             |    7 ++++++
>   arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
>   4 files changed, 51 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
> index 655e948..fb75aae 100644
> --- a/arch/arm/mach-omap2/mux.c
> +++ b/arch/arm/mach-omap2/mux.c
> @@ -351,6 +351,36 @@ err1:
>   	return NULL;
>   }
>
> +/**
> + * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
> + * @hmux:		Pads for a hwmod
> + *
> + * Gets the wakeup status of given pad from omap-hwmod.
> + * Returns true if wakeup capability is set and wakeup event occurred.
> + * Returns false if wakeup event has not occurred or pads are not available.
> + */
> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
> +{
> +	int i;
> +	unsigned int val;
> +	u8 ret = false;
> +
> +	for (i = 0; i<  hmux->nr_pads; i++) {
> +		struct omap_device_pad *pad =&hmux->pads[i];
> +
> +		if (pad->flags&  OMAP_DEVICE_PAD_WAKEUP) {
> +			val = omap_mux_read(pad->partition,
> +					pad->mux->reg_offset);
> +			if (val&  OMAP_WAKEUP_EVENT) {
> +				ret = true;
> +				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 2132308..8b2150a 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_get_wake_status - omap hwmod check pad wakeup
> + * @hmux:		Pads for a hwmod
> + *
> + * Called only from omap_hwmod.c, do not use.
> + */
> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
>   #else
>
> +static inline bool
> +omap_hwmod_mux_get_wake_status(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 e751dd9..a8b24d7 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2724,3 +2724,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
>
>   	return 0;
>   }
> +
> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
> +{
> +	if (oh&&  oh->mux)
> +		return omap_hwmod_mux_get_wake_status(oh->mux);
> +	return -EINVAL;
> +}
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index 0e329ca..9a6195c 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -607,6 +607,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_pad_get_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

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-10-01 14:33   ` Rajendra Nayak
@ 2011-10-03  5:00     ` Govindraj
  2011-10-03  5:23       ` Rajendra Nayak
  0 siblings, 1 reply; 41+ messages in thread
From: Govindraj @ 2011-10-03  5:00 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the review,


On Sat, Oct 1, 2011 at 8:03 PM, Rajendra Nayak <rnayak@ti.com> wrote:
> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>
>> Add API to determine IO-PAD wakeup event status for a given
>> hwmod dynamic_mux pad.
>>
>> Wake up event set will be cleared on pad mux_read.
>
> Are these api's even getting used in this series?

Used in Tero's irq_chaining patches.

http://lkml.org/lkml/2011/9/23/121

--
Thanks,
Govindraj.R


>
>>
>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>> ---
>> ?arch/arm/mach-omap2/mux.c ? ? ? ? ? ? ? ? ? ?| ? 30
>> ++++++++++++++++++++++++++
>> ?arch/arm/mach-omap2/mux.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++
>> ?arch/arm/mach-omap2/omap_hwmod.c ? ? ? ? ? ? | ? ?7 ++++++
>> ?arch/arm/plat-omap/include/plat/omap_hwmod.h | ? ?1 +
>> ?4 files changed, 51 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
>> index 655e948..fb75aae 100644
>> --- a/arch/arm/mach-omap2/mux.c
>> +++ b/arch/arm/mach-omap2/mux.c
>> @@ -351,6 +351,36 @@ err1:
>> ? ? ? ?return NULL;
>> ?}
>>
>> +/**
>> + * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
>> + * @hmux: ? ? ? ? ? ? ?Pads for a hwmod
>> + *
>> + * Gets the wakeup status of given pad from omap-hwmod.
>> + * Returns true if wakeup capability is set and wakeup event occurred.
>> + * Returns false if wakeup event has not occurred or pads are not
>> available.
>> + */
>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
>> +{
>> + ? ? ? int i;
>> + ? ? ? unsigned int val;
>> + ? ? ? u8 ret = false;
>> +
>> + ? ? ? for (i = 0; i< ?hmux->nr_pads; i++) {
>> + ? ? ? ? ? ? ? struct omap_device_pad *pad =&hmux->pads[i];
>> +
>> + ? ? ? ? ? ? ? if (pad->flags& ?OMAP_DEVICE_PAD_WAKEUP) {
>> + ? ? ? ? ? ? ? ? ? ? ? val = omap_mux_read(pad->partition,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pad->mux->reg_offset);
>> + ? ? ? ? ? ? ? ? ? ? ? if (val& ?OMAP_WAKEUP_EVENT) {
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret = true;
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 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 2132308..8b2150a 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_get_wake_status - omap hwmod check pad wakeup
>> + * @hmux: ? ? ? ? ? ? ?Pads for a hwmod
>> + *
>> + * Called only from omap_hwmod.c, do not use.
>> + */
>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
>> ?#else
>>
>> +static inline bool
>> +omap_hwmod_mux_get_wake_status(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 e751dd9..a8b24d7 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>> @@ -2724,3 +2724,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod
>> *oh)
>>
>> ? ? ? ?return 0;
>> ?}
>> +
>> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
>> +{
>> + ? ? ? if (oh&& ?oh->mux)
>> + ? ? ? ? ? ? ? return omap_hwmod_mux_get_wake_status(oh->mux);
>> + ? ? ? return -EINVAL;
>> +}
>> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>> b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>> index 0e329ca..9a6195c 100644
>> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>> @@ -607,6 +607,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_pad_get_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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-10-03  5:00     ` Govindraj
@ 2011-10-03  5:23       ` Rajendra Nayak
  2011-10-03  5:56         ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Rajendra Nayak @ 2011-10-03  5:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 03 October 2011 10:30 AM, Govindraj wrote:
> Thanks for the review,
>
>
> On Sat, Oct 1, 2011 at 8:03 PM, Rajendra Nayak<rnayak@ti.com>  wrote:
>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>>
>>> Add API to determine IO-PAD wakeup event status for a given
>>> hwmod dynamic_mux pad.
>>>
>>> Wake up event set will be cleared on pad mux_read.
>>
>> Are these api's even getting used in this series?
>
> Used in Tero's irq_chaining patches.

So shouldn't this patch be part of his series instead?

>
> http://lkml.org/lkml/2011/9/23/121
>
> --
> Thanks,
> Govindraj.R
>
>
>>
>>>
>>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>>> ---
>>>   arch/arm/mach-omap2/mux.c                    |   30
>>> ++++++++++++++++++++++++++
>>>   arch/arm/mach-omap2/mux.h                    |   13 +++++++++++
>>>   arch/arm/mach-omap2/omap_hwmod.c             |    7 ++++++
>>>   arch/arm/plat-omap/include/plat/omap_hwmod.h |    1 +
>>>   4 files changed, 51 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
>>> index 655e948..fb75aae 100644
>>> --- a/arch/arm/mach-omap2/mux.c
>>> +++ b/arch/arm/mach-omap2/mux.c
>>> @@ -351,6 +351,36 @@ err1:
>>>         return NULL;
>>>   }
>>>
>>> +/**
>>> + * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
>>> + * @hmux:              Pads for a hwmod
>>> + *
>>> + * Gets the wakeup status of given pad from omap-hwmod.
>>> + * Returns true if wakeup capability is set and wakeup event occurred.
>>> + * Returns false if wakeup event has not occurred or pads are not
>>> available.
>>> + */
>>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
>>> +{
>>> +       int i;
>>> +       unsigned int val;
>>> +       u8 ret = false;
>>> +
>>> +       for (i = 0; i<    hmux->nr_pads; i++) {
>>> +               struct omap_device_pad *pad =&hmux->pads[i];
>>> +
>>> +               if (pad->flags&    OMAP_DEVICE_PAD_WAKEUP) {
>>> +                       val = omap_mux_read(pad->partition,
>>> +                                       pad->mux->reg_offset);
>>> +                       if (val&    OMAP_WAKEUP_EVENT) {
>>> +                               ret = true;
>>> +                               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 2132308..8b2150a 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_get_wake_status - omap hwmod check pad wakeup
>>> + * @hmux:              Pads for a hwmod
>>> + *
>>> + * Called only from omap_hwmod.c, do not use.
>>> + */
>>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
>>>   #else
>>>
>>> +static inline bool
>>> +omap_hwmod_mux_get_wake_status(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 e751dd9..a8b24d7 100644
>>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>>> @@ -2724,3 +2724,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod
>>> *oh)
>>>
>>>         return 0;
>>>   }
>>> +
>>> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
>>> +{
>>> +       if (oh&&    oh->mux)
>>> +               return omap_hwmod_mux_get_wake_status(oh->mux);
>>> +       return -EINVAL;
>>> +}
>>> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>> b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>> index 0e329ca..9a6195c 100644
>>> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>> @@ -607,6 +607,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_pad_get_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
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-10-03  5:23       ` Rajendra Nayak
@ 2011-10-03  5:56         ` Govindraj
  2011-10-10 22:24           ` Kevin Hilman
  0 siblings, 1 reply; 41+ messages in thread
From: Govindraj @ 2011-10-03  5:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 3, 2011 at 10:53 AM, Rajendra Nayak <rnayak@ti.com> wrote:
> On Monday 03 October 2011 10:30 AM, Govindraj wrote:
>>
>> Thanks for the review,
>>
>>
>> On Sat, Oct 1, 2011 at 8:03 PM, Rajendra Nayak<rnayak@ti.com> ?wrote:
>>>
>>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>>>
>>>> Add API to determine IO-PAD wakeup event status for a given
>>>> hwmod dynamic_mux pad.
>>>>
>>>> Wake up event set will be cleared on pad mux_read.
>>>
>>> Are these api's even getting used in this series?
>>
>> Used in Tero's irq_chaining patches.
>
> So shouldn't this patch be part of his series instead?

Yes it is. Part of his v9-series.

--
Thanks,
Govindraj.R


>
>>
>> http://lkml.org/lkml/2011/9/23/121
>>
>> --
>> Thanks,
>> Govindraj.R
>>
>>
>>>
>>>>
>>>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>>>> ---
>>>> ?arch/arm/mach-omap2/mux.c ? ? ? ? ? ? ? ? ? ?| ? 30
>>>> ++++++++++++++++++++++++++
>>>> ?arch/arm/mach-omap2/mux.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++
>>>> ?arch/arm/mach-omap2/omap_hwmod.c ? ? ? ? ? ? | ? ?7 ++++++
>>>> ?arch/arm/plat-omap/include/plat/omap_hwmod.h | ? ?1 +
>>>> ?4 files changed, 51 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
>>>> index 655e948..fb75aae 100644
>>>> --- a/arch/arm/mach-omap2/mux.c
>>>> +++ b/arch/arm/mach-omap2/mux.c
>>>> @@ -351,6 +351,36 @@ err1:
>>>> ? ? ? ?return NULL;
>>>> ?}
>>>>
>>>> +/**
>>>> + * omap_hwmod_mux_get_wake_status - omap hwmod check pad wakeup
>>>> + * @hmux: ? ? ? ? ? ? ?Pads for a hwmod
>>>> + *
>>>> + * Gets the wakeup status of given pad from omap-hwmod.
>>>> + * Returns true if wakeup capability is set and wakeup event occurred.
>>>> + * Returns false if wakeup event has not occurred or pads are not
>>>> available.
>>>> + */
>>>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux)
>>>> +{
>>>> + ? ? ? int i;
>>>> + ? ? ? unsigned int val;
>>>> + ? ? ? u8 ret = false;
>>>> +
>>>> + ? ? ? for (i = 0; i< ? ?hmux->nr_pads; i++) {
>>>> + ? ? ? ? ? ? ? struct omap_device_pad *pad =&hmux->pads[i];
>>>> +
>>>> + ? ? ? ? ? ? ? if (pad->flags& ? ?OMAP_DEVICE_PAD_WAKEUP) {
>>>> + ? ? ? ? ? ? ? ? ? ? ? val = omap_mux_read(pad->partition,
>>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pad->mux->reg_offset);
>>>> + ? ? ? ? ? ? ? ? ? ? ? if (val& ? ?OMAP_WAKEUP_EVENT) {
>>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret = true;
>>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 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 2132308..8b2150a 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_get_wake_status - omap hwmod check pad wakeup
>>>> + * @hmux: ? ? ? ? ? ? ?Pads for a hwmod
>>>> + *
>>>> + * Called only from omap_hwmod.c, do not use.
>>>> + */
>>>> +bool omap_hwmod_mux_get_wake_status(struct omap_hwmod_mux_info *hmux);
>>>> ?#else
>>>>
>>>> +static inline bool
>>>> +omap_hwmod_mux_get_wake_status(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 e751dd9..a8b24d7 100644
>>>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>>>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>>>> @@ -2724,3 +2724,10 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod
>>>> *oh)
>>>>
>>>> ? ? ? ?return 0;
>>>> ?}
>>>> +
>>>> +int omap_hwmod_pad_get_wakeup_status(struct omap_hwmod *oh)
>>>> +{
>>>> + ? ? ? if (oh&& ? ?oh->mux)
>>>> + ? ? ? ? ? ? ? return omap_hwmod_mux_get_wake_status(oh->mux);
>>>> + ? ? ? return -EINVAL;
>>>> +}
>>>> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>>> b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>>> index 0e329ca..9a6195c 100644
>>>> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>>> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
>>>> @@ -607,6 +607,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_pad_get_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
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-serial"
>>> in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>>>
>
>

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

* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-10-01 13:41 ` [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Rajendra Nayak
@ 2011-10-03 15:10   ` Vishwanath Sripathy
  2011-10-04 21:03   ` Kevin Hilman
  1 sibling, 0 replies; 41+ messages in thread
From: Vishwanath Sripathy @ 2011-10-03 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

---snip--
> > +{
> > +	struct omap_device_pad *pad;
> > +	int ret = -EINVAL, j;
> > +
> > +	if (oh->mux&&  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) {
> > +				if (set_wake)
> > +					pad->idle |= OMAP_WAKEUP_EN;
> > +				else
> > +					pad->idle&= ~OMAP_WAKEUP_EN;
>
> I think apart from enabling/disabling the IO wakeup's at the pad
> level, there is also a need to trigger the IO daisy chain control
> (Wu clock) by programming the PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
> bit and waiting on the PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN) bit,
> which is done by the omap3_enable/disable_io_chain function.
> This is still done in the cpuidle path, but it makes sense to
> move that over here, since it should be done every time a pad
> level wakeup is enabled or disabled.
>
> See section 3.5.7.2.2 I/O Wake-Up Mechanism of 36xx TRM revA.
>
> "The I/O wake-up scheme is enabled by triggering the I/O daisy chain
> control (Wu clock) by
> programming a dedicated register (PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN)
> in
> the PRCM module.Software must wait for the I/O daisy chain to
> complete
> before it transitions the PER domain to a
> nonfunctional state. This is done by polling a dedicated status bit
> in
> the PRCM module
> (PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN). This status bit must be cleared
> by
> software when the bit is
> read to 1."
I am working on adding Daisy chain support via hwmod mux framework.
I will post the patches soon.

Regards
Vishwa

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

* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-10-01 13:41 ` [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Rajendra Nayak
  2011-10-03 15:10   ` Vishwanath Sripathy
@ 2011-10-04 21:03   ` Kevin Hilman
  2011-10-05 11:57     ` Rajendra Nayak
  1 sibling, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-04 21:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rajendra,

Rajendra Nayak <rnayak@ti.com> writes:

> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>> Add API to enable IO pad wakeup capability based on mux dynamic pad and
>> wake_up enable flag available from hwmod_mux initialization.
>>
>> Use the wakeup_enable flag and enable wakeup capability
>> for the given pads. Wakeup capability will be enabled/disabled
>> during hwmod idle transition based on whether wakeup_flag is
>> set or cleared.
>>
>> Call the omap_hwmod_set_ioring_wakeup from hwmod_wakeup_enable/disable.
>>
>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>> ---
>>   arch/arm/mach-omap2/omap_hwmod.c |   59 ++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 59 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
>> index 84cc0bd..e751dd9 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>> @@ -2062,6 +2062,34 @@ static int __init omap_hwmod_setup_all(void)
>>   core_initcall(omap_hwmod_setup_all);
>>
>>   /**
>> + * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
>> + * @oh: struct omap_hwmod *
>> + * @set: bool value indicating to set or clear wakeup status.
>> + *
>> + * Set or Clear wakeup flag for the io_pad.
>> + */
>> +static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
>> +{
>> +	struct omap_device_pad *pad;
>> +	int ret = -EINVAL, j;
>> +
>> +	if (oh->mux&&  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) {
>> +				if (set_wake)
>> +					pad->idle |= OMAP_WAKEUP_EN;
>> +				else
>> +					pad->idle&= ~OMAP_WAKEUP_EN;
>
> I think apart from enabling/disabling the IO wakeup's at the pad
> level, there is also a need to trigger the IO daisy chain control
> (Wu clock) by programming the PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
> bit and waiting on the PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN) bit,
> which is done by the omap3_enable/disable_io_chain function.
> This is still done in the cpuidle path, but it makes sense to
> move that over here, since it should be done every time a pad
> level wakeup is enabled or disabled.

So should it be done just here or also in the idle path?  In general,
I'm certainly for moving things out of the idle path into the places
where they belong.

However, I don't get from the TRM description below that it should be
done every time a pad-level wake is enabled or disabled.  Can you
clarify what part of the TRM description you mean?

All I understand is that it has to be done before PER domain
transisions.

Also, if this were to happen, are there side-effects of having the IO
daisy chain armed outside the idle path?

Kevin

> See section 3.5.7.2.2 I/O Wake-Up Mechanism of 36xx TRM revA.
>
> "The I/O wake-up scheme is enabled by triggering the I/O daisy chain
> control (Wu clock) by
> programming a dedicated register (PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN)
> in the PRCM module.Software must wait for the I/O daisy chain to
> complete before it transitions the PER domain to a
> nonfunctional state. This is done by polling a dedicated status bit in
> the PRCM module
> (PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN). This status bit must be cleared
> by software when the bit is
> read to 1."

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

* [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support
  2011-09-30 11:01 ` [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support Govindraj.R
@ 2011-10-04 21:42   ` Kevin Hilman
  2011-10-05  6:54     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-04 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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

> We had been using traditional 8250 driver as uart console driver
> prior to omap-serial driver. Since we have omap-serial driver
> in mainline kernel for some time now it has been used as default
> uart console driver on omap2+ platforms. Remove 8250 support for
> omap-uarts.

Nice to see the this disappearing.

> Serial_in and serial_out override for 8250 serial driver is also
> removed. Empty fifo read fix is already taken care with omap-serial
> driver with data ready bit check from LSR reg before reading RX fifo.

As stated in the previous review.  Patches that move code/features
should have the removal and the add-back in the same patch.  Doing so
makes it easy for reviewers to see whether it was simply moved, or if it
was modified when it was moved, etc.

> Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr
> in omap-serial driver.

Again, remove it here in the patch that adds that support (the errata
patch I guess.)

> Remove headers that were necessary to support 8250 support
> and remove all config bindings done to keep 8250 backward compatibility
> while adding omap-serial driver. Remove omap_uart_reset needed for
> 8250 autoconf.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

So basically, this patch should only remove the legacy 8250 support (as
the subject says) and everything else should be done in the other
relevant patches.

Kevin

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

* [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support
  2011-10-04 21:42   ` Kevin Hilman
@ 2011-10-05  6:54     ` Govindraj
  2011-10-05 18:42       ` Kevin Hilman
  0 siblings, 1 reply; 41+ messages in thread
From: Govindraj @ 2011-10-05  6:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kevin,

Thanks for the review,


On Wed, Oct 5, 2011 at 3:12 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> We had been using traditional 8250 driver as uart console driver
>> prior to omap-serial driver. Since we have omap-serial driver
>> in mainline kernel for some time now it has been used as default
>> uart console driver on omap2+ platforms. Remove 8250 support for
>> omap-uarts.
>
> Nice to see the this disappearing.
>
>> Serial_in and serial_out override for 8250 serial driver is also
>> removed.

>> Empty fifo read fix is already taken care with omap-serial
>> driver with data ready bit check from LSR reg before reading RX fifo.
>
> As stated in the previous review. ?Patches that move code/features
> should have the removal and the add-back in the same patch. ?Doing so
> makes it easy for reviewers to see whether it was simply moved, or if it
> was modified when it was moved, etc.
>

Empty fifo read is already taken care in omap-serial.c and is part of
mainline code.
Nothing to add to omap-serial.c

>> Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr
>> in omap-serial driver.
>
> Again, remove it here in the patch that adds that support (the errata
> patch I guess.)
>

The errata patch ( [PATCH v6 11/16] ) moves only mdr_errata and force_idle
from serial.c to omap-serial.c.

Already handled stuffs and things that already exists with omap-serial.c
are removed here.

>> Remove headers that were necessary to support 8250 support
>> and remove all config bindings done to keep 8250 backward compatibility
>> while adding omap-serial driver. Remove omap_uart_reset needed for
>> 8250 autoconf.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> So basically, this patch should only remove the legacy 8250 support (as
> the subject says) and everything else should be done in the other
> relevant patches.
>

Yes removes only the 8250 code. serial_in/serial_out were read/write overrides
part of 8250 code.

serial_in/serial_out had these checks for empty fifo read and wait for tx
which is already handled with omap-serial.c.

--
Thanks,
Govindraj.R


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

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

* [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup.
  2011-10-04 21:03   ` Kevin Hilman
@ 2011-10-05 11:57     ` Rajendra Nayak
  0 siblings, 0 replies; 41+ messages in thread
From: Rajendra Nayak @ 2011-10-05 11:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kevin,

On Wednesday 05 October 2011 02:33 AM, Kevin Hilman wrote:
> Hi Rajendra,
>
> Rajendra Nayak<rnayak@ti.com>  writes:
>
>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>> Add API to enable IO pad wakeup capability based on mux dynamic pad and
>>> wake_up enable flag available from hwmod_mux initialization.
>>>
>>> Use the wakeup_enable flag and enable wakeup capability
>>> for the given pads. Wakeup capability will be enabled/disabled
>>> during hwmod idle transition based on whether wakeup_flag is
>>> set or cleared.
>>>
>>> Call the omap_hwmod_set_ioring_wakeup from hwmod_wakeup_enable/disable.
>>>
>>> Signed-off-by: Govindraj.R<govindraj.raja@ti.com>
>>> ---
>>>    arch/arm/mach-omap2/omap_hwmod.c |   59 ++++++++++++++++++++++++++++++++++++++
>>>    1 files changed, 59 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
>>> index 84cc0bd..e751dd9 100644
>>> --- a/arch/arm/mach-omap2/omap_hwmod.c
>>> +++ b/arch/arm/mach-omap2/omap_hwmod.c
>>> @@ -2062,6 +2062,34 @@ static int __init omap_hwmod_setup_all(void)
>>>    core_initcall(omap_hwmod_setup_all);
>>>
>>>    /**
>>> + * omap_hwmod_set_ioring_wakeup - enable io pad wakeup flag.
>>> + * @oh: struct omap_hwmod *
>>> + * @set: bool value indicating to set or clear wakeup status.
>>> + *
>>> + * Set or Clear wakeup flag for the io_pad.
>>> + */
>>> +static int omap_hwmod_set_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
>>> +{
>>> +	struct omap_device_pad *pad;
>>> +	int ret = -EINVAL, j;
>>> +
>>> +	if (oh->mux&&   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) {
>>> +				if (set_wake)
>>> +					pad->idle |= OMAP_WAKEUP_EN;
>>> +				else
>>> +					pad->idle&= ~OMAP_WAKEUP_EN;
>>
>> I think apart from enabling/disabling the IO wakeup's at the pad
>> level, there is also a need to trigger the IO daisy chain control
>> (Wu clock) by programming the PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
>> bit and waiting on the PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN) bit,
>> which is done by the omap3_enable/disable_io_chain function.
>> This is still done in the cpuidle path, but it makes sense to
>> move that over here, since it should be done every time a pad
>> level wakeup is enabled or disabled.
>
> So should it be done just here or also in the idle path?  In general,
> I'm certainly for moving things out of the idle path into the places
> where they belong.
>
> However, I don't get from the TRM description below that it should be
> done every time a pad-level wake is enabled or disabled.  Can you
> clarify what part of the TRM description you mean?

+ Nilesh from the PRCM design team, I and Vishwa had a short meeting
with Nilesh just to double confirm our understanding on how IO daisy
should be implemented.

I agree the OMAP3 TRM isn't very clear in mentioning this and overall
there is very limited documentation on this.

The OMAP4 TRM however is a little better and there isn't any difference
in the way IO Daisy is implemented in OMAP3 and OMAP4.

So, I'll try and explain what I meant based on whats in the OMAP4 TRM :)

I am referring to OMAP4430_ES2.x Public TRM vO.

refer to Figure 3-74. I/O Pads Daisy-Chain Configuration,
The WUEN signal to each pad (which can be used to enable IO-daisy
for the given pad) is a AND of a signal from PRCM and
one from SCM.
The signal from PRCM can be enabled by writing into
PRM_IO_PMCTRL[16] GLOBAL_WUEN bit (which in our case we keep
enabled always, done early at boot).
The signal from SCM can be enabled by writing to the individual
pad registers in SCM
CONTROL.CONTROL_PADCONF_<IOpad>[14] WAKEUPENABLE0
CONTROL.CONTROL_PADCONF_<IOpad>[30] WAKEUPENABLE1.
This is done by hwmod every time the module is enabled/idled.

This is what is mentioned in the TRM here
"The I/O pad wake-up scheme must be enabled (WUEN signal) globally by 
setting the
PRM_IO_PMCTRL[16] GLOBAL_WUEN bit and by also setting I/O pad wake-up 
enabled/disabled
individually (WUEN signal) by writing to the following bit fields in the 
control module:
? CONTROL.CONTROL_PADCONF_<IOpad>[14] WAKEUPENABLE0
? CONTROL.CONTROL_PADCONF_<IOpad>[30] WAKEUPENABLE1"

And then the TRM mentions this about the need to trigger WUCLKIN
for every pad enable/disable.
This is needed to reset any spurious wakeups events.

"Once configured, the wake-up scheme within each I/O pad is enabled and 
disabled by triggering a control
(WUCLKIN signal) of the I/O daisy chain. This is done thanks to a 
dedicated PRCM module register bit
PRM_IO_PMCTRL[8] WUCLK_CTRL. The software must enable the I/O wakeup 
prior entering a
low-power mode and disable it following a wake-up event.
Writing the PRM_IO_PMCTRL[8] WUCLK_CTRL bit to 1 asserts signal WUCLKIN 
high to reset spurious
wake-up event and to latch the current pad input value. PRCM module 
register PRM_IO_PMCTRL[9]
WUCLK_STATUS logs the signal WUCLKOUT of the last pad of the I/O ring. 
Once this status is set to 1,
the software may clear the PRM_IO_PMCTRL[8] WUCLK_CTRL bit to 
effectively enable or disable the
wake-up feature within each pad."

The controls are exactly the same in case of OMAP3.
There is a global control at PRCM level (PRCM.PM_WKEN_WKUP[8] EN_IO)
and at pad level in SCM.

To assert the WUCLKIN, there is PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN
and to log the signal WUCLKOUT of the last pad there is
PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN.

Its just that the registers in OMAP3 are named weirdly, the digram isn't
any clear and the explanation in the TRM does not help much,
causing confusion.

 > All I understand is that it has to be done before PER domain
 > transisions.

This is mostly coming from pre 3430 es3 days when there was no
control for a WUCLKIN trigger in software. The hardware did this
based on per/core entering sleep states.

With 3430es3.1 and the subsequent 3630/4430/4460 silicons, the software
can decide when to enable/trigger iodaisy and it should ideally be done
before the powerdomain corresponding to the given module transitions to
RET or OFF. Until then the modules async wakeup is expected to generate
a wakeup.

 > Also, if this were to happen, are there side-effects of having the IO
 > daisy chain armed outside the idle path?

IO daisy is actually designed so that it can be armed outside of idle,
by providing software control to generate the WUCLKIN pulse.

So as long as a module is clocked, it can generate interrupts, once
its clocks are cut, it can generate an async wakeup, and once the
powerdomain belonging to the module transitions to RET or OFF, it should
be programmed to generate IO wakeup, independent of system idle state.

regards,
Rajendra

>
>
>
> Kevin
>
>> See section 3.5.7.2.2 I/O Wake-Up Mechanism of 36xx TRM revA.
>>
>> "The I/O wake-up scheme is enabled by triggering the I/O daisy chain
>> control (Wu clock) by
>> programming a dedicated register (PRCM.PM_WKEN_WKUP[16] EN_IO_CHAIN)
>> in the PRCM module.Software must wait for the I/O daisy chain to
>> complete before it transitions the PER domain to a
>> nonfunctional state. This is done by polling a dedicated status bit in
>> the PRCM module
>> (PRCM.PM_WKST_WKUP[16] ST_IO_CHAIN). This status bit must be cleared
>> by software when the bit is
>> read to 1."

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

* [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support
  2011-10-05  6:54     ` Govindraj
@ 2011-10-05 18:42       ` Kevin Hilman
  2011-10-06  8:16         ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-05 18:42 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Hi Kevin,
>
> Thanks for the review,
>
>
> On Wed, Oct 5, 2011 at 3:12 AM, Kevin Hilman <khilman@ti.com> wrote:
>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>
>>> We had been using traditional 8250 driver as uart console driver
>>> prior to omap-serial driver. Since we have omap-serial driver
>>> in mainline kernel for some time now it has been used as default
>>> uart console driver on omap2+ platforms. Remove 8250 support for
>>> omap-uarts.
>>
>> Nice to see the this disappearing.
>>
>>> Serial_in and serial_out override for 8250 serial driver is also
>>> removed.
>
>>> Empty fifo read fix is already taken care with omap-serial
>>> driver with data ready bit check from LSR reg before reading RX fifo.
>>
>> As stated in the previous review. ?Patches that move code/features
>> should have the removal and the add-back in the same patch. ?Doing so
>> makes it easy for reviewers to see whether it was simply moved, or if it
>> was modified when it was moved, etc.
>>
>
> Empty fifo read is already taken care in omap-serial.c and is part of
> mainline code.  Nothing to add to omap-serial.c

OK, good.  I guess I missed the 'already' part in your changelog.

>>> Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr
>>> in omap-serial driver.
>>
>> Again, remove it here in the patch that adds that support (the errata
>> patch I guess.)
>>
>
> The errata patch ( [PATCH v6 11/16] ) moves only mdr_errata and force_idle
> from serial.c to omap-serial.c.
>
> Already handled stuffs and things that already exists with omap-serial.c
> are removed here.

OK.

>>> Remove headers that were necessary to support 8250 support
>>> and remove all config bindings done to keep 8250 backward compatibility
>>> while adding omap-serial driver. Remove omap_uart_reset needed for
>>> 8250 autoconf.
>>>
>>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>>
>> So basically, this patch should only remove the legacy 8250 support (as
>> the subject says) and everything else should be done in the other
>> relevant patches.
>>
>
> Yes removes only the 8250 code. serial_in/serial_out were read/write overrides
> part of 8250 code.
>
> serial_in/serial_out had these checks for empty fifo read and wait for tx
> which is already handled with omap-serial.c.

OK, thanks for the clarification.  

The changelog could've been a bit more specific for readers not
intimately familiar with the driver.

Kevin

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

* [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts.
  2011-09-30 11:01 ` [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts Govindraj.R
@ 2011-10-05 19:04   ` Kevin Hilman
  2011-10-06  8:21     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-05 19:04 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Prior to this change rx-pad wakeup was done by writing to rx-pad offset value
> populated in serial.c idle_init. Now with mux framework support we can use
> mux_utilities along with hmwod framework to handle io-pad configuration and
> enable rx-pad wake-up mechanism.

This patch (along with a few others) have compile errors when CONFIG_PM
is not set.

Kevin

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

* [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support
  2011-10-05 18:42       ` Kevin Hilman
@ 2011-10-06  8:16         ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-06  8:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 6, 2011 at 12:12 AM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
>> Hi Kevin,
>>
>> Thanks for the review,
>>
>>
>> On Wed, Oct 5, 2011 at 3:12 AM, Kevin Hilman <khilman@ti.com> wrote:
>>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>>
>>>> We had been using traditional 8250 driver as uart console driver
>>>> prior to omap-serial driver. Since we have omap-serial driver
>>>> in mainline kernel for some time now it has been used as default
>>>> uart console driver on omap2+ platforms. Remove 8250 support for
>>>> omap-uarts.
>>>
>>> Nice to see the this disappearing.
>>>
>>>> Serial_in and serial_out override for 8250 serial driver is also
>>>> removed.
>>
>>>> Empty fifo read fix is already taken care with omap-serial
>>>> driver with data ready bit check from LSR reg before reading RX fifo.
>>>
>>> As stated in the previous review. ?Patches that move code/features
>>> should have the removal and the add-back in the same patch. ?Doing so
>>> makes it easy for reviewers to see whether it was simply moved, or if it
>>> was modified when it was moved, etc.
>>>
>>
>> Empty fifo read is already taken care in omap-serial.c and is part of
>> mainline code. ?Nothing to add to omap-serial.c
>
> OK, good. ?I guess I missed the 'already' part in your changelog.
>
>>>> Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr
>>>> in omap-serial driver.
>>>
>>> Again, remove it here in the patch that adds that support (the errata
>>> patch I guess.)
>>>
>>
>> The errata patch ( [PATCH v6 11/16] ) moves only mdr_errata and force_idle
>> from serial.c to omap-serial.c.
>>
>> Already handled stuffs and things that already exists with omap-serial.c
>> are removed here.
>
> OK.
>
>>>> Remove headers that were necessary to support 8250 support
>>>> and remove all config bindings done to keep 8250 backward compatibility
>>>> while adding omap-serial driver. Remove omap_uart_reset needed for
>>>> 8250 autoconf.
>>>>
>>>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>>>
>>> So basically, this patch should only remove the legacy 8250 support (as
>>> the subject says) and everything else should be done in the other
>>> relevant patches.
>>>
>>
>> Yes removes only the 8250 code. serial_in/serial_out were read/write overrides
>> part of 8250 code.
>>
>> serial_in/serial_out had these checks for empty fifo read and wait for tx
>> which is already handled with omap-serial.c.
>
> OK, thanks for the clarification.
>
> The changelog could've been a bit more specific for readers not
> intimately familiar with the driver.
>

Okay fine, I will re-visit this.

--
Thanks,
Govindraj.R

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

* [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts.
  2011-10-05 19:04   ` Kevin Hilman
@ 2011-10-06  8:21     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-06  8:21 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the review.

On Thu, Oct 6, 2011 at 12:34 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Prior to this change rx-pad wakeup was done by writing to rx-pad offset value
>> populated in serial.c idle_init. Now with mux framework support we can use
>> mux_utilities along with hmwod framework to handle io-pad configuration and
>> enable rx-pad wake-up mechanism.
>
> This patch (along with a few others) have compile errors when CONFIG_PM
> is not set.
>

Will check and fix this.

Please let me know on further comments on the series.

Will re-post fixing the same.

--
Thanks,
Govindraj.R


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

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-10-03  5:56         ` Govindraj
@ 2011-10-10 22:24           ` Kevin Hilman
  2011-10-11  6:17             ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

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

> On Mon, Oct 3, 2011 at 10:53 AM, Rajendra Nayak <rnayak@ti.com> wrote:
>> On Monday 03 October 2011 10:30 AM, Govindraj wrote:
>>
>>> On Sat, Oct 1, 2011 at 8:03 PM, Rajendra Nayak<rnayak@ti.com> ?wrote:
>>>>
>>>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>>>>
>>>>> Add API to determine IO-PAD wakeup event status for a given
>>>>> hwmod dynamic_mux pad.
>>>>>
>>>>> Wake up event set will be cleared on pad mux_read.
>>>>
>>>> Are these api's even getting used in this series?
>>>
>>> Used in Tero's irq_chaining patches.
>>
>> So shouldn't this patch be part of his series instead?
>
> Yes it is. Part of his v9-series.
>

Then please drop from this series and state the introductory patch
(PATCH 0/n) that this series has a dependency on Tero's series.

Kevin

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

* [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart
  2011-09-30 11:01 ` [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart Govindraj.R
@ 2011-10-10 22:30   ` Kevin Hilman
  2011-10-11  6:45     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 22:30 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Currently we use a shared irq handler to identify uart activity and then
> trigger a timer. 

OK.

> Based the timeout value set from sysfs the timer used to expire.

Please re-phrase as I'm not sure what is being said here.

> If no uart-activity was detected timer-expiry func sets can_sleep
> flag. Based on this we will disable the uart clocks in idle path.
>
> Since the clock gating mechanism is outside the uart driver, we currently
> use this mechanism. In preparation to runtime implementation for omap-serial
> driver we can cleanup this mechanism and use runtime API's to gate uart clocks.
>
> Also remove timer related info from local uart_state struct and remove
> the code used to set timeout value from sysfs. Remove un-used function
> omap_uart_check_wakeup.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

The patch itself fine, and is a well-neede cleanup, but changelog
(especially the first part) does not read well.

Kevin

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

* [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct
  2011-09-30 11:01 ` [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct Govindraj.R
@ 2011-10-10 23:31   ` Kevin Hilman
  2011-10-12 10:25     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 23:31 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Removing some of the uart info that is maintained in omap_uart_state struct
> used for UART PM in serial.c.
>
> Remove omap_uart_state struct dependency from omap_serial_init,
> omap_serial_init_port, omap_serial_early_init and omap_uart_idle_init
> functions.  And populate the same info in omap_uart_port_info struct
> used as pdata struct.

IMO, this change doesn't belong in this patch and leads to clutter.  The
rest of the series slowly removes/replaces all the fields from this
struct, so the right place to remove it's usage all together is at the
end of the series when (if) all the fields are no longer needed (or have
been moved.)

Stated differently, IMO, this patch should leave the uart->num and
uart->oh and the list_head (uart->node) alone (probably uart->pdev too)
and just cleanup the fields that are no longer used.  Removing num, oh,
node here causes churn because you're force to change things here that
are then removed in later patches.

> Added omap_uart_hwmod_lookup function to look up oh by name used in
> serial_port_init and omap_serial_early_init functions.

Because of the above change, you now are doing a hwmod lookup 2 times
for every UART.  Leaving the uart_list and uart->num in place will avoid
the need for that change.

> A list of omap_uart_state was maintained one for each uart, the same
> is removed.  Number of uarts available is maintained in num_uarts
> field, re-use the same in omap_serial_init func to register each uart.
>
> Remove omap_info which used details from omap_uart_state and use a
> pdata pointer to pass platform specific info to driver.

There is no omap_info.  Did you mean omap_up_info?

> The mapbase (start_address), membase(io_remap cookie) maintained as
> part of uart_state struct and pdata struct are removed as this is
> handled within driver. 

This part makes sense.

> Errata field is also moved to pdata. 

Why in this patch instead of the subsequent "Move errata handling from
serial.c to omap-serial" patch?

> These changes are done to cleanup serial.c file and prepare for
> runtime changes.

There are a lot of changes in this patch with very little description as
to why, and many appear to be unrelated.  They should probably be
separate patches, or have a better description as to how all the changes
are related so they belong in the same patch.

> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
> ---
>  arch/arm/mach-omap2/serial.c                  |  132 +++++++++---------------
>  arch/arm/plat-omap/include/plat/omap-serial.h |    4 +-
>  drivers/tty/serial/omap-serial.c              |   12 ++-
>  3 files changed, 61 insertions(+), 87 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index c98b9b4..8c43d1c 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -68,14 +68,6 @@ struct omap_uart_state {
>  	int clocked;
>  
>  	int regshift;
> -	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;
>  
> @@ -90,7 +82,6 @@ struct omap_uart_state {
>  #endif
>  };
>  
> -static LIST_HEAD(uart_list);
>  static u8 num_uarts;
>  
>  static int uart_idle_hwmod(struct omap_device *od)
> @@ -143,7 +134,19 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
>  	__raw_writeb(value, uart->membase + offset);
>  }
>  
> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
> +struct omap_hwmod *omap_uart_hwmod_lookup(int num)
> +{
> +	struct omap_hwmod *oh;
> +	char oh_name[MAX_UART_HWMOD_NAME_LEN];
> +
> +	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;
> +}
> +
> +#if defined(CONFIG_PM)

The CONFIG_ARCH_OMAP3 part of this #if was dropped with this change with
no mention as to why.  (I understand why it was done, but it's not
releveant to $SUBJECT patch so should be a separate patch.)

>  /*
>   * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
> @@ -357,22 +360,17 @@ int omap_uart_can_sleep(void)
>  	return can_sleep;
>  }
>  
> -static void omap_uart_idle_init(struct omap_uart_state *uart)
> +static void omap_uart_idle_init(struct omap_uart_port_info *uart,
> +				unsigned short num)
>  {
> -	int ret;
> -
> -	uart->can_sleep = 0;
> -	omap_uart_smart_idle_enable(uart, 0);
> -
>  	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
> -		u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
> +		u32 mod = (num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
>  		u32 wk_mask = 0;
>  		u32 padconf = 0;
>  
> -		/* XXX These PRM accesses do not belong here */

why?

>  		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;
> @@ -391,12 +389,11 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
>  			break;
>  		}
>  		uart->wk_mask = wk_mask;
> -		uart->padconf = padconf;

The assignment is removed here, making all the rest of the padconf stuff
that remains useless.

However, a subsequent patch removes the mux stuff entirely, so I suggest
you just drop this change from here.

>  	} 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;
> @@ -421,7 +418,6 @@ 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;
>  	}
>  }
>  
> @@ -436,26 +432,13 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
>  
>  static int __init omap_serial_early_init(void)
>  {
> -	int i = 0;
> -
>  	do {
> -		char oh_name[MAX_UART_HWMOD_NAME_LEN];
>  		struct omap_hwmod *oh;
> -		struct omap_uart_state *uart;
>  
> -		snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
> -			 "uart%d", i + 1);
> -		oh = omap_hwmod_lookup(oh_name);
> +		oh = omap_uart_hwmod_lookup(num_uarts);
>  		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++;
>  
>  		/*
> @@ -468,7 +451,7 @@ static int __init omap_serial_early_init(void)
>  		 * 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;
> +		oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
>  	} while (1);
>  
>  	return 0;
> @@ -488,57 +471,47 @@ 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 platform_device *pdev;
> -	void *pdata = NULL;
> +	char *name = DRIVER_NAME;
> +	struct omap_uart_port_info *pdata;
>  	u32 pdata_size = 0;
> -	char *name;
> -	struct omap_uart_port_info omap_up;
>  
>  	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))

why?  because of early_init, num_uarts is already the max number
of UARTs available (based on hwmod probe.)

>  		return;
>  
> -	list_for_each_entry(uart, &uart_list, node)
> -		if (bdata->id == uart->num)
> -			break;
> -
> -	oh = uart->oh;
> -	uart->dma_enabled = 0;
> -	name = DRIVER_NAME;
> +	oh = omap_uart_hwmod_lookup(bdata->id);
> +	if (!oh)
> +		return;
>  
> -	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.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
> +	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata) {
> +		pr_err("Memory allocation for UART pdata failed\n");
> +		return;
> +	}
>  
> -	pdata = &omap_up;
>  	pdata_size = sizeof(struct omap_uart_port_info);
> +	omap_uart_idle_init(pdata, bdata->id);

Why was this moved here?  

ISTR that the order of this call relative to the hwmod/omap_device
enable/disable calls below was important, especially in the DEBUG_LL
case.

> -	if (WARN_ON(!oh))
> -		return;
> +	pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
> +	pdata->flags = UPF_BOOT_AUTOCONF;
> +
> +	/* Enable the MDR1 errata for OMAP3 */
> +	if (cpu_is_omap34xx() && !cpu_is_ti816x())
> +		pdata->errata |= UART_ERRATA_i202_MDR1_ACCESS;
>  
> -	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
> -			       omap_uart_latency,
> -			       ARRAY_SIZE(omap_uart_latency), false);
> +	pdev = omap_device_build(name, bdata->id, oh, pdata,
> +				pdata_size, omap_uart_latency,
> +				ARRAY_SIZE(omap_uart_latency), false);

Note the unecesary whitespace changes in this change.

>  	WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
>  	     name, oh->name);
>  
> -	omap_device_disable_idle_on_suspend(pdev);

This should also be a separate patch at the end of the series, and is
not related to the changes described in the changelog.

>  	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
>  
> -	uart->regshift = 2;
> -	uart->mapbase = oh->slaves[0]->addr->pa_start;
> -	uart->membase = omap_hwmod_get_mpu_rt_va(oh);
> -	uart->pdev = pdev;
> -
> -	oh->dev_attr = uart;
> -
>  	console_lock(); /* in case the earlycon is on the UART */
>  
>  	/*
> @@ -546,23 +519,18 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
>  	 * on init.  Now that omap_device is ready, ensure full idle
>  	 * before doing omap_device_enable().
>  	 */
> -	omap_hwmod_idle(uart->oh);
> +	omap_hwmod_idle(oh);
>  
> -	omap_device_enable(uart->pdev);
> -	omap_uart_idle_init(uart);
> -	omap_hwmod_enable_wakeup(uart->oh);
> -	omap_device_idle(uart->pdev);
> +	omap_device_enable(pdev);
> +	omap_hwmod_enable_wakeup(oh);
>  
> -	omap_uart_block_sleep(uart);
>  	console_unlock();
>  
> -	if ((cpu_is_omap34xx() && uart->padconf) ||
> -	    (uart->wk_en && uart->wk_mask))
> +	if ((cpu_is_omap34xx() && bdata->pads) ||
> +		(pdata->wk_en && pdata->wk_mask))

This change seems to belong as part of the mux patch.

>  		device_init_wakeup(&pdev->dev, true);
>  
> -	/* Enable the MDR1 errata for OMAP3 */
> -	if (cpu_is_omap34xx() && !cpu_is_ti816x())
> -		uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
> +	kfree(pdata);
>  }
>  
>  /**
> @@ -574,11 +542,11 @@ 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 < num_uarts; i++) {
> +		bdata.id = i;
>  		bdata.flags = 0;
>  		bdata.pads = NULL;
>  		bdata.pads_cnt = 0;
> diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
> index 307cd6f..0f061b4 100644
> --- a/arch/arm/plat-omap/include/plat/omap-serial.h
> +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
> @@ -59,9 +59,9 @@
>  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 */
>  	upf_t			flags;		/* UPF_* flags */
> +
> +	u32			errata;
>  };
>  
>  struct uart_omap_dma {
> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
> index 5e713d3..6c2ea54 100644
> --- a/drivers/tty/serial/omap-serial.c
> +++ b/drivers/tty/serial/omap-serial.c
> @@ -1275,10 +1275,16 @@ 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, resource_size(mem));
> +
> +	if (!up->port.membase) {
> +		dev_err(&pdev->dev, "can't ioremap UART\n");
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
>  	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;

Kevin

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
@ 2011-10-10 23:42   ` Kevin Hilman
  2011-10-12 10:37     ` Govindraj
  2011-10-10 23:56   ` Kevin Hilman
  2011-10-13  0:06   ` Kevin Hilman
  2 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 23:42 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Adapts omap-serial driver to use pm_runtime API's.

[...]

> @@ -1065,19 +1123,18 @@ 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)
>  		uart_suspend_port(&serial_omap_reg, &up->port);
>  	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)
>  		uart_resume_port(&serial_omap_reg, &up->port);

These functions need to be wrapped in #ifdef CONFIG_SUSPEND, otherwise,
when building with !CONFIG_SUSPEND you'll get :

/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1134:12: warning: 'serial_omap_suspend' defined but not used
/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1150:12: warning: 'serial_omap_resume' defined but not used


[...]

> +static int serial_omap_runtime_suspend(struct device *dev)
> +{
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
> +	struct omap_uart_port_info *pdata = dev->platform_data;
> +
> +	if (!up)
> +		return -EINVAL;
> +
> +	if (!pdata->enable_wakeup || !pdata->get_context_loss_count)
> +		return 0;
> +
> +	if (pdata->get_context_loss_count)
> +		up->context_loss_cnt = pdata->get_context_loss_count(dev);
> +
> +	if (device_may_wakeup(dev)) {
> +		if (!up->wakeups_enabled) {
> +			pdata->enable_wakeup(up->pdev, true);
> +			up->wakeups_enabled = true;
> +		}
> +	} else {
> +		if (up->wakeups_enabled) {
> +			pdata->enable_wakeup(up->pdev, false);
> +			up->wakeups_enabled = false;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int serial_omap_runtime_resume(struct device *dev)
> +{
> +	struct uart_omap_port *up = dev_get_drvdata(dev);
> +	struct omap_uart_port_info *pdata = dev->platform_data;
> +
> +	if (up) {
> +		if (pdata->get_context_loss_count) {
> +			u32 loss_cnt = pdata->get_context_loss_count(dev);
> +
> +			if (up->context_loss_cnt != loss_cnt)
> +				serial_omap_restore_context(up);
> +		}
> +	}
> +
>  	return 0;
>  }

Similarily, thse need to be wrapped with #ifdef CONFIG_PM_RUNTIME,
otherwise, when !CONFIG_PM_RUNTIME:

/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1498:12: warning: 'serial_omap_runtime_suspend' defined but not used
/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1531:12: warning: 'serial_omap_runtime_resume' defined but not used

> +static const struct dev_pm_ops serial_omap_dev_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
> +	SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
> +				serial_omap_runtime_resume, NULL)
> +};
> +

Note that you don't need #else parts to the above #ifdefs since
the SET_*_OPS() macros used here take care of that.

Kevin

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
  2011-10-10 23:42   ` Kevin Hilman
@ 2011-10-10 23:56   ` Kevin Hilman
  2011-10-12 10:35     ` Govindraj
  2011-10-13  0:06   ` Kevin Hilman
  2 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 23:56 UTC (permalink / raw)
  To: linux-arm-kernel

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

> Adapts omap-serial driver to use pm_runtime API's.
>
> Use runtime runtime API's to handle uart clocks and obtain
> device_usage statics. Set runtime API's usage to irq_safe so that
> we can use get_sync from irq context. Auto-suspend for port specific
> activities and put for reg access. Use device_may_wakeup to check
> whether uart has wakeup capabilities and then enable uart runtime
> usage for the uart.

OK.  Current patch should do only this part.  The rest should be
separate patches with their own descriptive changelogs.

> Removing save_context/restore_context functions from serial.c
> Adding context restore to .runtime_suspend and using reg values from port
> structure to restore the uart port context based on context_loss_count.
> Maintain internal state machine using wakeups_enabled field for avoiding
> repeated enable/disable of uart port wakeup mechanism.

This part should be a separate patch that follows.

> Remove omap_uart_disable_wakeup and modify omap_uart_enable_wakeup
> to accept pdev and bool value to enable/disable the uart wakeup mechanism
> after uart clock's are cut. 
>
> omap_hwmod_enable_wakeup is used to set
> pad wakeup for the uarts. PM_WKEN reg values are left to default.
> Removed omap_uart_enable/disable_clocks in serial.c now clock handling
> done with runtime API's.

As stated in previous reviews, this wakeup enable/disable needs more
description as the functionality is changing compared to current code.

Current version modifies wakeup enable/disable at both power-domain
level (PM_WKEN) and at the IO ring. 

Updated version modifies wakeups at module-level (SYSCONFIG) and at IO
ring using omap_hwmod_enable_wakeup()

IMO, the updated version makes more sense, but needs a description as to
why that change in functionality will have equivalent results compared
to the existing one.

> By default uart autosuspend delay is set to -1 to avoid character loss
> if uart's are autoidled and woken up on rx pin.

OK, good.

> After boot up UART's can be autoidled by setting autosuspendi delay from sysfs.
>
> echo 3000 > /sys/devices/platform/omap/omap_uart.X/power/autosuspend_delay_ms
> X=0,1,2,3 for UART1/2/3/4. Number of uarts available may vary across omap_soc.
>
> Acked-by: Alan Cox <alan@linux.intel.com>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

Kevin

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

* [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure
  2011-09-30 11:01 ` [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure Govindraj.R
@ 2011-10-10 23:58   ` Kevin Hilman
  2011-10-11 13:21     ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-10 23:58 UTC (permalink / raw)
  To: linux-arm-kernel

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

> In preparation to runtime conversion add missing uart regs to
> port structure which can be used in context restore.
> Also ensuring all uart reg info's are part of port structure.
>
> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>

IMO, this should come later in the series to avoid adding bunch of code
that gets moved in a subsequent patch.

First, convert to runtime PM (current patch 9/16)
Then, add a patch to move context save/restore into driver.
Then, add this patch.

Kevin

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

* [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status
  2011-10-10 22:24           ` Kevin Hilman
@ 2011-10-11  6:17             ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-11  6:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 3:54 AM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
>> On Mon, Oct 3, 2011 at 10:53 AM, Rajendra Nayak <rnayak@ti.com> wrote:
>>> On Monday 03 October 2011 10:30 AM, Govindraj wrote:
>>>
>>>> On Sat, Oct 1, 2011 at 8:03 PM, Rajendra Nayak<rnayak@ti.com> ?wrote:
>>>>>
>>>>> On Friday 30 September 2011 04:31 PM, Govindraj.R wrote:
>>>>>>
>>>>>> Add API to determine IO-PAD wakeup event status for a given
>>>>>> hwmod dynamic_mux pad.
>>>>>>
>>>>>> Wake up event set will be cleared on pad mux_read.
>>>>>
>>>>> Are these api's even getting used in this series?
>>>>
>>>> Used in Tero's irq_chaining patches.
>>>
>>> So shouldn't this patch be part of his series instead?
>>
>> Yes it is. Part of his v9-series.
>>
>
> Then please drop from this series and state the introductory patch
> (PATCH 0/n) that this series has a dependency on Tero's series.
>

Okay.

--
Thanks,
Govindraj.R

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

* [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart
  2011-10-10 22:30   ` Kevin Hilman
@ 2011-10-11  6:45     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-11  6:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 4:00 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Currently we use a shared irq handler to identify uart activity and then
>> trigger a timer.
>
> OK.
>
>> Based the timeout value set from sysfs the timer used to expire.
>
> Please re-phrase as I'm not sure what is being said here.
>
>> If no uart-activity was detected timer-expiry func sets can_sleep
>> flag. Based on this we will disable the uart clocks in idle path.
>>
>> Since the clock gating mechanism is outside the uart driver, we currently
>> use this mechanism. In preparation to runtime implementation for omap-serial
>> driver we can cleanup this mechanism and use runtime API's to gate uart clocks.
>>
>> Also remove timer related info from local uart_state struct and remove
>> the code used to set timeout value from sysfs. Remove un-used function
>> omap_uart_check_wakeup.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> The patch itself fine, and is a well-neede cleanup, but changelog
> (especially the first part) does not read well.
>

Okay, Will Correct.

--
Thanks.
Govindraj.R

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

* [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure
  2011-10-10 23:58   ` Kevin Hilman
@ 2011-10-11 13:21     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-11 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 5:28 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> In preparation to runtime conversion add missing uart regs to
>> port structure which can be used in context restore.
>> Also ensuring all uart reg info's are part of port structure.
>>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> IMO, this should come later in the series to avoid adding bunch of code
> that gets moved in a subsequent patch.
>
> First, convert to runtime PM (current patch 9/16)
> Then, add a patch to move context save/restore into driver.
> Then, add this patch.

Okay fine.

--
Thanks,
Govindraj.R

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

* [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct
  2011-10-10 23:31   ` Kevin Hilman
@ 2011-10-12 10:25     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-12 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 5:01 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Removing some of the uart info that is maintained in omap_uart_state struct
>> used for UART PM in serial.c.
>>
>> Remove omap_uart_state struct dependency from omap_serial_init,
>> omap_serial_init_port, omap_serial_early_init and omap_uart_idle_init
>> functions. ?And populate the same info in omap_uart_port_info struct
>> used as pdata struct.
>
> IMO, this change doesn't belong in this patch and leads to clutter. ?The
> rest of the series slowly removes/replaces all the fields from this
> struct, so the right place to remove it's usage all together is at the
> end of the series when (if) all the fields are no longer needed (or have
> been moved.)
>

Okay will move it to end.

> Stated differently, IMO, this patch should leave the uart->num and
> uart->oh and the list_head (uart->node) alone (probably uart->pdev too)
> and just cleanup the fields that are no longer used. ?Removing num, oh,
> node here causes churn because you're force to change things here that
> are then removed in later patches.
>

okay will retain the list part.

>> Added omap_uart_hwmod_lookup function to look up oh by name used in
>> serial_port_init and omap_serial_early_init functions.
>
> Because of the above change, you now are doing a hwmod lookup 2 times
> for every UART. ?Leaving the uart_list and uart->num in place will avoid
> the need for that change.
>

yes since uart_list was removed, will retain the uart_list
to avoid the look up twice.


>> A list of omap_uart_state was maintained one for each uart, the same
>> is removed. ?Number of uarts available is maintained in num_uarts
>> field, re-use the same in omap_serial_init func to register each uart.
>>
>> Remove omap_info which used details from omap_uart_state and use a
>> pdata pointer to pass platform specific info to driver.
>
> There is no omap_info. ?Did you mean omap_up_info?

yes sorry typo.

>
>> The mapbase (start_address), membase(io_remap cookie) maintained as
>> part of uart_state struct and pdata struct are removed as this is
>> handled within driver.
>
> This part makes sense.
>

okay will retain this part only.

>> Errata field is also moved to pdata.
>
> Why in this patch instead of the subsequent "Move errata handling from
> serial.c to omap-serial" patch?
>

will move to the errata patch.


>> These changes are done to cleanup serial.c file and prepare for
>> runtime changes.
>
> There are a lot of changes in this patch with very little description as
> to why, and many appear to be unrelated. ?They should probably be
> separate patches, or have a better description as to how all the changes
> are related so they belong in the same patch.
>

okay fine will split them into smaller changes.


>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>> ---
>> ?arch/arm/mach-omap2/serial.c ? ? ? ? ? ? ? ? ?| ?132 +++++++++---------------
>> ?arch/arm/plat-omap/include/plat/omap-serial.h | ? ?4 +-
>> ?drivers/tty/serial/omap-serial.c ? ? ? ? ? ? ?| ? 12 ++-
>> ?3 files changed, 61 insertions(+), 87 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
>> index c98b9b4..8c43d1c 100644
>> --- a/arch/arm/mach-omap2/serial.c
>> +++ b/arch/arm/mach-omap2/serial.c
>> @@ -68,14 +68,6 @@ struct omap_uart_state {
>> ? ? ? int clocked;
>>
>> ? ? ? int regshift;
>> - ? ? 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;
>>
>> @@ -90,7 +82,6 @@ struct omap_uart_state {
>> ?#endif
>> ?};
>>
>> -static LIST_HEAD(uart_list);
>> ?static u8 num_uarts;
>>
>> ?static int uart_idle_hwmod(struct omap_device *od)
>> @@ -143,7 +134,19 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
>> ? ? ? __raw_writeb(value, uart->membase + offset);
>> ?}
>>
>> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
>> +struct omap_hwmod *omap_uart_hwmod_lookup(int num)
>> +{
>> + ? ? struct omap_hwmod *oh;
>> + ? ? char oh_name[MAX_UART_HWMOD_NAME_LEN];
>> +
>> + ? ? 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;
>> +}
>> +
>> +#if defined(CONFIG_PM)
>
> The CONFIG_ARCH_OMAP3 part of this #if was dropped with this change with
> no mention as to why. ?(I understand why it was done, but it's not
> releveant to $SUBJECT patch so should be a separate patch.)
>
>> ?/*
>> ? * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
>> @@ -357,22 +360,17 @@ int omap_uart_can_sleep(void)
>> ? ? ? return can_sleep;
>> ?}
>>
>> -static void omap_uart_idle_init(struct omap_uart_state *uart)
>> +static void omap_uart_idle_init(struct omap_uart_port_info *uart,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned short num)
>> ?{
>> - ? ? int ret;
>> -
>> - ? ? uart->can_sleep = 0;
>> - ? ? omap_uart_smart_idle_enable(uart, 0);
>> -
>> ? ? ? if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
>> - ? ? ? ? ? ? u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
>> + ? ? ? ? ? ? u32 mod = (num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
>> ? ? ? ? ? ? ? u32 wk_mask = 0;
>> ? ? ? ? ? ? ? u32 padconf = 0;
>>
>> - ? ? ? ? ? ? /* XXX These PRM accesses do not belong here */
>
> why?
>
>> ? ? ? ? ? ? ? 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;
>> @@ -391,12 +389,11 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
>> ? ? ? ? ? ? ? ? ? ? ? break;
>> ? ? ? ? ? ? ? }
>> ? ? ? ? ? ? ? uart->wk_mask = wk_mask;
>> - ? ? ? ? ? ? uart->padconf = padconf;
>
> The assignment is removed here, making all the rest of the padconf stuff
> that remains useless.
>
> However, a subsequent patch removes the mux stuff entirely, so I suggest
> you just drop this change from here.
>

okay will incorporate this as part of mux changes patch.


>> ? ? ? } 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;
>> @@ -421,7 +418,6 @@ 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;
>> ? ? ? }
>> ?}
>>
>> @@ -436,26 +432,13 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
>>
>> ?static int __init omap_serial_early_init(void)
>> ?{
>> - ? ? int i = 0;
>> -
>> ? ? ? do {
>> - ? ? ? ? ? ? char oh_name[MAX_UART_HWMOD_NAME_LEN];
>> ? ? ? ? ? ? ? struct omap_hwmod *oh;
>> - ? ? ? ? ? ? struct omap_uart_state *uart;
>>
>> - ? ? ? ? ? ? snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
>> - ? ? ? ? ? ? ? ? ? ? ?"uart%d", i + 1);
>> - ? ? ? ? ? ? oh = omap_hwmod_lookup(oh_name);
>> + ? ? ? ? ? ? oh = omap_uart_hwmod_lookup(num_uarts);
>> ? ? ? ? ? ? ? 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++;
>>
>> ? ? ? ? ? ? ? /*
>> @@ -468,7 +451,7 @@ static int __init omap_serial_early_init(void)
>> ? ? ? ? ? ? ? ?* 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;
>> + ? ? ? ? ? ? oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
>> ? ? ? } while (1);
>>
>> ? ? ? return 0;
>> @@ -488,57 +471,47 @@ 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 platform_device *pdev;
>> - ? ? void *pdata = NULL;
>> + ? ? char *name = DRIVER_NAME;
>> + ? ? struct omap_uart_port_info *pdata;
>> ? ? ? u32 pdata_size = 0;
>> - ? ? char *name;
>> - ? ? struct omap_uart_port_info omap_up;
>>
>> ? ? ? 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))
>
> why? ?because of early_init, num_uarts is already the max number
> of UARTs available (based on hwmod probe.)
>

yes will correct this and use num_uarts

>> ? ? ? ? ? ? ? return;
>>
>> - ? ? list_for_each_entry(uart, &uart_list, node)
>> - ? ? ? ? ? ? if (bdata->id == uart->num)
>> - ? ? ? ? ? ? ? ? ? ? break;
>> -
>> - ? ? oh = uart->oh;
>> - ? ? uart->dma_enabled = 0;
>> - ? ? name = DRIVER_NAME;
>> + ? ? oh = omap_uart_hwmod_lookup(bdata->id);
>> + ? ? if (!oh)
>> + ? ? ? ? ? ? return;
>>
>> - ? ? 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.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
>> + ? ? pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
>> + ? ? if (!pdata) {
>> + ? ? ? ? ? ? pr_err("Memory allocation for UART pdata failed\n");
>> + ? ? ? ? ? ? return;
>> + ? ? }
>>
>> - ? ? pdata = &omap_up;
>> ? ? ? pdata_size = sizeof(struct omap_uart_port_info);
>> + ? ? omap_uart_idle_init(pdata, bdata->id);
>
> Why was this moved here?
>
> ISTR that the order of this call relative to the hwmod/omap_device
> enable/disable calls below was important, especially in the DEBUG_LL
> case.
>
>> - ? ? if (WARN_ON(!oh))
>> - ? ? ? ? ? ? return;
>> + ? ? pdata->uartclk = OMAP24XX_BASE_BAUD * 16;
>> + ? ? pdata->flags = UPF_BOOT_AUTOCONF;
>> +
>> + ? ? /* Enable the MDR1 errata for OMAP3 */
>> + ? ? if (cpu_is_omap34xx() && !cpu_is_ti816x())
>> + ? ? ? ? ? ? pdata->errata |= UART_ERRATA_i202_MDR1_ACCESS;
>>
>> - ? ? pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?omap_uart_latency,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARRAY_SIZE(omap_uart_latency), false);
>> + ? ? pdev = omap_device_build(name, bdata->id, oh, pdata,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? pdata_size, omap_uart_latency,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ARRAY_SIZE(omap_uart_latency), false);
>
> Note the unecesary whitespace changes in this change.
>
>> ? ? ? WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
>> ? ? ? ? ? ?name, oh->name);
>>
>> - ? ? omap_device_disable_idle_on_suspend(pdev);
>
> This should also be a separate patch at the end of the series, and is
> not related to the changes described in the changelog.
>

okay.

>> ? ? ? oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
>>
>> - ? ? uart->regshift = 2;
>> - ? ? uart->mapbase = oh->slaves[0]->addr->pa_start;
>> - ? ? uart->membase = omap_hwmod_get_mpu_rt_va(oh);
>> - ? ? uart->pdev = pdev;
>> -
>> - ? ? oh->dev_attr = uart;
>> -
>> ? ? ? console_lock(); /* in case the earlycon is on the UART */
>>
>> ? ? ? /*
>> @@ -546,23 +519,18 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
>> ? ? ? ?* on init. ?Now that omap_device is ready, ensure full idle
>> ? ? ? ?* before doing omap_device_enable().
>> ? ? ? ?*/
>> - ? ? omap_hwmod_idle(uart->oh);
>> + ? ? omap_hwmod_idle(oh);
>>
>> - ? ? omap_device_enable(uart->pdev);
>> - ? ? omap_uart_idle_init(uart);
>> - ? ? omap_hwmod_enable_wakeup(uart->oh);
>> - ? ? omap_device_idle(uart->pdev);
>> + ? ? omap_device_enable(pdev);
>> + ? ? omap_hwmod_enable_wakeup(oh);
>>
>> - ? ? omap_uart_block_sleep(uart);
>> ? ? ? console_unlock();
>>
>> - ? ? if ((cpu_is_omap34xx() && uart->padconf) ||
>> - ? ? ? ? (uart->wk_en && uart->wk_mask))
>> + ? ? if ((cpu_is_omap34xx() && bdata->pads) ||
>> + ? ? ? ? ? ? (pdata->wk_en && pdata->wk_mask))
>
> This change seems to belong as part of the mux patch.
>

okay moving to mux change patch.

>> ? ? ? ? ? ? ? device_init_wakeup(&pdev->dev, true);
>>
>> - ? ? /* Enable the MDR1 errata for OMAP3 */
>> - ? ? if (cpu_is_omap34xx() && !cpu_is_ti816x())
>> - ? ? ? ? ? ? uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
>> + ? ? kfree(pdata);
>> ?}
>>
>> ?/**
>> @@ -574,11 +542,11 @@ 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 < num_uarts; i++) {
>> + ? ? ? ? ? ? bdata.id = i;
>> ? ? ? ? ? ? ? bdata.flags = 0;
>> ? ? ? ? ? ? ? bdata.pads = NULL;
>> ? ? ? ? ? ? ? bdata.pads_cnt = 0;
>> diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
>> index 307cd6f..0f061b4 100644
>> --- a/arch/arm/plat-omap/include/plat/omap-serial.h
>> +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
>> @@ -59,9 +59,9 @@
>> ?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 */
>> ? ? ? upf_t ? ? ? ? ? ? ? ? ? flags; ? ? ? ? ?/* UPF_* flags */
>> +
>> + ? ? u32 ? ? ? ? ? ? ? ? ? ? errata;
>> ?};
>>
>> ?struct uart_omap_dma {
>> diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
>> index 5e713d3..6c2ea54 100644
>> --- a/drivers/tty/serial/omap-serial.c
>> +++ b/drivers/tty/serial/omap-serial.c
>> @@ -1275,10 +1275,16 @@ 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, resource_size(mem));
>> +
>> + ? ? if (!up->port.membase) {
>> + ? ? ? ? ? ? dev_err(&pdev->dev, "can't ioremap UART\n");
>> + ? ? ? ? ? ? ret = -ENOMEM;
>> + ? ? ? ? ? ? goto err;
>> + ? ? }
>> +
>> ? ? ? 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;
>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-10 23:56   ` Kevin Hilman
@ 2011-10-12 10:35     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-12 10:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 5:26 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Adapts omap-serial driver to use pm_runtime API's.
>>
>> Use runtime runtime API's to handle uart clocks and obtain
>> device_usage statics. Set runtime API's usage to irq_safe so that
>> we can use get_sync from irq context. Auto-suspend for port specific
>> activities and put for reg access. Use device_may_wakeup to check
>> whether uart has wakeup capabilities and then enable uart runtime
>> usage for the uart.
>
> OK. ?Current patch should do only this part. ?The rest should be
> separate patches with their own descriptive changelogs.
>

Yes, started splitting them.

>> Removing save_context/restore_context functions from serial.c
>> Adding context restore to .runtime_suspend and using reg values from port
>> structure to restore the uart port context based on context_loss_count.
>> Maintain internal state machine using wakeups_enabled field for avoiding
>> repeated enable/disable of uart port wakeup mechanism.
>
> This part should be a separate patch that follows.
>

okay,

>> Remove omap_uart_disable_wakeup and modify omap_uart_enable_wakeup
>> to accept pdev and bool value to enable/disable the uart wakeup mechanism
>> after uart clock's are cut.
>>
>> omap_hwmod_enable_wakeup is used to set
>> pad wakeup for the uarts. PM_WKEN reg values are left to default.
>> Removed omap_uart_enable/disable_clocks in serial.c now clock handling
>> done with runtime API's.
>
> As stated in previous reviews, this wakeup enable/disable needs more
> description as the functionality is changing compared to current code.
>
> Current version modifies wakeup enable/disable at both power-domain
> level (PM_WKEN) and at the IO ring.
>
> Updated version modifies wakeups at module-level (SYSCONFIG) and at IO
> ring using omap_hwmod_enable_wakeup()
>
> IMO, the updated version makes more sense, but needs a description as to
> why that change in functionality will have equivalent results compared
> to the existing one.
>

Okay,

>> By default uart autosuspend delay is set to -1 to avoid character loss
>> if uart's are autoidled and woken up on rx pin.
>
> OK, good.
>
>> After boot up UART's can be autoidled by setting autosuspendi delay from sysfs.
>>
>> echo 3000 > /sys/devices/platform/omap/omap_uart.X/power/autosuspend_delay_ms
>> X=0,1,2,3 for UART1/2/3/4. Number of uarts available may vary across omap_soc.
>>
>> Acked-by: Alan Cox <alan@linux.intel.com>
>> Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
>
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-10 23:42   ` Kevin Hilman
@ 2011-10-12 10:37     ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-12 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 11, 2011 at 5:12 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
>> Adapts omap-serial driver to use pm_runtime API's.
>
> [...]
>
>> @@ -1065,19 +1123,18 @@ 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)
>> ? ? ? ? ? ? ? uart_suspend_port(&serial_omap_reg, &up->port);
>> ? ? ? 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)
>> ? ? ? ? ? ? ? uart_resume_port(&serial_omap_reg, &up->port);
>
> These functions need to be wrapped in #ifdef CONFIG_SUSPEND, otherwise,
> when building with !CONFIG_SUSPEND you'll get :
>
> /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1134:12: warning: 'serial_omap_suspend' defined but not used
> /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1150:12: warning: 'serial_omap_resume' defined but not used
>
>
> [...]
>
>> +static int serial_omap_runtime_suspend(struct device *dev)
>> +{
>> + ? ? struct uart_omap_port *up = dev_get_drvdata(dev);
>> + ? ? struct omap_uart_port_info *pdata = dev->platform_data;
>> +
>> + ? ? if (!up)
>> + ? ? ? ? ? ? return -EINVAL;
>> +
>> + ? ? if (!pdata->enable_wakeup || !pdata->get_context_loss_count)
>> + ? ? ? ? ? ? return 0;
>> +
>> + ? ? if (pdata->get_context_loss_count)
>> + ? ? ? ? ? ? up->context_loss_cnt = pdata->get_context_loss_count(dev);
>> +
>> + ? ? if (device_may_wakeup(dev)) {
>> + ? ? ? ? ? ? if (!up->wakeups_enabled) {
>> + ? ? ? ? ? ? ? ? ? ? pdata->enable_wakeup(up->pdev, true);
>> + ? ? ? ? ? ? ? ? ? ? up->wakeups_enabled = true;
>> + ? ? ? ? ? ? }
>> + ? ? } else {
>> + ? ? ? ? ? ? if (up->wakeups_enabled) {
>> + ? ? ? ? ? ? ? ? ? ? pdata->enable_wakeup(up->pdev, false);
>> + ? ? ? ? ? ? ? ? ? ? up->wakeups_enabled = false;
>> + ? ? ? ? ? ? }
>> + ? ? }
>> +
>> + ? ? return 0;
>> +}
>> +
>> +static int serial_omap_runtime_resume(struct device *dev)
>> +{
>> + ? ? struct uart_omap_port *up = dev_get_drvdata(dev);
>> + ? ? struct omap_uart_port_info *pdata = dev->platform_data;
>> +
>> + ? ? if (up) {
>> + ? ? ? ? ? ? if (pdata->get_context_loss_count) {
>> + ? ? ? ? ? ? ? ? ? ? u32 loss_cnt = pdata->get_context_loss_count(dev);
>> +
>> + ? ? ? ? ? ? ? ? ? ? if (up->context_loss_cnt != loss_cnt)
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? serial_omap_restore_context(up);
>> + ? ? ? ? ? ? }
>> + ? ? }
>> +
>> ? ? ? return 0;
>> ?}
>
> Similarily, thse need to be wrapped with #ifdef CONFIG_PM_RUNTIME,
> otherwise, when !CONFIG_PM_RUNTIME:
>
> /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1498:12: warning: 'serial_omap_runtime_suspend' defined but not used
> /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:1531:12: warning: 'serial_omap_runtime_resume' defined but not used
>
>> +static const struct dev_pm_ops serial_omap_dev_pm_ops = {
>> + ? ? SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
>> + ? ? SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? serial_omap_runtime_resume, NULL)
>> +};
>> +
>
> Note that you don't need #else parts to the above #ifdefs since
> the SET_*_OPS() macros used here take care of that.
>

Yes fine, Corrected

Thanks for catching this.

--
Govindraj.R

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
  2011-10-10 23:42   ` Kevin Hilman
  2011-10-10 23:56   ` Kevin Hilman
@ 2011-10-13  0:06   ` Kevin Hilman
  2011-10-13  1:28     ` Govindraj
  2 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-13  0:06 UTC (permalink / raw)
  To: linux-arm-kernel

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

[...] 

> Use device_may_wakeup to check whether uart has wakeup capabilities
> and then enable uart runtime usage for the uart.

Curious about what happens when device_may_wakeup() is not set during
device init.

[...]

> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
> +	if (device_may_wakeup(&pdev->dev)) {
> +		pm_runtime_enable(&pdev->dev);

So if device_may_wakeup() is false, runtime PM is not enabled, then...

> +		pm_runtime_get_sync(&pdev->dev);

...this get doesn't happen, and the first register access causes a crash.

So either this get isn't needed, because there is no device access in
this path, or this path is broken and needs validation.

> +	}
> +
>  	ui[pdev->id] = up;
>  	serial_omap_add_console_port(up);
>  
> @@ -1312,6 +1380,7 @@ static int serial_omap_probe(struct platform_device *pdev)
>  	if (ret != 0)
>  		goto do_release_region;
>  
> +	pm_runtime_put(&pdev->dev);

...also, this put is not balanced with a corresponding get.

Kevin

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-13  0:06   ` Kevin Hilman
@ 2011-10-13  1:28     ` Govindraj
  2011-10-13 21:22       ` Kevin Hilman
  0 siblings, 1 reply; 41+ messages in thread
From: Govindraj @ 2011-10-13  1:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 13, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Govindraj.R" <govindraj.raja@ti.com> writes:
>
> [...]
>
>> Use device_may_wakeup to check whether uart has wakeup capabilities
>> and then enable uart runtime usage for the uart.
>
> Curious about what happens when device_may_wakeup() is not set during
> device init.
>
> [...]
>
>> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
>> + ? ? if (device_may_wakeup(&pdev->dev)) {
>> + ? ? ? ? ? ? pm_runtime_enable(&pdev->dev);
>
> So if device_may_wakeup() is false, runtime PM is not enabled, then...
>
>> + ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev);
>
> ...this get doesn't happen, and the first register access causes a crash.

Actually no crash, clocks will left enabled from boot up (hwmod_no_reset/idle)
that are idled and enabled back here.

Since hwmod_idle is binded here later ([PATCH v6 15/16]),

>
> So either this get isn't needed, because there is no device access in
> this path, or this path is broken and needs validation.
>
>> + ? ? }
>> +
>> ? ? ? ui[pdev->id] = up;
>> ? ? ? serial_omap_add_console_port(up);
>>
>> @@ -1312,6 +1380,7 @@ static int serial_omap_probe(struct platform_device *pdev)
>> ? ? ? if (ret != 0)
>> ? ? ? ? ? ? ? goto do_release_region;
>>
>> + ? ? pm_runtime_put(&pdev->dev);
>
> ...also, this put is not balanced with a corresponding get.

this needs to happen only when runtime is enabled.

will correct this.

--
Thanks,
Govindraj.,R

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-13  1:28     ` Govindraj
@ 2011-10-13 21:22       ` Kevin Hilman
  2011-10-14 12:32         ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-13 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

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

> On Thu, Oct 13, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>
>> [...]
>>
>>> Use device_may_wakeup to check whether uart has wakeup capabilities
>>> and then enable uart runtime usage for the uart.
>>
>> Curious about what happens when device_may_wakeup() is not set during
>> device init.
>>
>> [...]
>>
>>> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
>>> + ? ? if (device_may_wakeup(&pdev->dev)) {
>>> + ? ? ? ? ? ? pm_runtime_enable(&pdev->dev);
>>
>> So if device_may_wakeup() is false, runtime PM is not enabled, then...
>>
>>> + ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev);
>>
>> ...this get doesn't happen, and the first register access causes a crash.
>
> Actually no crash, clocks will left enabled from boot up (hwmod_no_reset/idle)
> that are idled and enabled back here.
>
> Since hwmod_idle is binded here later ([PATCH v6 15/16]),

IMO, That's not a very maintainable solution.   

What happens when when someone fixes serial.c to only set
HWMOD_INIT_NO_IDLE on the console UART?  or if we fix things so we don't
need INIT_NO_IDLE anymore?  Then this will crash.

Driver code should not make assumptions like this about what device init
code is or isn't doing.

Kevin

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-13 21:22       ` Kevin Hilman
@ 2011-10-14 12:32         ` Govindraj
  2011-10-14 17:04           ` Kevin Hilman
  0 siblings, 1 reply; 41+ messages in thread
From: Govindraj @ 2011-10-14 12:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 14, 2011 at 2:52 AM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
>> On Thu, Oct 13, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>>
>>> [...]
>>>
>>>> Use device_may_wakeup to check whether uart has wakeup capabilities
>>>> and then enable uart runtime usage for the uart.
>>>
>>> Curious about what happens when device_may_wakeup() is not set during
>>> device init.
>>>
>>> [...]
>>>
>>>> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
>>>> + ? ? if (device_may_wakeup(&pdev->dev)) {
>>>> + ? ? ? ? ? ? pm_runtime_enable(&pdev->dev);
>>>
>>> So if device_may_wakeup() is false, runtime PM is not enabled, then...
>>>
>>>> + ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev);
>>>
>>> ...this get doesn't happen, and the first register access causes a crash.
>>
>> Actually no crash, clocks will left enabled from boot up (hwmod_no_reset/idle)
>> that are idled and enabled back here.
>>
>> Since hwmod_idle is binded here later ([PATCH v6 15/16]),
>
> IMO, That's not a very maintainable solution.
>
> What happens when when someone fixes serial.c to only set
> HWMOD_INIT_NO_IDLE on the console UART? ?or if we fix things so we don't
> need INIT_NO_IDLE anymore? ?Then this will crash.
>
> Driver code should not make assumptions like this about what device init
> code is or isn't doing.
>

Okay, How about doing as below ensuring get_sync always
and forbid runtime to avoid clock_gating if wakeup is not set.

static int serial_omap_probe(struct platform_device *pdev) {
[..]
        pm_runtime_enable(&pdev->dev);
        pm_runtime_get_sync(&pdev->dev);

        if (!device_may_wakeup(&pdev->dev))
                pm_runtime_forbid(&pdev->dev);

[..]

        pm_runtime_put(&pdev->dev);
[..]
}


--
Thanks,
Govindraj.R

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-14 12:32         ` Govindraj
@ 2011-10-14 17:04           ` Kevin Hilman
  2011-10-14 18:29             ` Govindraj
  0 siblings, 1 reply; 41+ messages in thread
From: Kevin Hilman @ 2011-10-14 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

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

> On Fri, Oct 14, 2011 at 2:52 AM, Kevin Hilman <khilman@ti.com> wrote:
>> Govindraj <govindraj.ti@gmail.com> writes:
>>
>>> On Thu, Oct 13, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>>>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>>>
>>>> [...]
>>>>
>>>>> Use device_may_wakeup to check whether uart has wakeup capabilities
>>>>> and then enable uart runtime usage for the uart.
>>>>
>>>> Curious about what happens when device_may_wakeup() is not set during
>>>> device init.
>>>>
>>>> [...]
>>>>
>>>>> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
>>>>> + ? ? if (device_may_wakeup(&pdev->dev)) {
>>>>> + ? ? ? ? ? ? pm_runtime_enable(&pdev->dev);
>>>>
>>>> So if device_may_wakeup() is false, runtime PM is not enabled, then...
>>>>
>>>>> + ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev);
>>>>
>>>> ...this get doesn't happen, and the first register access causes a crash.
>>>
>>> Actually no crash, clocks will left enabled from boot up (hwmod_no_reset/idle)
>>> that are idled and enabled back here.
>>>
>>> Since hwmod_idle is binded here later ([PATCH v6 15/16]),
>>
>> IMO, That's not a very maintainable solution.
>>
>> What happens when when someone fixes serial.c to only set
>> HWMOD_INIT_NO_IDLE on the console UART? ?or if we fix things so we don't
>> need INIT_NO_IDLE anymore? ?Then this will crash.
>>
>> Driver code should not make assumptions like this about what device init
>> code is or isn't doing.
>>
>
> Okay, How about doing as below ensuring get_sync always
> and forbid runtime to avoid clock_gating if wakeup is not set.
>

This is better, I'm not crazy about that either.

Consider a platform that doesn't have wakeups, but the UARTs are not
used (at least initially.)   That means on power up, all the UARTs are
left enabled to consume power even when they're not used.

Kevin

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

* [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver
  2011-10-14 17:04           ` Kevin Hilman
@ 2011-10-14 18:29             ` Govindraj
  0 siblings, 0 replies; 41+ messages in thread
From: Govindraj @ 2011-10-14 18:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 14, 2011 at 10:34 PM, Kevin Hilman <khilman@ti.com> wrote:
> Govindraj <govindraj.ti@gmail.com> writes:
>
>> On Fri, Oct 14, 2011 at 2:52 AM, Kevin Hilman <khilman@ti.com> wrote:
>>> Govindraj <govindraj.ti@gmail.com> writes:
>>>
>>>> On Thu, Oct 13, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>>>>> "Govindraj.R" <govindraj.raja@ti.com> writes:
>>>>>
>>>>> [...]
>>>>>
>>>>>> Use device_may_wakeup to check whether uart has wakeup capabilities
>>>>>> and then enable uart runtime usage for the uart.
>>>>>
>>>>> Curious about what happens when device_may_wakeup() is not set during
>>>>> device init.
>>>>>
>>>>> [...]
>>>>>
>>>>>> @@ -1305,6 +1363,16 @@ 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_irq_safe(&pdev->dev);
>>>>>> + ? ? if (device_may_wakeup(&pdev->dev)) {
>>>>>> + ? ? ? ? ? ? pm_runtime_enable(&pdev->dev);
>>>>>
>>>>> So if device_may_wakeup() is false, runtime PM is not enabled, then...
>>>>>
>>>>>> + ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev);
>>>>>
>>>>> ...this get doesn't happen, and the first register access causes a crash.
>>>>
>>>> Actually no crash, clocks will left enabled from boot up (hwmod_no_reset/idle)
>>>> that are idled and enabled back here.
>>>>
>>>> Since hwmod_idle is binded here later ([PATCH v6 15/16]),
>>>
>>> IMO, That's not a very maintainable solution.
>>>
>>> What happens when when someone fixes serial.c to only set
>>> HWMOD_INIT_NO_IDLE on the console UART? ?or if we fix things so we don't
>>> need INIT_NO_IDLE anymore? ?Then this will crash.
>>>
>>> Driver code should not make assumptions like this about what device init
>>> code is or isn't doing.
>>>
>>
>> Okay, How about doing as below ensuring get_sync always
>> and forbid runtime to avoid clock_gating if wakeup is not set.
>>
>
> This is better, I'm not crazy about that either.
>
> Consider a platform that doesn't have wakeups, but the UARTs are not
> used (at least initially.) ? That means on power up, all the UARTs are
> left enabled to consume power even when they're not used.
>

okay, the right place would be serial_omap_pm
to do add runtime forbid.

whenever the uart port is used it will call serial_omap_pm
with state param assigned value zero from serial_core layer
for open system call from user space.

Also when uart port is closed it will shutdown where we can add runtime_allow.
So for uart ports not wakeup capable keep uart clocks on until
used and once port is shutdown cut uart clocks.


diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 8a955fc..2c43744 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -608,6 +608,10 @@ static void serial_omap_shutdown(struct uart_port *port)
                        up->uart_dma.rx_buf_dma_phys);
                up->uart_dma.rx_buf = NULL;
        }
+
+       if (!device_may_wakeup(&up->pdev->dev))
+               pm_runtime_allow(&up->pdev->dev);
+
        pm_runtime_put(&up->pdev->dev);
        free_irq(up->port.irq, up);
 }
@@ -893,6 +897,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 && !device_may_wakeup(&up->pdev->dev))
+               pm_runtime_forbid(&up->pdev->dev);
+
        pm_runtime_put(&up->pdev->dev);
 }


--
Thanks,
Govindraj.R

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

end of thread, other threads:[~2011-10-14 18:29 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-30 11:01 [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Govindraj.R
2011-09-30 11:01 ` [PATCH v6 02/16] OMAP2+: hwmod: Add API to check IO PAD wakeup status Govindraj.R
2011-10-01 14:33   ` Rajendra Nayak
2011-10-03  5:00     ` Govindraj
2011-10-03  5:23       ` Rajendra Nayak
2011-10-03  5:56         ` Govindraj
2011-10-10 22:24           ` Kevin Hilman
2011-10-11  6:17             ` Govindraj
2011-09-30 11:01 ` [PATCH v6 03/16] OMAP2+: UART: cleanup + remove uart pm specific API Govindraj.R
2011-09-30 11:01 ` [PATCH v6 04/16] OMAP2+: UART: cleanup 8250 console driver support Govindraj.R
2011-10-04 21:42   ` Kevin Hilman
2011-10-05  6:54     ` Govindraj
2011-10-05 18:42       ` Kevin Hilman
2011-10-06  8:16         ` Govindraj
2011-09-30 11:01 ` [PATCH v6 05/16] OMAP2+: UART: Cleanup part of clock gating mechanism for uart Govindraj.R
2011-10-10 22:30   ` Kevin Hilman
2011-10-11  6:45     ` Govindraj
2011-09-30 11:01 ` [PATCH v6 06/16] OMAP2+: UART: Remove certain feilds from omap_uart_state struct Govindraj.R
2011-10-10 23:31   ` Kevin Hilman
2011-10-12 10:25     ` Govindraj
2011-09-30 11:01 ` [PATCH v6 07/16] OMAP2+: UART: Add default mux for all uarts Govindraj.R
2011-10-05 19:04   ` Kevin Hilman
2011-10-06  8:21     ` Govindraj
2011-09-30 11:01 ` [PATCH v6 08/16] OMAP2+: UART: Store certain reg values to port structure Govindraj.R
2011-10-10 23:58   ` Kevin Hilman
2011-10-11 13:21     ` Govindraj
2011-09-30 11:01 ` [PATCH v6 09/16] OMAP2+: UART: Add runtime pm support for omap-serial driver Govindraj.R
2011-10-10 23:42   ` Kevin Hilman
2011-10-12 10:37     ` Govindraj
2011-10-10 23:56   ` Kevin Hilman
2011-10-12 10:35     ` Govindraj
2011-10-13  0:06   ` Kevin Hilman
2011-10-13  1:28     ` Govindraj
2011-10-13 21:22       ` Kevin Hilman
2011-10-14 12:32         ` Govindraj
2011-10-14 17:04           ` Kevin Hilman
2011-10-14 18:29             ` Govindraj
2011-10-01 13:41 ` [PATCH v6 01/16] OMAP2+: hwmod: Add API to enable IO ring wakeup Rajendra Nayak
2011-10-03 15:10   ` Vishwanath Sripathy
2011-10-04 21:03   ` Kevin Hilman
2011-10-05 11:57     ` Rajendra Nayak

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).