public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/4] PM: Workaround for taking care of gpio clocks
  2008-06-30  8:50 [PATCH 0/6] 34XX: PM: Workarounds to get omap3 to retention 4th Högander Jouni
@ 2008-08-15  6:18 ` Jouni Hogander
  0 siblings, 0 replies; 19+ messages in thread
From: Jouni Hogander @ 2008-08-15  6:18 UTC (permalink / raw)
  To: linux-omap

In omap3 gpios 2-6 are in per domain. Functional clocks for these
should be disabled. This patch is needed until gpio driver disables
gpio clocks.

GPIO modules in PER domain are not able to act as a wake up source if
PER domain is in retention. PER domain sleep transition before MPU is
prevented by leaving icks active. PER domain still enters retention
together with MPU. When this happens IOPAD wake up mechanism is used
for gpios.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
 arch/arm/mach-omap2/pm34xx.c |   54 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 5c37cbd..d7278d3 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -53,6 +53,36 @@ static void (*saved_idle)(void);
 
 static struct powerdomain *mpu_pwrdm;
 
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+#define NUM_OF_PERGPIOS 5
+static struct clk *gpio_fcks[NUM_OF_PERGPIOS];
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void per_gpio_clk_enable(void)
+{
+	int i;
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
+		clk_enable(gpio_fcks[i-1]);
+}
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void per_gpio_clk_disable(void)
+{
+	int i;
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
+		clk_disable(gpio_fcks[i-1]);
+}
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void gpio_fclk_mask(u32 *fclk)
+{
+	*fclk &= ~(0x1f << 13);
+}
+
 /* PRCM Interrupt Handler for wakeups */
 static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 {
@@ -169,8 +199,18 @@ static void omap_sram_idle(void)
 
 	omap2_gpio_prepare_for_retention();
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	if (clocks_off_while_idle)
+		per_gpio_clk_disable();
+
 	_omap_sram_idle(NULL, save_state);
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	if (clocks_off_while_idle)
+		per_gpio_clk_enable();
+
 	omap2_gpio_resume_after_retention();
 }
 
@@ -200,6 +240,10 @@ static int omap3_fclks_active(void)
 				  CM_FCLKEN);
 	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
 				  CM_FCLKEN);
+
+	if (clocks_off_while_idle)
+		gpio_fclk_mask(&fck_per);
+
 	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
 	    fck_cam | fck_per | fck_usbhost)
 		return 1;
@@ -418,7 +462,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm)
 int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst;
-	int ret;
+	char clk_name[11];
+	int ret, i;
 
 	printk(KERN_ERR "Power Management for TI OMAP3.\n");
 
@@ -454,6 +499,13 @@ int __init omap3_pm_init(void)
 
 	pm_idle = omap3_pm_idle;
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) {
+		sprintf(clk_name, "gpio%d_fck", i + 1);
+		gpio_fcks[i-1] = clk_get(NULL, clk_name);
+	}
+
 err1:
 	return ret;
 err2:
-- 
1.5.5


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

* [PATCH 0/4] Refreshed PM workaround patches 2.
@ 2008-08-15  7:44 Högander Jouni
  2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Högander Jouni @ 2008-08-15  7:44 UTC (permalink / raw)
  To: linux-omap

Refreshed PM workaround set without coding style errors and 24xx build
fixed. Here are instructions how to test them:

To get Omap into retention, this patch set still depends on:
1. ARCH: OMAP: MUSB: Do not block sleep (Felipe Balbi)

Test:
1. Apply dependency patch and workaround set on top of them

2. Enable disabling/enabling of gpio2-6 and uart clocks on idle:
   $ echo 1 > /sys/power/clocks_off_while_idle

3. Try out static suspend:
   $ echo mem > /sys/power/state
   Wake up from suspend by entering character to serial console. This
   should print out:
   "Successfully put all powerdomains to target state"

4. Try out dynamic sleep:
   $ echo 1 > /sys/power/sleep_while_idle
   On Omap3430 SDP board VCORE_EN led can be used as an indicator. If
   it starts to blink after a while then Omap enters retention on
   idle. To make this work also display needs to be blanked.

-- 
Jouni Högander

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

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

* [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
@ 2008-08-15  7:47 ` Jouni Hogander
  2008-08-20 11:35   ` Tony Lindgren
  2008-08-21  8:17   ` Rajendra Nayak
  2008-08-15  7:47 ` [PATCH 2/4] PM: Workaround for taking care of gpio clocks Jouni Hogander
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 19+ messages in thread
From: Jouni Hogander @ 2008-08-15  7:47 UTC (permalink / raw)
  To: linux-omap

This workaround shouldn't be needed when all drivers are configuring
their sysconfig registers properly and using their clocks properly.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
 arch/arm/mach-omap2/pm34xx.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index a57cf41..f30fa9e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -174,10 +174,47 @@ static void omap_sram_idle(void)
 	omap2_gpio_resume_after_retention();
 }
 
+/* XXX This workaround shouldn't be needed when all drivers are configuring
+ * their sysconfig registers properly and using their clocks
+ * properly. */
+static int omap3_fclks_active(void)
+{
+	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
+		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
+
+	fck_core1 = cm_read_mod_reg(CORE_MOD,
+				    CM_FCLKEN1);
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		fck_core3 = cm_read_mod_reg(CORE_MOD,
+					    OMAP3430ES2_CM_FCLKEN3);
+		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+					  CM_FCLKEN);
+		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+					      CM_FCLKEN);
+	} else
+		fck_sgx = cm_read_mod_reg(GFX_MOD,
+					  OMAP3430ES2_CM_FCLKEN3);
+	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
+				  CM_FCLKEN);
+	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
+				  CM_FCLKEN);
+	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
+				  CM_FCLKEN);
+	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
+	    fck_cam | fck_per | fck_usbhost)
+		return 1;
+	return 0;
+}
+
 static int omap3_can_sleep(void)
 {
 	if (!enable_dyn_sleep)
 		return 0;
+	/* XXX This workaround shouldn't be needed when all drivers are
+	 * configuring their sysconfig registers properly and using their
+	 * clocks properly. */
+	if (omap3_fclks_active())
+		return 0;
 	if (atomic_read(&sleep_block) > 0)
 		return 0;
 	return 1;
-- 
1.5.5


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

* [PATCH 2/4] PM: Workaround for taking care of gpio clocks
  2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
  2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
@ 2008-08-15  7:47 ` Jouni Hogander
  2008-08-20 11:37   ` Tony Lindgren
  2008-08-15  7:47 ` [PATCH 3/4] Added sleep support to UART Jouni Hogander
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 19+ messages in thread
From: Jouni Hogander @ 2008-08-15  7:47 UTC (permalink / raw)
  To: linux-omap

In omap3 gpios 2-6 are in per domain. Functional clocks for these
should be disabled. This patch is needed until gpio driver disables
gpio clocks.

GPIO modules in PER domain are not able to act as a wake up source if
PER domain is in retention. PER domain sleep transition before MPU is
prevented by leaving icks active. PER domain still enters retention
together with MPU. When this happens IOPAD wake up mechanism is used
for gpios.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
 arch/arm/mach-omap2/pm34xx.c |   54 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index f30fa9e..7d5d461 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -53,6 +53,36 @@ static void (*saved_idle)(void);
 
 static struct powerdomain *mpu_pwrdm;
 
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+#define NUM_OF_PERGPIOS 5
+static struct clk *gpio_fcks[NUM_OF_PERGPIOS];
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void per_gpio_clk_enable(void)
+{
+	int i;
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
+		clk_enable(gpio_fcks[i-1]);
+}
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void per_gpio_clk_disable(void)
+{
+	int i;
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
+		clk_disable(gpio_fcks[i-1]);
+}
+
+/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+ * handles fcks correctly */
+static void gpio_fclk_mask(u32 *fclk)
+{
+	*fclk &= ~(0x1f << 13);
+}
+
 /* PRCM Interrupt Handler for wakeups */
 static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 {
@@ -169,8 +199,18 @@ static void omap_sram_idle(void)
 
 	omap2_gpio_prepare_for_retention();
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	if (clocks_off_while_idle)
+		per_gpio_clk_disable();
+
 	_omap_sram_idle(NULL, save_state);
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	if (clocks_off_while_idle)
+		per_gpio_clk_enable();
+
 	omap2_gpio_resume_after_retention();
 }
 
@@ -200,6 +240,10 @@ static int omap3_fclks_active(void)
 				  CM_FCLKEN);
 	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
 				  CM_FCLKEN);
+
+	if (clocks_off_while_idle)
+		gpio_fclk_mask(&fck_per);
+
 	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
 	    fck_cam | fck_per | fck_usbhost)
 		return 1;
@@ -418,7 +462,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm)
 int __init omap3_pm_init(void)
 {
 	struct power_state *pwrst;
-	int ret;
+	char clk_name[11];
+	int ret, i;
 
 	printk(KERN_ERR "Power Management for TI OMAP3.\n");
 
@@ -454,6 +499,13 @@ int __init omap3_pm_init(void)
 
 	pm_idle = omap3_pm_idle;
 
+	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
+	 * handles fcks correctly */
+	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) {
+		sprintf(clk_name, "gpio%d_fck", i + 1);
+		gpio_fcks[i-1] = clk_get(NULL, clk_name);
+	}
+
 err1:
 	return ret;
 err2:
-- 
1.5.5


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

* [PATCH 3/4] Added sleep support to UART
  2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
  2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
  2008-08-15  7:47 ` [PATCH 2/4] PM: Workaround for taking care of gpio clocks Jouni Hogander
@ 2008-08-15  7:47 ` Jouni Hogander
  2008-08-20 11:40   ` Tony Lindgren
  2008-08-15  7:47 ` [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
  2008-08-15  7:49 ` [PATCH 0/4] Refreshed PM workaround patches 2 Felipe Balbi
  4 siblings, 1 reply; 19+ messages in thread
From: Jouni Hogander @ 2008-08-15  7:47 UTC (permalink / raw)
  To: linux-omap; +Cc: Tero Kristo

From: Tero Kristo <tero.kristo@nokia.com>

UART usage (e.g. serial console) now denies sleep for 5 seconds. This
makes it possible to use serial console when dynamic idle is
enabled. Write 1 to /sys/power/clocks_off_while_sleep to enable uart
clock disable on idle. Without this omap won't enter retention.

Also moved code from pm-debug.c to serial.c, and made pm24xx.c use
this new implementation.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
 arch/arm/mach-omap2/pm-debug.c           |  132 --------------------------
 arch/arm/mach-omap2/pm.h                 |    7 --
 arch/arm/mach-omap2/pm24xx.c             |   57 +++++++-----
 arch/arm/mach-omap2/pm34xx.c             |   27 ++++--
 arch/arm/mach-omap2/serial.c             |  148 ++++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/mach/common.h |    3 +
 6 files changed, 204 insertions(+), 170 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 1b14bcf..b00f5f4 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -37,138 +37,6 @@
 #ifdef CONFIG_PM_DEBUG
 int omap2_pm_debug = 0;
 
-static int serial_console_clock_disabled;
-static int serial_console_uart;
-static unsigned int serial_console_next_disable;
-
-static struct clk *console_iclk, *console_fclk;
-
-static void serial_console_kick(void)
-{
-	serial_console_next_disable = omap2_read_32k_sync_counter();
-	/* Keep the clocks on for 4 secs */
-	serial_console_next_disable += 4 * 32768;
-}
-
-static void serial_wait_tx(void)
-{
-	static const unsigned long uart_bases[3] = {
-		0x4806a000, 0x4806c000, 0x4806e000
-	};
-	unsigned long lsr_reg;
-	int looped = 0;
-
-	/* Wait for TX FIFO and THR to get empty */
-	lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2));
-	while ((__raw_readb(lsr_reg) & 0x60) != 0x60)
-		looped = 1;
-	if (looped)
-		serial_console_kick();
-}
-
-u32 omap2_read_32k_sync_counter(void)
-{
-        return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010);
-}
-
-void serial_console_fclk_mask(u32 *f1, u32 *f2)
-{
-	switch (serial_console_uart)  {
-	case 1:
-		*f1 &= ~(1 << 21);
-		break;
-	case 2:
-		*f1 &= ~(1 << 22);
-		break;
-	case 3:
-		*f2 &= ~(1 << 2);
-		break;
-	}
-}
-
-void serial_console_sleep(int enable)
-{
-	if (console_iclk == NULL || console_fclk == NULL)
-		return;
-
-	if (enable) {
-		BUG_ON(serial_console_clock_disabled);
-		if (clk_get_usecount(console_fclk) == 0)
-			return;
-		if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0)
-			return;
-		serial_wait_tx();
-		clk_disable(console_iclk);
-		clk_disable(console_fclk);
-		serial_console_clock_disabled = 1;
-	} else {
-		int serial_wakeup = 0;
-		u32 l;
-
-		switch (serial_console_uart)  {
-		case 1:
-			l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
-			if (l & OMAP24XX_ST_UART1)
-				serial_wakeup = 1;
-			break;
-		case 2:
-			l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
-			if (l & OMAP24XX_ST_UART2)
-				serial_wakeup = 1;
-			break;
-		case 3:
-			l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2);
-			if (l & OMAP24XX_ST_UART3)
-				serial_wakeup = 1;
-			break;
-		}
-		if (serial_wakeup)
-			serial_console_kick();
-		if (!serial_console_clock_disabled)
-			return;
-		clk_enable(console_iclk);
-		clk_enable(console_fclk);
-		serial_console_clock_disabled = 0;
-	}
-}
-
-void pm_init_serial_console(void)
-{
-	const struct omap_serial_console_config *conf;
-	char name[16];
-
-	conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
-			       struct omap_serial_console_config);
-	if (conf == NULL)
-		return;
-	if (conf->console_uart > 3 || conf->console_uart < 1)
-		return;
-	serial_console_uart = conf->console_uart;
-	sprintf(name, "uart%d_fck", conf->console_uart);
-	console_fclk = clk_get(NULL, name);
-	if (IS_ERR(console_fclk))
-		console_fclk = NULL;
-	name[6] = 'i';
-	console_iclk = clk_get(NULL, name);
-	if (IS_ERR(console_fclk))
-		console_iclk = NULL;
-	if (console_fclk == NULL || console_iclk == NULL) {
-		serial_console_uart = 0;
-		return;
-	}
-	switch (serial_console_uart) {
-	case 1:
-		prm_set_mod_reg_bits(OMAP24XX_ST_UART1, CORE_MOD, PM_WKEN1);
-		break;
-	case 2:
-		prm_set_mod_reg_bits(OMAP24XX_ST_UART2, CORE_MOD, PM_WKEN1);
-		break;
-	case 3:
-		prm_set_mod_reg_bits(OMAP24XX_ST_UART3, CORE_MOD, OMAP24XX_PM_WKEN2);
-		break;
-	}
-}
-
 #define DUMP_PRM_MOD_REG(mod, reg)    \
 	regs[reg_count].name = #mod "." #reg; \
 	regs[reg_count++].val = prm_read_mod_reg(mod, reg)
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 68c9278..fe3f764 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -25,16 +25,9 @@ extern void omap2_allow_sleep(void);
 
 
 #ifdef CONFIG_PM_DEBUG
-extern u32 omap2_read_32k_sync_counter(void);
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
-extern void serial_console_fclk_mask(u32 *f1, u32 *f2);
-extern void pm_init_serial_console(void);
-extern void serial_console_sleep(int enable);
 extern int omap2_pm_debug;
 #else
-#define omap2_read_32k_sync_counter()		0
-#define serial_console_sleep(enable)		do {} while (0);
-#define pm_init_serial_console()		do {} while (0);
 #define omap2_pm_dump(mode, resume, us)		do {} while (0);
 #define serial_console_fclk_mask(f1, f2)		do {} while (0);
 #define omap2_pm_debug				0
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 5c76120..d766a35 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -44,6 +44,7 @@
 #include <mach/mux.h>
 #include <mach/dma.h>
 #include <mach/board.h>
+#include <mach/common.h>
 
 #include "prm.h"
 #include "prm-regbits-24xx.h"
@@ -73,7 +74,10 @@ static int omap2_fclks_active(void)
 
 	f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
 	f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
-	serial_console_fclk_mask(&f1, &f2);
+
+	if (clocks_off_while_idle)
+		omap_serial_fclk_mask(&f1, &f2);
+
 	if (f1 | f2)
 		return 1;
 	return 0;
@@ -81,7 +85,8 @@ static int omap2_fclks_active(void)
 
 static void omap2_enter_full_retention(void)
 {
-	u32 l, sleep_time = 0;
+	u32 l = 0;
+	struct timespec sleep_time;
 
 	/* There is 1 reference hold for all children of the oscillator
 	 * clock, the following will remove it. If no one else uses the
@@ -111,28 +116,33 @@ static void omap2_enter_full_retention(void)
 
 	if (omap2_pm_debug) {
 		omap2_pm_dump(0, 0, 0);
-		sleep_time = omap2_read_32k_sync_counter();
+		getnstimeofday(&sleep_time);
 	}
 
+	if (clocks_off_while_idle)
+		omap_serial_enable_clocks(0);
+
 	/* One last check for pending IRQs to avoid extra latency due
 	 * to sleeping unnecessarily. */
 	if (omap_irq_pending())
 		goto no_sleep;
 
-	serial_console_sleep(1);
 	/* Jump to SRAM suspend code */
 	omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
 no_sleep:
-	serial_console_sleep(0);
+	omap_serial_check_wakeup();
+	if (clocks_off_while_idle)
+		omap_serial_enable_clocks(1);
 
 	if (omap2_pm_debug) {
-		unsigned long long tmp;
-		u32 resume_time;
-
-		resume_time = omap2_read_32k_sync_counter();
-		tmp = resume_time - sleep_time;
-		tmp *= 1000000;
-		omap2_pm_dump(0, 1, tmp / 32768);
+		struct timespec t;
+		struct timespec ts_delta;
+
+		getnstimeofday(&t);
+		ts_delta = timespec_sub(t, sleep_time);
+		omap2_pm_dump(0, 1,
+			      div_s64(timespec_to_ns(&ts_delta),
+				      NSEC_PER_USEC));
 	}
 	omap2_gpio_resume_after_retention();
 
@@ -193,7 +203,7 @@ static int omap2_allow_mpu_retention(void)
 
 static void omap2_enter_mpu_retention(void)
 {
-	u32 sleep_time = 0;
+	struct timespec sleep_time;
 	int only_idle = 0;
 
 	/* Putting MPU into the WFI state while a transfer is active
@@ -222,19 +232,20 @@ static void omap2_enter_mpu_retention(void)
 
 	if (omap2_pm_debug) {
 		omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
-		sleep_time = omap2_read_32k_sync_counter();
+		getnstimeofday(&sleep_time);
 	}
 
 	omap2_sram_idle();
 
 	if (omap2_pm_debug) {
-		unsigned long long tmp;
-		u32 resume_time;
-
-		resume_time = omap2_read_32k_sync_counter();
-		tmp = resume_time - sleep_time;
-		tmp *= 1000000;
-		omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768);
+		struct timespec t;
+		struct timespec ts_delta;
+
+		getnstimeofday(&t);
+		ts_delta = timespec_sub(t, sleep_time);
+		omap2_pm_dump(only_idle ? 2 : 1, 1,
+			      div_s64(timespec_to_ns(&ts_delta),
+				      NSEC_PER_USEC));
 	}
 }
 
@@ -250,6 +261,8 @@ static int omap2_can_sleep(void)
 		return 0;
 	if (omap_dma_running())
 		return 0;
+	if (!omap_serial_can_sleep())
+		return 0;
 
 	return 1;
 }
@@ -517,8 +530,6 @@ int __init omap2_pm_init(void)
 
 	prcm_setup_regs();
 
-	pm_init_serial_console();
-
 	/* Hack to prevent MPU retention when STI console is enabled. */
 	{
 		const struct omap_sti_console_config *sti;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7d5d461..29b4eee 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -29,6 +29,7 @@
 #include <mach/pm.h>
 #include <mach/clockdomain.h>
 #include <mach/powerdomain.h>
+#include <mach/common.h>
 
 #include "cm.h"
 #include "cm-regbits-34xx.h"
@@ -89,6 +90,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 	u32 wkst, irqstatus_mpu;
 	u32 fclk, iclk;
 
+	/* Check if we woke up to serial console activity */
+	omap_serial_check_wakeup();
+
 	/* WKUP */
 	wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
 	if (wkst) {
@@ -198,18 +202,21 @@ static void omap_sram_idle(void)
 	}
 
 	omap2_gpio_prepare_for_retention();
-
-	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
-	 * handles fcks correctly */
-	if (clocks_off_while_idle)
+	if (clocks_off_while_idle) {
+		omap_serial_enable_clocks(0);
+		/* XXX This is for gpio fclk hack. Will be removed as
+		 * gpio driver * handles fcks correctly */
 		per_gpio_clk_disable();
+	}
 
 	_omap_sram_idle(NULL, save_state);
 
-	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
-	 * handles fcks correctly */
-	if (clocks_off_while_idle)
+	if (clocks_off_while_idle) {
+		omap_serial_enable_clocks(1);
+		/* XXX This is for gpio fclk hack. Will be removed as
+		 * gpio driver * handles fcks correctly */
 		per_gpio_clk_enable();
+	}
 
 	omap2_gpio_resume_after_retention();
 }
@@ -241,8 +248,10 @@ static int omap3_fclks_active(void)
 	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
 				  CM_FCLKEN);
 
-	if (clocks_off_while_idle)
+	if (clocks_off_while_idle) {
 		gpio_fclk_mask(&fck_per);
+		omap_serial_fclk_mask(&fck_core1, &fck_per);
+	}
 
 	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
 	    fck_cam | fck_per | fck_usbhost)
@@ -261,6 +270,8 @@ static int omap3_can_sleep(void)
 		return 0;
 	if (atomic_read(&sleep_block) > 0)
 		return 0;
+	if (!omap_serial_can_sleep())
+		return 0;
 	return 1;
 }
 
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index d9fca6f..f55ab25 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -22,9 +22,66 @@
 
 #include <mach/common.h>
 #include <mach/board.h>
+#include <mach/clock.h>
+#include <mach/control.h>
+
+#include "prm.h"
+#include "pm.h"
+
+#define SERIAL_AWAKE_TIME 5
 
 static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
 static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
+static struct timespec omap_serial_next_sleep;
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static const u32 omap2_uart_wk_st[OMAP_MAX_NR_PORTS] = {
+	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
+	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
+	OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKST2)
+};
+static const u32 omap2_uart_wk_en[OMAP_MAX_NR_PORTS] = {
+	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+	OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKEN2),
+};
+static const u32 omap2_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
+	OMAP24XX_ST_UART1, OMAP24XX_ST_UART2, OMAP24XX_ST_UART3
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static const u32 omap3_uart_wk_st[OMAP_MAX_NR_PORTS] = {
+	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
+	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
+	OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKST1)
+};
+static const u32 omap3_uart_wk_en[OMAP_MAX_NR_PORTS] = {
+	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
+	OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKEN1)
+};
+static const u32 omap3_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
+	OMAP3430_ST_UART1, OMAP3430_ST_UART2, OMAP3430_ST_UART3
+};
+#endif
+
+static const u32 *omap_uart_wk_st;
+static const u32 *omap_uart_wk_en;
+static const u32 *omap_uart_wk_bit;
+
+/* UART padconfig registers, these may differ if non-default padconfig
+   is used */
+#define CONTROL_PADCONF_UART1_RX 0x182
+#define CONTROL_PADCONF_UART2_RX 0x17A
+#define CONTROL_PADCONF_UART3_RX 0x19E
+#define PADCONF_WAKEUP_ST 0x8000
+
+static const u32 omap34xx_uart_padconf[OMAP_MAX_NR_PORTS] = {
+	CONTROL_PADCONF_UART1_RX,
+	CONTROL_PADCONF_UART2_RX,
+	CONTROL_PADCONF_UART3_RX
+};
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
@@ -83,6 +140,13 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
 	serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
 }
 
+static void omap_serial_kick(void)
+{
+	getnstimeofday(&omap_serial_next_sleep);
+	timespec_add_ns(&omap_serial_next_sleep, (s64)SERIAL_AWAKE_TIME *
+		NSEC_PER_SEC);
+}
+
 void omap_serial_enable_clocks(int enable)
 {
 	int i;
@@ -99,6 +163,67 @@ void omap_serial_enable_clocks(int enable)
 	}
 }
 
+void omap_serial_fclk_mask(u32 *f1, u32 *f2)
+{
+	if (uart_ick[0])
+		*f1 &= ~(1 << uart_fck[0]->enable_bit);
+	if (uart_ick[1])
+		*f1 &= ~(1 << uart_fck[1]->enable_bit);
+	if (uart_ick[2])
+		*f2 &= ~(1 << uart_fck[2]->enable_bit);
+}
+
+void omap_serial_check_wakeup(void)
+{
+	int i;
+
+
+	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+		if (!uart_ick[i])
+			continue;
+
+		if (cpu_is_omap34xx())
+			if (omap_ctrl_readw(omap34xx_uart_padconf[i]) &
+			    PADCONF_WAKEUP_ST) {
+				omap_serial_kick();
+				return;
+			}
+
+		if (__raw_readl(omap_uart_wk_st[i]) &
+		    omap_uart_wk_bit[i]) {
+			omap_serial_kick();
+			return;
+		}
+	}
+}
+
+int omap_serial_can_sleep(void)
+{
+	int i;
+	struct timespec t;
+
+	struct plat_serial8250_port *p = serial_platform_data;
+
+	getnstimeofday(&t);
+
+	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+		if (!uart_ick[i])
+			continue;
+		/* Check if we have data in the transmit buffer */
+		if ((serial_read_reg(p + i, UART_LSR) &
+			(UART_LSR_TEMT|UART_LSR_THRE))
+			!= (UART_LSR_TEMT|UART_LSR_THRE)) {
+				omap_serial_kick();
+				return 0;
+		}
+	}
+
+	if (timespec_compare(&t, &omap_serial_next_sleep) < 0)
+		return 0;
+
+	return 1;
+}
+
 void __init omap_serial_init(void)
 {
 	int i;
@@ -116,8 +241,25 @@ void __init omap_serial_init(void)
 	if (info == NULL)
 		return;
 
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap242x()) {
+		omap_uart_wk_st = omap2_uart_wk_st;
+		omap_uart_wk_en = omap2_uart_wk_en;
+		omap_uart_wk_bit = omap2_uart_wk_bit;
+	}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+	if (cpu_is_omap34xx()) {
+		omap_uart_wk_st = omap3_uart_wk_st;
+		omap_uart_wk_en = omap3_uart_wk_en;
+		omap_uart_wk_bit = omap3_uart_wk_bit;
+	}
+#endif
+
 	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
 		struct plat_serial8250_port *p = serial_platform_data + i;
+		u32 v;
 
 		if (!(info->enabled_uarts & (1 << i))) {
 			p->membase = NULL;
@@ -142,7 +284,13 @@ void __init omap_serial_init(void)
 			clk_enable(uart_fck[i]);
 
 		omap_serial_reset(p);
+
+		v = __raw_readl(omap_uart_wk_en[i]);
+		v |= omap_uart_wk_bit[i];
+		__raw_writel(v, omap_uart_wk_en[i]);
 	}
+
+	omap_serial_kick();
 }
 
 static struct platform_device serial_device = {
diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h
index 5f46249..003c08e 100644
--- a/arch/arm/plat-omap/include/mach/common.h
+++ b/arch/arm/plat-omap/include/mach/common.h
@@ -35,6 +35,9 @@ extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 extern void omap_serial_init(void);
 extern void omap_serial_enable_clocks(int enable);
+extern int omap_serial_can_sleep(void);
+extern void omap_serial_fclk_mask(u32 *f1, u32 *f2);
+void omap_serial_check_wakeup(void);
 #ifdef CONFIG_I2C_OMAP
 extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
 				 struct i2c_board_info const *info,
-- 
1.5.5


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

* [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls
  2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
                   ` (2 preceding siblings ...)
  2008-08-15  7:47 ` [PATCH 3/4] Added sleep support to UART Jouni Hogander
@ 2008-08-15  7:47 ` Jouni Hogander
  2008-08-20 11:51   ` Tony Lindgren
  2008-08-15  7:49 ` [PATCH 0/4] Refreshed PM workaround patches 2 Felipe Balbi
  4 siblings, 1 reply; 19+ messages in thread
From: Jouni Hogander @ 2008-08-15  7:47 UTC (permalink / raw)
  To: linux-omap; +Cc: ext Jouni Hogander

From: ext Jouni Hogander <jouni.hogander@nokia.com>

This workaround enables autoidle for interface clocks and plls. Also
automatic control of external oscillator through sys_clkreq is
enabled.

Proper fix to this is to generalize omap3_dpll_allow_idle,
omap3_dpll_deny_idle, omap3_dpll_autoidle_read and call it for each
clock on init.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
 arch/arm/mach-omap2/pm34xx.c |  120 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 29b4eee..cc2ab70 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -438,6 +438,126 @@ static void __init prcm_setup_regs(void)
 	} else
 		prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
 
+	/* XXX Enable interface clock autoidle for all modules. This
+	 * should be done by clockfw */
+	cm_write_mod_reg(
+		OMAP3430ES2_AUTO_MMC3 |
+		OMAP3430ES2_AUTO_ICR |
+		OMAP3430_AUTO_AES2 |
+		OMAP3430_AUTO_SHA12 |
+		OMAP3430_AUTO_DES2 |
+		OMAP3430_AUTO_MMC2 |
+		OMAP3430_AUTO_MMC1 |
+		OMAP3430_AUTO_MSPRO |
+		OMAP3430_AUTO_HDQ |
+		OMAP3430_AUTO_MCSPI4 |
+		OMAP3430_AUTO_MCSPI3 |
+		OMAP3430_AUTO_MCSPI2 |
+		OMAP3430_AUTO_MCSPI1 |
+		OMAP3430_AUTO_I2C3 |
+		OMAP3430_AUTO_I2C2 |
+		OMAP3430_AUTO_I2C1 |
+		OMAP3430_AUTO_UART2 |
+		OMAP3430_AUTO_UART1 |
+		OMAP3430_AUTO_GPT11 |
+		OMAP3430_AUTO_GPT10 |
+		OMAP3430_AUTO_MCBSP5 |
+		OMAP3430_AUTO_MCBSP1 |
+		OMAP3430ES1_AUTO_FAC | /* This is es1 only */
+		OMAP3430_AUTO_MAILBOXES |
+		OMAP3430_AUTO_OMAPCTRL |
+		OMAP3430ES1_AUTO_FSHOSTUSB |
+		OMAP3430_AUTO_HSOTGUSB |
+		OMAP3430ES1_AUTO_D2D | /* This is es1 only */
+		OMAP3430_AUTO_SSI,
+		CORE_MOD, CM_AUTOIDLE1);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_PKA |
+		OMAP3430_AUTO_AES1 |
+		OMAP3430_AUTO_RNG |
+		OMAP3430_AUTO_SHA11 |
+		OMAP3430_AUTO_DES1,
+		CORE_MOD, CM_AUTOIDLE2);
+
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		cm_write_mod_reg(
+			OMAP3430ES2_AUTO_USBTLL,
+			CORE_MOD, CM_AUTOIDLE3);
+	}
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_WDT2 |
+		OMAP3430_AUTO_WDT1 |
+		OMAP3430_AUTO_GPIO1 |
+		OMAP3430_AUTO_32KSYNC |
+		OMAP3430_AUTO_GPT12 |
+		OMAP3430_AUTO_GPT1 ,
+		WKUP_MOD, CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_DSS,
+		OMAP3430_DSS_MOD,
+		CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_CAM,
+		OMAP3430_CAM_MOD,
+		CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_GPIO6 |
+		OMAP3430_AUTO_GPIO5 |
+		OMAP3430_AUTO_GPIO4 |
+		OMAP3430_AUTO_GPIO3 |
+		OMAP3430_AUTO_GPIO2 |
+		OMAP3430_AUTO_WDT3 |
+		OMAP3430_AUTO_UART3 |
+		OMAP3430_AUTO_GPT9 |
+		OMAP3430_AUTO_GPT8 |
+		OMAP3430_AUTO_GPT7 |
+		OMAP3430_AUTO_GPT6 |
+		OMAP3430_AUTO_GPT5 |
+		OMAP3430_AUTO_GPT4 |
+		OMAP3430_AUTO_GPT3 |
+		OMAP3430_AUTO_GPT2 |
+		OMAP3430_AUTO_MCBSP4 |
+		OMAP3430_AUTO_MCBSP3 |
+		OMAP3430_AUTO_MCBSP2,
+		OMAP3430_PER_MOD,
+		CM_AUTOIDLE);
+
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		cm_write_mod_reg(
+			OMAP3430ES2_AUTO_USBHOST,
+			OMAP3430ES2_USBHOST_MOD,
+			CM_AUTOIDLE);
+	}
+
+	/* XXX Set all plls to autoidle. This is needed until autoidle is
+	 * enabled by clockfw */
+	cm_write_mod_reg(1 << OMAP3430_CLKTRCTRL_IVA2_SHIFT,
+			 OMAP3430_IVA2_MOD,
+			 CM_AUTOIDLE2);
+	cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
+			 MPU_MOD,
+			 CM_AUTOIDLE2);
+	cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
+			 (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
+			 PLL_MOD,
+			 CM_AUTOIDLE);
+	cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
+			 PLL_MOD,
+			 CM_AUTOIDLE2);
+
+	/* XXX Enable control of expternal oscillator through
+	 * sys_clkreq. I think clockfw should provide means to do this
+	 */
+	prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
+			     1 << OMAP_AUTOEXTCLKMODE_SHIFT,
+			     OMAP3430_GR_MOD,
+			     OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+
 	/* setup wakup source */
 	prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1,
 			  WKUP_MOD, PM_WKEN);
-- 
1.5.5


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

* Re: [PATCH 0/4] Refreshed PM workaround patches 2.
  2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
                   ` (3 preceding siblings ...)
  2008-08-15  7:47 ` [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
@ 2008-08-15  7:49 ` Felipe Balbi
  2008-08-18 13:23   ` Tony Lindgren
  4 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2008-08-15  7:49 UTC (permalink / raw)
  To: H?gander Jouni; +Cc: linux-omap

On Fri, Aug 15, 2008 at 10:44:47AM +0300, H?gander Jouni wrote:
> Refreshed PM workaround set without coding style errors and 24xx build
> fixed. Here are instructions how to test them:
> 
> To get Omap into retention, this patch set still depends on:
> 1. ARCH: OMAP: MUSB: Do not block sleep (Felipe Balbi)

I thought it had been applied. Probably lost while tony was on
vacations. Anyways, here it is:

From: Felipe Balbi <felipe.balbi@nokia.com>

arch: omap: usb: do not block sleep

musb_set_clock should not block sleep on omap3-based
boards, it prevents system from sleeping.

Thanks to Jouni Högander for pointing this out

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---

diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 71ddf55..3f90a93 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -58,7 +58,6 @@ static int musb_set_clock(struct clk *clk, int state)
                if (clk_on > 0)
                        return -ENODEV;
 
-               omap2_block_sleep();
                clk_enable(clk);
                clk_on = 1;
        } else {
@@ -67,7 +66,6 @@ static int musb_set_clock(struct clk *clk, int state)
 
                clk_disable(clk);
                clk_on = 0;
-               omap2_allow_sleep();
        }
 
        return 0;

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

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

* Re: [PATCH 0/4] Refreshed PM workaround patches 2.
  2008-08-15  7:49 ` [PATCH 0/4] Refreshed PM workaround patches 2 Felipe Balbi
@ 2008-08-18 13:23   ` Tony Lindgren
  0 siblings, 0 replies; 19+ messages in thread
From: Tony Lindgren @ 2008-08-18 13:23 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: H?gander Jouni, linux-omap

* Felipe Balbi <me@felipebalbi.com> [080815 10:50]:
> On Fri, Aug 15, 2008 at 10:44:47AM +0300, H?gander Jouni wrote:
> > Refreshed PM workaround set without coding style errors and 24xx build
> > fixed. Here are instructions how to test them:
> > 
> > To get Omap into retention, this patch set still depends on:
> > 1. ARCH: OMAP: MUSB: Do not block sleep (Felipe Balbi)
> 
> I thought it had been applied. Probably lost while tony was on
> vacations. Anyways, here it is:

Thanks, pushing today.

Tony

> From: Felipe Balbi <felipe.balbi@nokia.com>
> 
> arch: omap: usb: do not block sleep
> 
> musb_set_clock should not block sleep on omap3-based
> boards, it prevents system from sleeping.
> 
> Thanks to Jouni Högander for pointing this out
> 
> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
> ---
> 
> diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
> index 71ddf55..3f90a93 100644
> --- a/arch/arm/mach-omap2/usb-musb.c
> +++ b/arch/arm/mach-omap2/usb-musb.c
> @@ -58,7 +58,6 @@ static int musb_set_clock(struct clk *clk, int state)
>                 if (clk_on > 0)
>                         return -ENODEV;
>  
> -               omap2_block_sleep();
>                 clk_enable(clk);
>                 clk_on = 1;
>         } else {
> @@ -67,7 +66,6 @@ static int musb_set_clock(struct clk *clk, int state)
>  
>                 clk_disable(clk);
>                 clk_on = 0;
> -               omap2_allow_sleep();
>         }
>  
>         return 0;
> 
> -- 
> balbi
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
@ 2008-08-20 11:35   ` Tony Lindgren
  2008-08-22  5:45     ` Högander Jouni
  2008-08-21  8:17   ` Rajendra Nayak
  1 sibling, 1 reply; 19+ messages in thread
From: Tony Lindgren @ 2008-08-20 11:35 UTC (permalink / raw)
  To: Jouni Hogander; +Cc: linux-omap

[-- Attachment #1: Type: text/plain, Size: 361 bytes --]

* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
> This workaround shouldn't be needed when all drivers are configuring
> their sysconfig registers properly and using their clocks properly.

How about the cosmetically prettified version below? This could
still be kept around as CONFIG_PM_DEBUG functionality even after
the drivers are fixed.

Tony


[-- Attachment #2: pm-34xx-fclk-check --]
[-- Type: text/plain, Size: 2222 bytes --]

>From e37e8acd7685df9cb39f2fbc7887ba36639d5820 Mon Sep 17 00:00:00 2001
From: Jouni Hogander <jouni.hogander@nokia.com>
Date: Wed, 20 Aug 2008 14:32:46 +0300
Subject: [PATCH] ARM: OMAP: 34xx specific check wether any fck is active before entering sleep

We cannot enter sleep_while_idle if some functional clocks are
active. Add a check for enabled functional clocks for 34xx.

Note that this workaround could be behind CONFIG_PM_DEBUG
option when all drivers are configuring their sysconfig
registers properly and using their clocks properly.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index a57cf41..a145f80 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -174,10 +174,47 @@ static void omap_sram_idle(void)
 	omap2_gpio_resume_after_retention();
 }
 
+/*
+ * Check if functional clocks are enabled before entering
+ * sleep. This function could be behind CONFIG_PM_DEBUG
+ * when all drivers are configuring their sysconfig registers
+ * properly and using their clocks properly.
+ */
+static int omap3_fclks_active(void)
+{
+	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
+		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
+
+	fck_core1 = cm_read_mod_reg(CORE_MOD,
+				    CM_FCLKEN1);
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		fck_core3 = cm_read_mod_reg(CORE_MOD,
+					    OMAP3430ES2_CM_FCLKEN3);
+		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+					  CM_FCLKEN);
+		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+					      CM_FCLKEN);
+	} else
+		fck_sgx = cm_read_mod_reg(GFX_MOD,
+					  OMAP3430ES2_CM_FCLKEN3);
+	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
+				  CM_FCLKEN);
+	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
+				  CM_FCLKEN);
+	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
+				  CM_FCLKEN);
+	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
+	    fck_cam | fck_per | fck_usbhost)
+		return 1;
+	return 0;
+}
+
 static int omap3_can_sleep(void)
 {
 	if (!enable_dyn_sleep)
 		return 0;
+	if (omap3_fclks_active())
+		return 0;
 	if (atomic_read(&sleep_block) > 0)
 		return 0;
 	return 1;

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

* Re: [PATCH 2/4] PM: Workaround for taking care of gpio clocks
  2008-08-15  7:47 ` [PATCH 2/4] PM: Workaround for taking care of gpio clocks Jouni Hogander
@ 2008-08-20 11:37   ` Tony Lindgren
  2008-08-21 11:07     ` Tero.Kristo
  0 siblings, 1 reply; 19+ messages in thread
From: Tony Lindgren @ 2008-08-20 11:37 UTC (permalink / raw)
  To: Jouni Hogander; +Cc: linux-omap

* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
> In omap3 gpios 2-6 are in per domain. Functional clocks for these
> should be disabled. This patch is needed until gpio driver disables
> gpio clocks.
> 
> GPIO modules in PER domain are not able to act as a wake up source if
> PER domain is in retention. PER domain sleep transition before MPU is
> prevented by leaving icks active. PER domain still enters retention
> together with MPU. When this happens IOPAD wake up mechanism is used
> for gpios.

As we talked offline.. Should we pass the GPIO wake-up configuration
from board-*.c files? Or can we always automatically do this safely
on 34xx?

Tony


> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> ---
>  arch/arm/mach-omap2/pm34xx.c |   54 +++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 53 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index f30fa9e..7d5d461 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -53,6 +53,36 @@ static void (*saved_idle)(void);
>  
>  static struct powerdomain *mpu_pwrdm;
>  
> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> + * handles fcks correctly */
> +#define NUM_OF_PERGPIOS 5
> +static struct clk *gpio_fcks[NUM_OF_PERGPIOS];
> +
> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> + * handles fcks correctly */
> +static void per_gpio_clk_enable(void)
> +{
> +	int i;
> +	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
> +		clk_enable(gpio_fcks[i-1]);
> +}
> +
> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> + * handles fcks correctly */
> +static void per_gpio_clk_disable(void)
> +{
> +	int i;
> +	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++)
> +		clk_disable(gpio_fcks[i-1]);
> +}
> +
> +/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> + * handles fcks correctly */
> +static void gpio_fclk_mask(u32 *fclk)
> +{
> +	*fclk &= ~(0x1f << 13);
> +}
> +
>  /* PRCM Interrupt Handler for wakeups */
>  static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
>  {
> @@ -169,8 +199,18 @@ static void omap_sram_idle(void)
>  
>  	omap2_gpio_prepare_for_retention();
>  
> +	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> +	 * handles fcks correctly */
> +	if (clocks_off_while_idle)
> +		per_gpio_clk_disable();
> +
>  	_omap_sram_idle(NULL, save_state);
>  
> +	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> +	 * handles fcks correctly */
> +	if (clocks_off_while_idle)
> +		per_gpio_clk_enable();
> +
>  	omap2_gpio_resume_after_retention();
>  }
>  
> @@ -200,6 +240,10 @@ static int omap3_fclks_active(void)
>  				  CM_FCLKEN);
>  	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
>  				  CM_FCLKEN);
> +
> +	if (clocks_off_while_idle)
> +		gpio_fclk_mask(&fck_per);
> +
>  	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
>  	    fck_cam | fck_per | fck_usbhost)
>  		return 1;
> @@ -418,7 +462,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm)
>  int __init omap3_pm_init(void)
>  {
>  	struct power_state *pwrst;
> -	int ret;
> +	char clk_name[11];
> +	int ret, i;
>  
>  	printk(KERN_ERR "Power Management for TI OMAP3.\n");
>  
> @@ -454,6 +499,13 @@ int __init omap3_pm_init(void)
>  
>  	pm_idle = omap3_pm_idle;
>  
> +	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> +	 * handles fcks correctly */
> +	for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) {
> +		sprintf(clk_name, "gpio%d_fck", i + 1);
> +		gpio_fcks[i-1] = clk_get(NULL, clk_name);
> +	}
> +
>  err1:
>  	return ret;
>  err2:
> -- 
> 1.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 3/4] Added sleep support to UART
  2008-08-15  7:47 ` [PATCH 3/4] Added sleep support to UART Jouni Hogander
@ 2008-08-20 11:40   ` Tony Lindgren
  2008-08-20 12:26     ` Tero.Kristo
  0 siblings, 1 reply; 19+ messages in thread
From: Tony Lindgren @ 2008-08-20 11:40 UTC (permalink / raw)
  To: Jouni Hogander; +Cc: linux-omap, Tero Kristo

* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:48]:
> From: Tero Kristo <tero.kristo@nokia.com>
> 
> UART usage (e.g. serial console) now denies sleep for 5 seconds. This
> makes it possible to use serial console when dynamic idle is
> enabled. Write 1 to /sys/power/clocks_off_while_sleep to enable uart
> clock disable on idle. Without this omap won't enter retention.
> 
> Also moved code from pm-debug.c to serial.c, and made pm24xx.c use
> this new implementation.

This looks OK and safe to apply now. I guess it depends on the GPIO
patch above though?

Tony

> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> ---
>  arch/arm/mach-omap2/pm-debug.c           |  132 --------------------------
>  arch/arm/mach-omap2/pm.h                 |    7 --
>  arch/arm/mach-omap2/pm24xx.c             |   57 +++++++-----
>  arch/arm/mach-omap2/pm34xx.c             |   27 ++++--
>  arch/arm/mach-omap2/serial.c             |  148 ++++++++++++++++++++++++++++++
>  arch/arm/plat-omap/include/mach/common.h |    3 +
>  6 files changed, 204 insertions(+), 170 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 1b14bcf..b00f5f4 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -37,138 +37,6 @@
>  #ifdef CONFIG_PM_DEBUG
>  int omap2_pm_debug = 0;
>  
> -static int serial_console_clock_disabled;
> -static int serial_console_uart;
> -static unsigned int serial_console_next_disable;
> -
> -static struct clk *console_iclk, *console_fclk;
> -
> -static void serial_console_kick(void)
> -{
> -	serial_console_next_disable = omap2_read_32k_sync_counter();
> -	/* Keep the clocks on for 4 secs */
> -	serial_console_next_disable += 4 * 32768;
> -}
> -
> -static void serial_wait_tx(void)
> -{
> -	static const unsigned long uart_bases[3] = {
> -		0x4806a000, 0x4806c000, 0x4806e000
> -	};
> -	unsigned long lsr_reg;
> -	int looped = 0;
> -
> -	/* Wait for TX FIFO and THR to get empty */
> -	lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2));
> -	while ((__raw_readb(lsr_reg) & 0x60) != 0x60)
> -		looped = 1;
> -	if (looped)
> -		serial_console_kick();
> -}
> -
> -u32 omap2_read_32k_sync_counter(void)
> -{
> -        return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010);
> -}
> -
> -void serial_console_fclk_mask(u32 *f1, u32 *f2)
> -{
> -	switch (serial_console_uart)  {
> -	case 1:
> -		*f1 &= ~(1 << 21);
> -		break;
> -	case 2:
> -		*f1 &= ~(1 << 22);
> -		break;
> -	case 3:
> -		*f2 &= ~(1 << 2);
> -		break;
> -	}
> -}
> -
> -void serial_console_sleep(int enable)
> -{
> -	if (console_iclk == NULL || console_fclk == NULL)
> -		return;
> -
> -	if (enable) {
> -		BUG_ON(serial_console_clock_disabled);
> -		if (clk_get_usecount(console_fclk) == 0)
> -			return;
> -		if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0)
> -			return;
> -		serial_wait_tx();
> -		clk_disable(console_iclk);
> -		clk_disable(console_fclk);
> -		serial_console_clock_disabled = 1;
> -	} else {
> -		int serial_wakeup = 0;
> -		u32 l;
> -
> -		switch (serial_console_uart)  {
> -		case 1:
> -			l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
> -			if (l & OMAP24XX_ST_UART1)
> -				serial_wakeup = 1;
> -			break;
> -		case 2:
> -			l = prm_read_mod_reg(CORE_MOD, PM_WKST1);
> -			if (l & OMAP24XX_ST_UART2)
> -				serial_wakeup = 1;
> -			break;
> -		case 3:
> -			l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2);
> -			if (l & OMAP24XX_ST_UART3)
> -				serial_wakeup = 1;
> -			break;
> -		}
> -		if (serial_wakeup)
> -			serial_console_kick();
> -		if (!serial_console_clock_disabled)
> -			return;
> -		clk_enable(console_iclk);
> -		clk_enable(console_fclk);
> -		serial_console_clock_disabled = 0;
> -	}
> -}
> -
> -void pm_init_serial_console(void)
> -{
> -	const struct omap_serial_console_config *conf;
> -	char name[16];
> -
> -	conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
> -			       struct omap_serial_console_config);
> -	if (conf == NULL)
> -		return;
> -	if (conf->console_uart > 3 || conf->console_uart < 1)
> -		return;
> -	serial_console_uart = conf->console_uart;
> -	sprintf(name, "uart%d_fck", conf->console_uart);
> -	console_fclk = clk_get(NULL, name);
> -	if (IS_ERR(console_fclk))
> -		console_fclk = NULL;
> -	name[6] = 'i';
> -	console_iclk = clk_get(NULL, name);
> -	if (IS_ERR(console_fclk))
> -		console_iclk = NULL;
> -	if (console_fclk == NULL || console_iclk == NULL) {
> -		serial_console_uart = 0;
> -		return;
> -	}
> -	switch (serial_console_uart) {
> -	case 1:
> -		prm_set_mod_reg_bits(OMAP24XX_ST_UART1, CORE_MOD, PM_WKEN1);
> -		break;
> -	case 2:
> -		prm_set_mod_reg_bits(OMAP24XX_ST_UART2, CORE_MOD, PM_WKEN1);
> -		break;
> -	case 3:
> -		prm_set_mod_reg_bits(OMAP24XX_ST_UART3, CORE_MOD, OMAP24XX_PM_WKEN2);
> -		break;
> -	}
> -}
> -
>  #define DUMP_PRM_MOD_REG(mod, reg)    \
>  	regs[reg_count].name = #mod "." #reg; \
>  	regs[reg_count++].val = prm_read_mod_reg(mod, reg)
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index 68c9278..fe3f764 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -25,16 +25,9 @@ extern void omap2_allow_sleep(void);
>  
>  
>  #ifdef CONFIG_PM_DEBUG
> -extern u32 omap2_read_32k_sync_counter(void);
>  extern void omap2_pm_dump(int mode, int resume, unsigned int us);
> -extern void serial_console_fclk_mask(u32 *f1, u32 *f2);
> -extern void pm_init_serial_console(void);
> -extern void serial_console_sleep(int enable);
>  extern int omap2_pm_debug;
>  #else
> -#define omap2_read_32k_sync_counter()		0
> -#define serial_console_sleep(enable)		do {} while (0);
> -#define pm_init_serial_console()		do {} while (0);
>  #define omap2_pm_dump(mode, resume, us)		do {} while (0);
>  #define serial_console_fclk_mask(f1, f2)		do {} while (0);
>  #define omap2_pm_debug				0
> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
> index 5c76120..d766a35 100644
> --- a/arch/arm/mach-omap2/pm24xx.c
> +++ b/arch/arm/mach-omap2/pm24xx.c
> @@ -44,6 +44,7 @@
>  #include <mach/mux.h>
>  #include <mach/dma.h>
>  #include <mach/board.h>
> +#include <mach/common.h>
>  
>  #include "prm.h"
>  #include "prm-regbits-24xx.h"
> @@ -73,7 +74,10 @@ static int omap2_fclks_active(void)
>  
>  	f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
>  	f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
> -	serial_console_fclk_mask(&f1, &f2);
> +
> +	if (clocks_off_while_idle)
> +		omap_serial_fclk_mask(&f1, &f2);
> +
>  	if (f1 | f2)
>  		return 1;
>  	return 0;
> @@ -81,7 +85,8 @@ static int omap2_fclks_active(void)
>  
>  static void omap2_enter_full_retention(void)
>  {
> -	u32 l, sleep_time = 0;
> +	u32 l = 0;
> +	struct timespec sleep_time;
>  
>  	/* There is 1 reference hold for all children of the oscillator
>  	 * clock, the following will remove it. If no one else uses the
> @@ -111,28 +116,33 @@ static void omap2_enter_full_retention(void)
>  
>  	if (omap2_pm_debug) {
>  		omap2_pm_dump(0, 0, 0);
> -		sleep_time = omap2_read_32k_sync_counter();
> +		getnstimeofday(&sleep_time);
>  	}
>  
> +	if (clocks_off_while_idle)
> +		omap_serial_enable_clocks(0);
> +
>  	/* One last check for pending IRQs to avoid extra latency due
>  	 * to sleeping unnecessarily. */
>  	if (omap_irq_pending())
>  		goto no_sleep;
>  
> -	serial_console_sleep(1);
>  	/* Jump to SRAM suspend code */
>  	omap2_sram_suspend(OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL));
>  no_sleep:
> -	serial_console_sleep(0);
> +	omap_serial_check_wakeup();
> +	if (clocks_off_while_idle)
> +		omap_serial_enable_clocks(1);
>  
>  	if (omap2_pm_debug) {
> -		unsigned long long tmp;
> -		u32 resume_time;
> -
> -		resume_time = omap2_read_32k_sync_counter();
> -		tmp = resume_time - sleep_time;
> -		tmp *= 1000000;
> -		omap2_pm_dump(0, 1, tmp / 32768);
> +		struct timespec t;
> +		struct timespec ts_delta;
> +
> +		getnstimeofday(&t);
> +		ts_delta = timespec_sub(t, sleep_time);
> +		omap2_pm_dump(0, 1,
> +			      div_s64(timespec_to_ns(&ts_delta),
> +				      NSEC_PER_USEC));
>  	}
>  	omap2_gpio_resume_after_retention();
>  
> @@ -193,7 +203,7 @@ static int omap2_allow_mpu_retention(void)
>  
>  static void omap2_enter_mpu_retention(void)
>  {
> -	u32 sleep_time = 0;
> +	struct timespec sleep_time;
>  	int only_idle = 0;
>  
>  	/* Putting MPU into the WFI state while a transfer is active
> @@ -222,19 +232,20 @@ static void omap2_enter_mpu_retention(void)
>  
>  	if (omap2_pm_debug) {
>  		omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
> -		sleep_time = omap2_read_32k_sync_counter();
> +		getnstimeofday(&sleep_time);
>  	}
>  
>  	omap2_sram_idle();
>  
>  	if (omap2_pm_debug) {
> -		unsigned long long tmp;
> -		u32 resume_time;
> -
> -		resume_time = omap2_read_32k_sync_counter();
> -		tmp = resume_time - sleep_time;
> -		tmp *= 1000000;
> -		omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768);
> +		struct timespec t;
> +		struct timespec ts_delta;
> +
> +		getnstimeofday(&t);
> +		ts_delta = timespec_sub(t, sleep_time);
> +		omap2_pm_dump(only_idle ? 2 : 1, 1,
> +			      div_s64(timespec_to_ns(&ts_delta),
> +				      NSEC_PER_USEC));
>  	}
>  }
>  
> @@ -250,6 +261,8 @@ static int omap2_can_sleep(void)
>  		return 0;
>  	if (omap_dma_running())
>  		return 0;
> +	if (!omap_serial_can_sleep())
> +		return 0;
>  
>  	return 1;
>  }
> @@ -517,8 +530,6 @@ int __init omap2_pm_init(void)
>  
>  	prcm_setup_regs();
>  
> -	pm_init_serial_console();
> -
>  	/* Hack to prevent MPU retention when STI console is enabled. */
>  	{
>  		const struct omap_sti_console_config *sti;
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 7d5d461..29b4eee 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -29,6 +29,7 @@
>  #include <mach/pm.h>
>  #include <mach/clockdomain.h>
>  #include <mach/powerdomain.h>
> +#include <mach/common.h>
>  
>  #include "cm.h"
>  #include "cm-regbits-34xx.h"
> @@ -89,6 +90,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
>  	u32 wkst, irqstatus_mpu;
>  	u32 fclk, iclk;
>  
> +	/* Check if we woke up to serial console activity */
> +	omap_serial_check_wakeup();
> +
>  	/* WKUP */
>  	wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
>  	if (wkst) {
> @@ -198,18 +202,21 @@ static void omap_sram_idle(void)
>  	}
>  
>  	omap2_gpio_prepare_for_retention();
> -
> -	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> -	 * handles fcks correctly */
> -	if (clocks_off_while_idle)
> +	if (clocks_off_while_idle) {
> +		omap_serial_enable_clocks(0);
> +		/* XXX This is for gpio fclk hack. Will be removed as
> +		 * gpio driver * handles fcks correctly */
>  		per_gpio_clk_disable();
> +	}
>  
>  	_omap_sram_idle(NULL, save_state);
>  
> -	/* XXX This is for gpio fclk hack. Will be removed as gpio driver
> -	 * handles fcks correctly */
> -	if (clocks_off_while_idle)
> +	if (clocks_off_while_idle) {
> +		omap_serial_enable_clocks(1);
> +		/* XXX This is for gpio fclk hack. Will be removed as
> +		 * gpio driver * handles fcks correctly */
>  		per_gpio_clk_enable();
> +	}
>  
>  	omap2_gpio_resume_after_retention();
>  }
> @@ -241,8 +248,10 @@ static int omap3_fclks_active(void)
>  	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
>  				  CM_FCLKEN);
>  
> -	if (clocks_off_while_idle)
> +	if (clocks_off_while_idle) {
>  		gpio_fclk_mask(&fck_per);
> +		omap_serial_fclk_mask(&fck_core1, &fck_per);
> +	}
>  
>  	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
>  	    fck_cam | fck_per | fck_usbhost)
> @@ -261,6 +270,8 @@ static int omap3_can_sleep(void)
>  		return 0;
>  	if (atomic_read(&sleep_block) > 0)
>  		return 0;
> +	if (!omap_serial_can_sleep())
> +		return 0;
>  	return 1;
>  }
>  
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index d9fca6f..f55ab25 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -22,9 +22,66 @@
>  
>  #include <mach/common.h>
>  #include <mach/board.h>
> +#include <mach/clock.h>
> +#include <mach/control.h>
> +
> +#include "prm.h"
> +#include "pm.h"
> +
> +#define SERIAL_AWAKE_TIME 5
>  
>  static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
>  static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
> +static struct timespec omap_serial_next_sleep;
> +
> +#ifdef CONFIG_ARCH_OMAP24XX
> +static const u32 omap2_uart_wk_st[OMAP_MAX_NR_PORTS] = {
> +	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
> +	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1),
> +	OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKST2)
> +};
> +static const u32 omap2_uart_wk_en[OMAP_MAX_NR_PORTS] = {
> +	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
> +	OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1),
> +	OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKEN2),
> +};
> +static const u32 omap2_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
> +	OMAP24XX_ST_UART1, OMAP24XX_ST_UART2, OMAP24XX_ST_UART3
> +};
> +#endif
> +
> +#ifdef CONFIG_ARCH_OMAP34XX
> +static const u32 omap3_uart_wk_st[OMAP_MAX_NR_PORTS] = {
> +	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
> +	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1),
> +	OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKST1)
> +};
> +static const u32 omap3_uart_wk_en[OMAP_MAX_NR_PORTS] = {
> +	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
> +	OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1),
> +	OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKEN1)
> +};
> +static const u32 omap3_uart_wk_bit[OMAP_MAX_NR_PORTS] = {
> +	OMAP3430_ST_UART1, OMAP3430_ST_UART2, OMAP3430_ST_UART3
> +};
> +#endif
> +
> +static const u32 *omap_uart_wk_st;
> +static const u32 *omap_uart_wk_en;
> +static const u32 *omap_uart_wk_bit;
> +
> +/* UART padconfig registers, these may differ if non-default padconfig
> +   is used */
> +#define CONTROL_PADCONF_UART1_RX 0x182
> +#define CONTROL_PADCONF_UART2_RX 0x17A
> +#define CONTROL_PADCONF_UART3_RX 0x19E
> +#define PADCONF_WAKEUP_ST 0x8000
> +
> +static const u32 omap34xx_uart_padconf[OMAP_MAX_NR_PORTS] = {
> +	CONTROL_PADCONF_UART1_RX,
> +	CONTROL_PADCONF_UART2_RX,
> +	CONTROL_PADCONF_UART3_RX
> +};
>  
>  static struct plat_serial8250_port serial_platform_data[] = {
>  	{
> @@ -83,6 +140,13 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
>  	serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
>  }
>  
> +static void omap_serial_kick(void)
> +{
> +	getnstimeofday(&omap_serial_next_sleep);
> +	timespec_add_ns(&omap_serial_next_sleep, (s64)SERIAL_AWAKE_TIME *
> +		NSEC_PER_SEC);
> +}
> +
>  void omap_serial_enable_clocks(int enable)
>  {
>  	int i;
> @@ -99,6 +163,67 @@ void omap_serial_enable_clocks(int enable)
>  	}
>  }
>  
> +void omap_serial_fclk_mask(u32 *f1, u32 *f2)
> +{
> +	if (uart_ick[0])
> +		*f1 &= ~(1 << uart_fck[0]->enable_bit);
> +	if (uart_ick[1])
> +		*f1 &= ~(1 << uart_fck[1]->enable_bit);
> +	if (uart_ick[2])
> +		*f2 &= ~(1 << uart_fck[2]->enable_bit);
> +}
> +
> +void omap_serial_check_wakeup(void)
> +{
> +	int i;
> +
> +
> +	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
> +		if (!uart_ick[i])
> +			continue;
> +
> +		if (cpu_is_omap34xx())
> +			if (omap_ctrl_readw(omap34xx_uart_padconf[i]) &
> +			    PADCONF_WAKEUP_ST) {
> +				omap_serial_kick();
> +				return;
> +			}
> +
> +		if (__raw_readl(omap_uart_wk_st[i]) &
> +		    omap_uart_wk_bit[i]) {
> +			omap_serial_kick();
> +			return;
> +		}
> +	}
> +}
> +
> +int omap_serial_can_sleep(void)
> +{
> +	int i;
> +	struct timespec t;
> +
> +	struct plat_serial8250_port *p = serial_platform_data;
> +
> +	getnstimeofday(&t);
> +
> +	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
> +		if (!uart_ick[i])
> +			continue;
> +		/* Check if we have data in the transmit buffer */
> +		if ((serial_read_reg(p + i, UART_LSR) &
> +			(UART_LSR_TEMT|UART_LSR_THRE))
> +			!= (UART_LSR_TEMT|UART_LSR_THRE)) {
> +				omap_serial_kick();
> +				return 0;
> +		}
> +	}
> +
> +	if (timespec_compare(&t, &omap_serial_next_sleep) < 0)
> +		return 0;
> +
> +	return 1;
> +}
> +
>  void __init omap_serial_init(void)
>  {
>  	int i;
> @@ -116,8 +241,25 @@ void __init omap_serial_init(void)
>  	if (info == NULL)
>  		return;
>  
> +#ifdef CONFIG_ARCH_OMAP24XX
> +	if (cpu_is_omap242x()) {
> +		omap_uart_wk_st = omap2_uart_wk_st;
> +		omap_uart_wk_en = omap2_uart_wk_en;
> +		omap_uart_wk_bit = omap2_uart_wk_bit;
> +	}
> +#endif
> +
> +#ifdef CONFIG_ARCH_OMAP34XX
> +	if (cpu_is_omap34xx()) {
> +		omap_uart_wk_st = omap3_uart_wk_st;
> +		omap_uart_wk_en = omap3_uart_wk_en;
> +		omap_uart_wk_bit = omap3_uart_wk_bit;
> +	}
> +#endif
> +
>  	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
>  		struct plat_serial8250_port *p = serial_platform_data + i;
> +		u32 v;
>  
>  		if (!(info->enabled_uarts & (1 << i))) {
>  			p->membase = NULL;
> @@ -142,7 +284,13 @@ void __init omap_serial_init(void)
>  			clk_enable(uart_fck[i]);
>  
>  		omap_serial_reset(p);
> +
> +		v = __raw_readl(omap_uart_wk_en[i]);
> +		v |= omap_uart_wk_bit[i];
> +		__raw_writel(v, omap_uart_wk_en[i]);
>  	}
> +
> +	omap_serial_kick();
>  }
>  
>  static struct platform_device serial_device = {
> diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h
> index 5f46249..003c08e 100644
> --- a/arch/arm/plat-omap/include/mach/common.h
> +++ b/arch/arm/plat-omap/include/mach/common.h
> @@ -35,6 +35,9 @@ extern void omap_map_common_io(void);
>  extern struct sys_timer omap_timer;
>  extern void omap_serial_init(void);
>  extern void omap_serial_enable_clocks(int enable);
> +extern int omap_serial_can_sleep(void);
> +extern void omap_serial_fclk_mask(u32 *f1, u32 *f2);
> +void omap_serial_check_wakeup(void);
>  #ifdef CONFIG_I2C_OMAP
>  extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
>  				 struct i2c_board_info const *info,
> -- 
> 1.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls
  2008-08-15  7:47 ` [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
@ 2008-08-20 11:51   ` Tony Lindgren
  0 siblings, 0 replies; 19+ messages in thread
From: Tony Lindgren @ 2008-08-20 11:51 UTC (permalink / raw)
  To: Jouni Hogander; +Cc: linux-omap

[-- Attachment #1: Type: text/plain, Size: 548 bytes --]

* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
> From: ext Jouni Hogander <jouni.hogander@nokia.com>
> 
> This workaround enables autoidle for interface clocks and plls. Also
> automatic control of external oscillator through sys_clkreq is
> enabled.
> 
> Proper fix to this is to generalize omap3_dpll_allow_idle,
> omap3_dpll_deny_idle, omap3_dpll_autoidle_read and call it for each
> clock on init.

How about this prettified version? I doubt that we'll get to changing
the clock fwk for this until in about six months or so.

Tony

[-- Attachment #2: pm-34xx-autoidle --]
[-- Type: text/plain, Size: 4192 bytes --]

>From 558b9c500eb66b744bfa45eaf83ea501e7343e3c Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Wed, 20 Aug 2008 14:50:14 +0300
Subject: [PATCH] From: ext Jouni Hogander <jouni.hogander@nokia.com>

ARM: OMAP: Enable 34xx autoidle for clocks and plls

Enable autoidle for interface clocks and plls. Also automatic
control of external oscillator through sys_clkreq is enabled.

In the long term, proper solution is to generalize
omap3_dpll_allow_idle, omap3_dpll_deny_idle,
omap3_dpll_autoidle_read and call it for each clock on init.

Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index a145f80..a16eb33 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -383,6 +383,132 @@ static void __init prcm_setup_regs(void)
 	} else
 		prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
 
+	/*
+	 * Enable interface clock autoidle for all modules.
+	 * Note that in the long run this should be done by clockfw
+	 */
+	cm_write_mod_reg(
+		OMAP3430ES2_AUTO_MMC3 |
+		OMAP3430ES2_AUTO_ICR |
+		OMAP3430_AUTO_AES2 |
+		OMAP3430_AUTO_SHA12 |
+		OMAP3430_AUTO_DES2 |
+		OMAP3430_AUTO_MMC2 |
+		OMAP3430_AUTO_MMC1 |
+		OMAP3430_AUTO_MSPRO |
+		OMAP3430_AUTO_HDQ |
+		OMAP3430_AUTO_MCSPI4 |
+		OMAP3430_AUTO_MCSPI3 |
+		OMAP3430_AUTO_MCSPI2 |
+		OMAP3430_AUTO_MCSPI1 |
+		OMAP3430_AUTO_I2C3 |
+		OMAP3430_AUTO_I2C2 |
+		OMAP3430_AUTO_I2C1 |
+		OMAP3430_AUTO_UART2 |
+		OMAP3430_AUTO_UART1 |
+		OMAP3430_AUTO_GPT11 |
+		OMAP3430_AUTO_GPT10 |
+		OMAP3430_AUTO_MCBSP5 |
+		OMAP3430_AUTO_MCBSP1 |
+		OMAP3430ES1_AUTO_FAC | /* This is es1 only */
+		OMAP3430_AUTO_MAILBOXES |
+		OMAP3430_AUTO_OMAPCTRL |
+		OMAP3430ES1_AUTO_FSHOSTUSB |
+		OMAP3430_AUTO_HSOTGUSB |
+		OMAP3430ES1_AUTO_D2D | /* This is es1 only */
+		OMAP3430_AUTO_SSI,
+		CORE_MOD, CM_AUTOIDLE1);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_PKA |
+		OMAP3430_AUTO_AES1 |
+		OMAP3430_AUTO_RNG |
+		OMAP3430_AUTO_SHA11 |
+		OMAP3430_AUTO_DES1,
+		CORE_MOD, CM_AUTOIDLE2);
+
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		cm_write_mod_reg(
+			OMAP3430ES2_AUTO_USBTLL,
+			CORE_MOD, CM_AUTOIDLE3);
+	}
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_WDT2 |
+		OMAP3430_AUTO_WDT1 |
+		OMAP3430_AUTO_GPIO1 |
+		OMAP3430_AUTO_32KSYNC |
+		OMAP3430_AUTO_GPT12 |
+		OMAP3430_AUTO_GPT1 ,
+		WKUP_MOD, CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_DSS,
+		OMAP3430_DSS_MOD,
+		CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_CAM,
+		OMAP3430_CAM_MOD,
+		CM_AUTOIDLE);
+
+	cm_write_mod_reg(
+		OMAP3430_AUTO_GPIO6 |
+		OMAP3430_AUTO_GPIO5 |
+		OMAP3430_AUTO_GPIO4 |
+		OMAP3430_AUTO_GPIO3 |
+		OMAP3430_AUTO_GPIO2 |
+		OMAP3430_AUTO_WDT3 |
+		OMAP3430_AUTO_UART3 |
+		OMAP3430_AUTO_GPT9 |
+		OMAP3430_AUTO_GPT8 |
+		OMAP3430_AUTO_GPT7 |
+		OMAP3430_AUTO_GPT6 |
+		OMAP3430_AUTO_GPT5 |
+		OMAP3430_AUTO_GPT4 |
+		OMAP3430_AUTO_GPT3 |
+		OMAP3430_AUTO_GPT2 |
+		OMAP3430_AUTO_MCBSP4 |
+		OMAP3430_AUTO_MCBSP3 |
+		OMAP3430_AUTO_MCBSP2,
+		OMAP3430_PER_MOD,
+		CM_AUTOIDLE);
+
+	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
+		cm_write_mod_reg(
+			OMAP3430ES2_AUTO_USBHOST,
+			OMAP3430ES2_USBHOST_MOD,
+			CM_AUTOIDLE);
+	}
+
+	/*
+	 * Set all plls to autoidle. This is needed until autoidle is
+	 * enabled by clockfw
+	 */
+	cm_write_mod_reg(1 << OMAP3430_CLKTRCTRL_IVA2_SHIFT,
+			 OMAP3430_IVA2_MOD,
+			 CM_AUTOIDLE2);
+	cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
+			 MPU_MOD,
+			 CM_AUTOIDLE2);
+	cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
+			 (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
+			 PLL_MOD,
+			 CM_AUTOIDLE);
+	cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
+			 PLL_MOD,
+			 CM_AUTOIDLE2);
+
+	/*
+	 * Enable control of expternal oscillator through
+	 * sys_clkreq. In the long run clock framework should
+	 * take care of this.
+	 */
+	prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
+			     1 << OMAP_AUTOEXTCLKMODE_SHIFT,
+			     OMAP3430_GR_MOD,
+			     OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+
 	/* setup wakup source */
 	prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1,
 			  WKUP_MOD, PM_WKEN);

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

* RE: [PATCH 3/4] Added sleep support to UART
  2008-08-20 11:40   ` Tony Lindgren
@ 2008-08-20 12:26     ` Tero.Kristo
  0 siblings, 0 replies; 19+ messages in thread
From: Tero.Kristo @ 2008-08-20 12:26 UTC (permalink / raw)
  To: tony, jouni.hogander; +Cc: linux-omap

 

>-----Original Message-----
>From: ext Tony Lindgren [mailto:tony@atomide.com] 
>Sent: 20 August, 2008 14:40
>To: Hogander Jouni (Nokia-D/Tampere)
>Cc: linux-omap@vger.kernel.org; Kristo Tero (Nokia-D/Tampere)
>Subject: Re: [PATCH 3/4] Added sleep support to UART
>
>* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:48]:
>> From: Tero Kristo <tero.kristo@nokia.com>
>> 
>> UART usage (e.g. serial console) now denies sleep for 5 
>seconds. This 
>> makes it possible to use serial console when dynamic idle is 
>enabled. 
>> Write 1 to /sys/power/clocks_off_while_sleep to enable uart clock 
>> disable on idle. Without this omap won't enter retention.
>> 
>> Also moved code from pm-debug.c to serial.c, and made pm24xx.c use 
>> this new implementation.
>
>This looks OK and safe to apply now. I guess it depends on the 
>GPIO patch above though?

Yes, checks for the sleep conditions and dynamic clock disable / enable
mechanism are introduced in the GPIO patch. I think it would be possible
to change the order of dependency if needed though, but this would
require changes to both patches.

-Tero

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

* RE: [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
  2008-08-20 11:35   ` Tony Lindgren
@ 2008-08-21  8:17   ` Rajendra Nayak
  2008-08-21  9:41     ` Rajendra Nayak
  1 sibling, 1 reply; 19+ messages in thread
From: Rajendra Nayak @ 2008-08-21  8:17 UTC (permalink / raw)
  To: 'Jouni Hogander', linux-omap

Jouni,

I am having some issues applying these patches. Any idea whats wrong?

(Stripping trailing CRs from patch.)
patching file arch/arm/mach-omap2/pm34xx.c
patch: **** malformed patch at line 66:         return 1;

regards,
Rajendra
 

> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org 
> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Jouni Hogander
> Sent: Friday, August 15, 2008 1:17 PM
> To: linux-omap@vger.kernel.org
> Subject: [PATCH 1/4] 34XX: PM: Workaround to check wether any 
> fck is active before entering sleep
> 
> This workaround shouldn't be needed when all drivers are 
> configuring their sysconfig registers properly and using 
> their clocks properly.
> 
> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> ---
>  arch/arm/mach-omap2/pm34xx.c |   37 
> +++++++++++++++++++++++++++++++++++++
>  1 files changed, 37 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/pm34xx.c 
> b/arch/arm/mach-omap2/pm34xx.c index a57cf41..f30fa9e 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -174,10 +174,47 @@ static void omap_sram_idle(void)
>  	omap2_gpio_resume_after_retention();
>  }
>  
> +/* XXX This workaround shouldn't be needed when all drivers are 
> +configuring
> + * their sysconfig registers properly and using their clocks
> + * properly. */
> +static int omap3_fclks_active(void)
> +{
> +	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
> +		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
> +
> +	fck_core1 = cm_read_mod_reg(CORE_MOD,
> +				    CM_FCLKEN1);
> +	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> +		fck_core3 = cm_read_mod_reg(CORE_MOD,
> +					    OMAP3430ES2_CM_FCLKEN3);
> +		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
> +					  CM_FCLKEN);
> +		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
> +					      CM_FCLKEN);
> +	} else
> +		fck_sgx = cm_read_mod_reg(GFX_MOD,
> +					  OMAP3430ES2_CM_FCLKEN3);
> +	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
> +				  CM_FCLKEN);
> +	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
> +				  CM_FCLKEN);
> +	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> +				  CM_FCLKEN);
> +	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> +	    fck_cam | fck_per | fck_usbhost)
> +		return 1;
> +	return 0;
> +}
> +
>  static int omap3_can_sleep(void)
>  {
>  	if (!enable_dyn_sleep)
>  		return 0;
> +	/* XXX This workaround shouldn't be needed when all drivers are
> +	 * configuring their sysconfig registers properly and 
> using their
> +	 * clocks properly. */
> +	if (omap3_fclks_active())
> +		return 0;
>  	if (atomic_read(&sleep_block) > 0)
>  		return 0;
>  	return 1;
> --
> 1.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe 
> linux-omap" in the body of a message to 
> majordomo@vger.kernel.org More majordomo info at  
> http://vger.kernel.org/majordomo-info.html
> 
> 


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

* RE: [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-21  8:17   ` Rajendra Nayak
@ 2008-08-21  9:41     ` Rajendra Nayak
  0 siblings, 0 replies; 19+ messages in thread
From: Rajendra Nayak @ 2008-08-21  9:41 UTC (permalink / raw)
  To: 'Jouni Hogander', linux-omap

 
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org 
> [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Rajendra Nayak
> Sent: Thursday, August 21, 2008 1:47 PM
> To: 'Jouni Hogander'; linux-omap@vger.kernel.org
> Subject: RE: [PATCH 1/4] 34XX: PM: Workaround to check wether 
> any fck is active before entering sleep
> 
> Jouni,
> 
> I am having some issues applying these patches. Any idea whats wrong?

Ok.. so I figured this out. It was some mail client issue at my end.. 
sorry for the trouble.

> 
> (Stripping trailing CRs from patch.)
> patching file arch/arm/mach-omap2/pm34xx.c
> patch: **** malformed patch at line 66:         return 1;
> 
> regards,
> Rajendra
>  
> 
> > -----Original Message-----
> > From: linux-omap-owner@vger.kernel.org 
> > [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of 
> Jouni Hogander
> > Sent: Friday, August 15, 2008 1:17 PM
> > To: linux-omap@vger.kernel.org
> > Subject: [PATCH 1/4] 34XX: PM: Workaround to check wether any 
> > fck is active before entering sleep
> > 
> > This workaround shouldn't be needed when all drivers are 
> > configuring their sysconfig registers properly and using 
> > their clocks properly.
> > 
> > Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> > ---
> >  arch/arm/mach-omap2/pm34xx.c |   37 
> > +++++++++++++++++++++++++++++++++++++
> >  1 files changed, 37 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/pm34xx.c 
> > b/arch/arm/mach-omap2/pm34xx.c index a57cf41..f30fa9e 100644
> > --- a/arch/arm/mach-omap2/pm34xx.c
> > +++ b/arch/arm/mach-omap2/pm34xx.c
> > @@ -174,10 +174,47 @@ static void omap_sram_idle(void)
> >  	omap2_gpio_resume_after_retention();
> >  }
> >  
> > +/* XXX This workaround shouldn't be needed when all drivers are 
> > +configuring
> > + * their sysconfig registers properly and using their clocks
> > + * properly. */
> > +static int omap3_fclks_active(void)
> > +{
> > +	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
> > +		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
> > +
> > +	fck_core1 = cm_read_mod_reg(CORE_MOD,
> > +				    CM_FCLKEN1);
> > +	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> > +		fck_core3 = cm_read_mod_reg(CORE_MOD,
> > +					    OMAP3430ES2_CM_FCLKEN3);
> > +		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
> > +					  CM_FCLKEN);
> > +		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
> > +					      CM_FCLKEN);
> > +	} else
> > +		fck_sgx = cm_read_mod_reg(GFX_MOD,
> > +					  OMAP3430ES2_CM_FCLKEN3);
> > +	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
> > +				  CM_FCLKEN);
> > +	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
> > +				  CM_FCLKEN);
> > +	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> > +				  CM_FCLKEN);
> > +	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> > +	    fck_cam | fck_per | fck_usbhost)
> > +		return 1;
> > +	return 0;
> > +}
> > +
> >  static int omap3_can_sleep(void)
> >  {
> >  	if (!enable_dyn_sleep)
> >  		return 0;
> > +	/* XXX This workaround shouldn't be needed when all drivers are
> > +	 * configuring their sysconfig registers properly and 
> > using their
> > +	 * clocks properly. */
> > +	if (omap3_fclks_active())
> > +		return 0;
> >  	if (atomic_read(&sleep_block) > 0)
> >  		return 0;
> >  	return 1;
> > --
> > 1.5.5
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe 
> > linux-omap" in the body of a message to 
> > majordomo@vger.kernel.org More majordomo info at  
> > http://vger.kernel.org/majordomo-info.html
> > 
> > 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe 
> linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


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

* RE: [PATCH 2/4] PM: Workaround for taking care of gpio clocks
  2008-08-20 11:37   ` Tony Lindgren
@ 2008-08-21 11:07     ` Tero.Kristo
  2008-08-22 18:06       ` Tony Lindgren
  0 siblings, 1 reply; 19+ messages in thread
From: Tero.Kristo @ 2008-08-21 11:07 UTC (permalink / raw)
  To: tony, jouni.hogander; +Cc: linux-omap

 

>-----Original Message-----
>From: linux-omap-owner@vger.kernel.org 
>[mailto:linux-omap-owner@vger.kernel.org] On Behalf Of ext 
>Tony Lindgren
>Sent: 20 August, 2008 14:37
>To: Hogander Jouni (Nokia-D/Tampere)
>Cc: linux-omap@vger.kernel.org
>Subject: Re: [PATCH 2/4] PM: Workaround for taking care of gpio clocks
>
>* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
>> In omap3 gpios 2-6 are in per domain. Functional clocks for these 
>> should be disabled. This patch is needed until gpio driver disables 
>> gpio clocks.
>> 
>> GPIO modules in PER domain are not able to act as a wake up 
>source if 
>> PER domain is in retention. PER domain sleep transition 
>before MPU is 
>> prevented by leaving icks active. PER domain still enters retention 
>> together with MPU. When this happens IOPAD wake up mechanism is used 
>> for gpios.
>
>As we talked offline.. Should we pass the GPIO wake-up 
>configuration from board-*.c files? Or can we always 
>automatically do this safely on 34xx?

After some investigation it seems that we can configure wake-up events
for almost every GPIO from the padconfigs. There are only 2 pins that do
not seem to have this functionality, however I am not sure if this is a
documentation bug or what because it is strange that only 2 pins lack
this capability. GPIOs 32 and 187 are missing wake-up capability from
padconfig.

Because of this, our proposal would be to make GPIO clock switching
global, but this would be enabled from a sysfs entry pretty much like
how it is in the patches now. However, this would be separated from UART
clock switching. So, we would introduce two new sysfs files:
uart_clocks_off_while_idle and gpio_clocks_off_while_idle. This would
avoid introducing new complexity in to the idle loop.

How does this sound like?

-Tero

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

* Re: [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-20 11:35   ` Tony Lindgren
@ 2008-08-22  5:45     ` Högander Jouni
  2008-08-22 18:07       ` Tony Lindgren
  0 siblings, 1 reply; 19+ messages in thread
From: Högander Jouni @ 2008-08-22  5:45 UTC (permalink / raw)
  To: ext Tony Lindgren; +Cc: linux-omap

"ext Tony Lindgren" <tony@atomide.com> writes:

> * Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
>> This workaround shouldn't be needed when all drivers are configuring
>> their sysconfig registers properly and using their clocks properly.
>
> How about the cosmetically prettified version below? This could
> still be kept around as CONFIG_PM_DEBUG functionality even after
> the drivers are fixed.

Sounds ok to me. I don't get how PM_DEBUG option is related to this,
but anyway ok to me.

>
> Tony
>
>>From e37e8acd7685df9cb39f2fbc7887ba36639d5820 Mon Sep 17 00:00:00 2001
> From: Jouni Hogander <jouni.hogander@nokia.com>
> Date: Wed, 20 Aug 2008 14:32:46 +0300
> Subject: [PATCH] ARM: OMAP: 34xx specific check wether any fck is active before entering sleep
>
> We cannot enter sleep_while_idle if some functional clocks are
> active. Add a check for enabled functional clocks for 34xx.
>
> Note that this workaround could be behind CONFIG_PM_DEBUG
> option when all drivers are configuring their sysconfig
> registers properly and using their clocks properly.
>
> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index a57cf41..a145f80 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -174,10 +174,47 @@ static void omap_sram_idle(void)
>  	omap2_gpio_resume_after_retention();
>  }
>  
> +/*
> + * Check if functional clocks are enabled before entering
> + * sleep. This function could be behind CONFIG_PM_DEBUG
> + * when all drivers are configuring their sysconfig registers
> + * properly and using their clocks properly.
> + */
> +static int omap3_fclks_active(void)
> +{
> +	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
> +		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
> +
> +	fck_core1 = cm_read_mod_reg(CORE_MOD,
> +				    CM_FCLKEN1);
> +	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> +		fck_core3 = cm_read_mod_reg(CORE_MOD,
> +					    OMAP3430ES2_CM_FCLKEN3);
> +		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
> +					  CM_FCLKEN);
> +		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
> +					      CM_FCLKEN);
> +	} else
> +		fck_sgx = cm_read_mod_reg(GFX_MOD,
> +					  OMAP3430ES2_CM_FCLKEN3);
> +	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
> +				  CM_FCLKEN);
> +	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
> +				  CM_FCLKEN);
> +	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> +				  CM_FCLKEN);
> +	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> +	    fck_cam | fck_per | fck_usbhost)
> +		return 1;
> +	return 0;
> +}
> +
>  static int omap3_can_sleep(void)
>  {
>  	if (!enable_dyn_sleep)
>  		return 0;
> +	if (omap3_fclks_active())
> +		return 0;
>  	if (atomic_read(&sleep_block) > 0)
>  		return 0;
>  	return 1;

-- 
Jouni Högander

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

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

* Re: [PATCH 2/4] PM: Workaround for taking care of gpio clocks
  2008-08-21 11:07     ` Tero.Kristo
@ 2008-08-22 18:06       ` Tony Lindgren
  0 siblings, 0 replies; 19+ messages in thread
From: Tony Lindgren @ 2008-08-22 18:06 UTC (permalink / raw)
  To: Tero.Kristo; +Cc: jouni.hogander, linux-omap

* Tero.Kristo@nokia.com <Tero.Kristo@nokia.com> [080821 14:08]:
>  
> 
> >-----Original Message-----
> >From: linux-omap-owner@vger.kernel.org 
> >[mailto:linux-omap-owner@vger.kernel.org] On Behalf Of ext 
> >Tony Lindgren
> >Sent: 20 August, 2008 14:37
> >To: Hogander Jouni (Nokia-D/Tampere)
> >Cc: linux-omap@vger.kernel.org
> >Subject: Re: [PATCH 2/4] PM: Workaround for taking care of gpio clocks
> >
> >* Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
> >> In omap3 gpios 2-6 are in per domain. Functional clocks for these 
> >> should be disabled. This patch is needed until gpio driver disables 
> >> gpio clocks.
> >> 
> >> GPIO modules in PER domain are not able to act as a wake up 
> >source if 
> >> PER domain is in retention. PER domain sleep transition 
> >before MPU is 
> >> prevented by leaving icks active. PER domain still enters retention 
> >> together with MPU. When this happens IOPAD wake up mechanism is used 
> >> for gpios.
> >
> >As we talked offline.. Should we pass the GPIO wake-up 
> >configuration from board-*.c files? Or can we always 
> >automatically do this safely on 34xx?
> 
> After some investigation it seems that we can configure wake-up events
> for almost every GPIO from the padconfigs. There are only 2 pins that do
> not seem to have this functionality, however I am not sure if this is a
> documentation bug or what because it is strange that only 2 pins lack
> this capability. GPIOs 32 and 187 are missing wake-up capability from
> padconfig.
> 
> Because of this, our proposal would be to make GPIO clock switching
> global, but this would be enabled from a sysfs entry pretty much like
> how it is in the patches now. However, this would be separated from UART
> clock switching. So, we would introduce two new sysfs files:
> uart_clocks_off_while_idle and gpio_clocks_off_while_idle. This would
> avoid introducing new complexity in to the idle loop.
> 
> How does this sound like?

Sounds good to me. Then we may be able to remove both sysfs files
eventually.

Regards,

Tony

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

* Re: [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep
  2008-08-22  5:45     ` Högander Jouni
@ 2008-08-22 18:07       ` Tony Lindgren
  0 siblings, 0 replies; 19+ messages in thread
From: Tony Lindgren @ 2008-08-22 18:07 UTC (permalink / raw)
  To: Högander Jouni; +Cc: linux-omap

* Högander Jouni <jouni.hogander@nokia.com> [080822 08:45]:
> "ext Tony Lindgren" <tony@atomide.com> writes:
> 
> > * Jouni Hogander <jouni.hogander@nokia.com> [080815 10:47]:
> >> This workaround shouldn't be needed when all drivers are configuring
> >> their sysconfig registers properly and using their clocks properly.
> >
> > How about the cosmetically prettified version below? This could
> > still be kept around as CONFIG_PM_DEBUG functionality even after
> > the drivers are fixed.
> 
> Sounds ok to me. I don't get how PM_DEBUG option is related to this,
> but anyway ok to me.

OK will push then. PM_DEBUG option comment was just to be able to
maybe warn about debug broken drivers if idle fails or something
like that.

Tony

> >
> > Tony
> >
> >>From e37e8acd7685df9cb39f2fbc7887ba36639d5820 Mon Sep 17 00:00:00 2001
> > From: Jouni Hogander <jouni.hogander@nokia.com>
> > Date: Wed, 20 Aug 2008 14:32:46 +0300
> > Subject: [PATCH] ARM: OMAP: 34xx specific check wether any fck is active before entering sleep
> >
> > We cannot enter sleep_while_idle if some functional clocks are
> > active. Add a check for enabled functional clocks for 34xx.
> >
> > Note that this workaround could be behind CONFIG_PM_DEBUG
> > option when all drivers are configuring their sysconfig
> > registers properly and using their clocks properly.
> >
> > Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
> > Signed-off-by: Tony Lindgren <tony@atomide.com>
> >
> > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> > index a57cf41..a145f80 100644
> > --- a/arch/arm/mach-omap2/pm34xx.c
> > +++ b/arch/arm/mach-omap2/pm34xx.c
> > @@ -174,10 +174,47 @@ static void omap_sram_idle(void)
> >  	omap2_gpio_resume_after_retention();
> >  }
> >  
> > +/*
> > + * Check if functional clocks are enabled before entering
> > + * sleep. This function could be behind CONFIG_PM_DEBUG
> > + * when all drivers are configuring their sysconfig registers
> > + * properly and using their clocks properly.
> > + */
> > +static int omap3_fclks_active(void)
> > +{
> > +	u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
> > +		fck_cam = 0, fck_per = 0, fck_usbhost = 0;
> > +
> > +	fck_core1 = cm_read_mod_reg(CORE_MOD,
> > +				    CM_FCLKEN1);
> > +	if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
> > +		fck_core3 = cm_read_mod_reg(CORE_MOD,
> > +					    OMAP3430ES2_CM_FCLKEN3);
> > +		fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
> > +					  CM_FCLKEN);
> > +		fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
> > +					      CM_FCLKEN);
> > +	} else
> > +		fck_sgx = cm_read_mod_reg(GFX_MOD,
> > +					  OMAP3430ES2_CM_FCLKEN3);
> > +	fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
> > +				  CM_FCLKEN);
> > +	fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
> > +				  CM_FCLKEN);
> > +	fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
> > +				  CM_FCLKEN);
> > +	if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
> > +	    fck_cam | fck_per | fck_usbhost)
> > +		return 1;
> > +	return 0;
> > +}
> > +
> >  static int omap3_can_sleep(void)
> >  {
> >  	if (!enable_dyn_sleep)
> >  		return 0;
> > +	if (omap3_fclks_active())
> > +		return 0;
> >  	if (atomic_read(&sleep_block) > 0)
> >  		return 0;
> >  	return 1;
> 
> -- 
> Jouni Högander
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2008-08-22 18:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-15  7:44 [PATCH 0/4] Refreshed PM workaround patches 2 Högander Jouni
2008-08-15  7:47 ` [PATCH 1/4] 34XX: PM: Workaround to check wether any fck is active before entering sleep Jouni Hogander
2008-08-20 11:35   ` Tony Lindgren
2008-08-22  5:45     ` Högander Jouni
2008-08-22 18:07       ` Tony Lindgren
2008-08-21  8:17   ` Rajendra Nayak
2008-08-21  9:41     ` Rajendra Nayak
2008-08-15  7:47 ` [PATCH 2/4] PM: Workaround for taking care of gpio clocks Jouni Hogander
2008-08-20 11:37   ` Tony Lindgren
2008-08-21 11:07     ` Tero.Kristo
2008-08-22 18:06       ` Tony Lindgren
2008-08-15  7:47 ` [PATCH 3/4] Added sleep support to UART Jouni Hogander
2008-08-20 11:40   ` Tony Lindgren
2008-08-20 12:26     ` Tero.Kristo
2008-08-15  7:47 ` [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls Jouni Hogander
2008-08-20 11:51   ` Tony Lindgren
2008-08-15  7:49 ` [PATCH 0/4] Refreshed PM workaround patches 2 Felipe Balbi
2008-08-18 13:23   ` Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2008-06-30  8:50 [PATCH 0/6] 34XX: PM: Workarounds to get omap3 to retention 4th Högander Jouni
2008-08-15  6:18 ` [PATCH 2/4] PM: Workaround for taking care of gpio clocks Jouni Hogander

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox