linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] OMAP PM fixes for 2.6.32
@ 2009-10-02 18:14 Kevin Hilman
  2009-10-02 18:14 ` [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler Kevin Hilman
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

These fixes are primarily for PRCM interrupt handler bugs
and GPIO wakeup support.

Jon Hunter (1):
  OMAP3: PM: Prevent hang in prcm_interrupt_handler

Kevin Hilman (1):
  OMAP3: PM: Enable GPIO module-level wakeups

Paul Walmsley (2):
  OMAP3: PM: PRCM interrupt: check MPUGRPSEL register
  OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts

Vikram Pandita (1):
  OMAP3: PM: USBHOST: clear wakeup events on both hosts

 arch/arm/mach-omap2/pm34xx.c |  187 ++++++++++++++++++++++++------------------
 1 files changed, 106 insertions(+), 81 deletions(-)

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

* [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler
  2009-10-02 18:14 [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
@ 2009-10-02 18:14 ` Kevin Hilman
  2009-10-02 18:14   ` [PATCH 2/5] OMAP3: PM: PRCM interrupt: check MPUGRPSEL register Kevin Hilman
  2009-10-05 17:57 ` [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
  2009-10-05 18:02 ` Kevin Hilman
  2 siblings, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

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

There are two scenarios where a race condition could result in a hang
in the prcm_interrupt handler. These are:

1). Waiting for PRM_IRQSTATUS_MPU register to clear.
Bit 0 of the PRM_IRQSTATUS_MPU register indicates that a wake-up event
is pending for the MPU. This bit can only be cleared if the all the
wake-up events latched in the various PM_WKST_x registers have been
cleared. If a wake-up event occurred during the processing of the prcm
interrupt handler, after the corresponding PM_WKST_x register was
checked but before the PRM_IRQSTATUS_MPU was cleared, then the CPU
would be stuck forever waiting for bit 0 in PRM_IRQSTATUS_MPU to be
cleared.

2). Waiting for the PM_WKST_x register to clear.
Some power domains have more than one wake-up source. The PM_WKST_x
registers indicate the source of a wake-up event and need to be cleared
after a wake-up event occurs. When the PM_WKST_x registers are read and
before they are cleared, it is possible that another wake-up event
could occur causing another bit to be set in one of the PM_WKST_x
registers. If this did occur after reading a PM_WKST_x register then
the CPU would miss this event and get stuck forever in a loop waiting
for that PM_WKST_x register to clear.

This patch address the above race conditions that would result in a
hang.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Reviewed-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |  143 ++++++++++++++++++------------------------
 1 files changed, 60 insertions(+), 83 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ff5a6c..1e7aae2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -51,97 +51,74 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state);
 
 static struct powerdomain *mpu_pwrdm;
 
-/* PRCM Interrupt Handler for wakeups */
-static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+/*
+ * PRCM Interrupt Handler Helper Function
+ *
+ * The purpose of this function is to clear any wake-up events latched
+ * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
+ * may occur whilst attempting to clear a PM_WKST_x register and thus
+ * set another bit in this register. A while loop is used to ensure
+ * that any peripheral wake-up events occurring while attempting to
+ * clear the PM_WKST_x are detected and cleared.
+ */
+static void prcm_clear_mod_irqs(s16 module, u8 regs)
 {
-	u32 wkst, irqstatus_mpu;
-	u32 fclk, iclk;
+	u32 wkst, fclk, iclk;
+	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
+	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
+	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
 
-	/* WKUP */
-	wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
+	wkst = prm_read_mod_reg(module, wkst_off);
 	if (wkst) {
-		iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
-		fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
-		cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
-		cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
-		prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
-		while (prm_read_mod_reg(WKUP_MOD, PM_WKST))
-			cpu_relax();
-		cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
-		cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
-	}
-
-	/* CORE */
-	wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
-	if (wkst) {
-		iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
-		fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
-		cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
-		cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
-		prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
-		while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
-			cpu_relax();
-		cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
-		cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
-	}
-	wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
-	if (wkst) {
-		iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
-		fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-		cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
-		cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-		prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
-		while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
-			cpu_relax();
-		cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
-		cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
-	}
-
-	/* PER */
-	wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
-	if (wkst) {
-		iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
-		fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
-		cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
-		cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
-		prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
-		while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
-			cpu_relax();
-		cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
-		cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
+		iclk = cm_read_mod_reg(module, iclk_off);
+		fclk = cm_read_mod_reg(module, fclk_off);
+		while (wkst) {
+			cm_set_mod_reg_bits(wkst, module, iclk_off);
+			cm_set_mod_reg_bits(wkst, module, fclk_off);
+			prm_write_mod_reg(wkst, module, wkst_off);
+			wkst = prm_read_mod_reg(module, wkst_off);
+		}
+		cm_write_mod_reg(iclk, module, iclk_off);
+		cm_write_mod_reg(fclk, module, fclk_off);
 	}
+}
 
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		/* USBHOST */
-		wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
-		if (wkst) {
-			iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-					       CM_ICLKEN);
-			fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-					       CM_FCLKEN);
-			cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
-					    CM_ICLKEN);
-			cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
-					    CM_FCLKEN);
-			prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
-					  PM_WKST);
-			while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
-						PM_WKST))
-				cpu_relax();
-			cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
-					 CM_ICLKEN);
-			cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
-					 CM_FCLKEN);
+/*
+ * PRCM Interrupt Handler
+ *
+ * The PRM_IRQSTATUS_MPU register indicates if there are any pending
+ * interrupts from the PRCM for the MPU. These bits must be cleared in
+ * order to clear the PRCM interrupt. The PRCM interrupt handler is
+ * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
+ * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
+ * register indicates that a wake-up event is pending for the MPU and
+ * this bit can only be cleared if the all the wake-up events latched
+ * in the various PM_WKST_x registers have been cleared. The interrupt
+ * handler is implemented using a do-while loop so that if a wake-up
+ * event occurred during the processing of the prcm interrupt handler
+ * (setting a bit in the corresponding PM_WKST_x register and thus
+ * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
+ * this would be handled.
+ */
+static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+{
+	u32 irqstatus_mpu;
+
+	do {
+		prcm_clear_mod_irqs(WKUP_MOD, 1);
+		prcm_clear_mod_irqs(CORE_MOD, 1);
+		prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
+		if (omap_rev() > OMAP3430_REV_ES1_0) {
+			prcm_clear_mod_irqs(CORE_MOD, 3);
+			prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
 		}
-	}
 
-	irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
-					 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-	prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
-			  OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+		irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
+					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+		prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
+					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-	while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET))
-		cpu_relax();
+	} while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
 
 	return IRQ_HANDLED;
 }
-- 
1.6.4.3

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

* [PATCH 2/5] OMAP3: PM: PRCM interrupt: check MPUGRPSEL register
  2009-10-02 18:14 ` [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler Kevin Hilman
@ 2009-10-02 18:14   ` Kevin Hilman
  2009-10-02 18:14     ` [PATCH 3/5] OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts Kevin Hilman
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

From: Paul Walmsley <paul@pwsan.com>

PM_WKST register contents should be ANDed with the contents of the
MPUGRPSEL registers.  Otherwise the MPU PRCM interrupt handler could
wind up clearing wakeup events meant for the IVA PRCM interrupt
handler. A future revision to this code should be to read a cached
version of MPUGRPSEL from the powerdomain code, since PRM reads are
relatively slow.

Updated after Jon Hunter's PRCM IRQ change by Kevin Hilman

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 1e7aae2..0e7bd8e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -67,8 +67,11 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
 	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
 	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
 	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
+	u16 grpsel_off = (regs == 3) ?
+		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
 
 	wkst = prm_read_mod_reg(module, wkst_off);
+	wkst &= prm_read_mod_reg(module, grpsel_off);
 	if (wkst) {
 		iclk = cm_read_mod_reg(module, iclk_off);
 		fclk = cm_read_mod_reg(module, fclk_off);
-- 
1.6.4.3

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

* [PATCH 3/5] OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts
  2009-10-02 18:14   ` [PATCH 2/5] OMAP3: PM: PRCM interrupt: check MPUGRPSEL register Kevin Hilman
@ 2009-10-02 18:14     ` Kevin Hilman
  2009-10-02 18:14       ` [PATCH 4/5] OMAP3: PM: USBHOST: clear wakeup events on both hosts Kevin Hilman
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

From: Paul Walmsley <paul@pwsan.com>

Clearing wakeup sources is now only done when the PRM indicates a
wakeup source interrupt.  Since we don't handle any other types of
PRCM interrupts right now, warn if we get any other type of PRCM
interrupt.  Either code needs to be added to the PRCM interrupt
handler to react to these, or these other interrupts should be masked
off at init.

Updated after Jon Hunter's PRCM IRQ rework by Kevin Hilman.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   46 +++++++++++++++++++++++++++++++++--------
 1 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0e7bd8e..d9440a1 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -61,7 +61,7 @@ static struct powerdomain *mpu_pwrdm;
  * that any peripheral wake-up events occurring while attempting to
  * clear the PM_WKST_x are detected and cleared.
  */
-static void prcm_clear_mod_irqs(s16 module, u8 regs)
+static int prcm_clear_mod_irqs(s16 module, u8 regs)
 {
 	u32 wkst, fclk, iclk;
 	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -69,6 +69,7 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
 	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
 	u16 grpsel_off = (regs == 3) ?
 		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
+	int c = 0;
 
 	wkst = prm_read_mod_reg(module, wkst_off);
 	wkst &= prm_read_mod_reg(module, grpsel_off);
@@ -80,10 +81,28 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
 			cm_set_mod_reg_bits(wkst, module, fclk_off);
 			prm_write_mod_reg(wkst, module, wkst_off);
 			wkst = prm_read_mod_reg(module, wkst_off);
+			c++;
 		}
 		cm_write_mod_reg(iclk, module, iclk_off);
 		cm_write_mod_reg(fclk, module, fclk_off);
 	}
+
+	return c;
+}
+
+static int _prcm_int_handle_wakeup(void)
+{
+	int c;
+
+	c = prcm_clear_mod_irqs(WKUP_MOD, 1);
+	c += prcm_clear_mod_irqs(CORE_MOD, 1);
+	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
+	if (omap_rev() > OMAP3430_REV_ES1_0) {
+		c += prcm_clear_mod_irqs(CORE_MOD, 3);
+		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
+	}
+
+	return c;
 }
 
 /*
@@ -106,18 +125,27 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
 static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 {
 	u32 irqstatus_mpu;
+	int c = 0;
 
 	do {
-		prcm_clear_mod_irqs(WKUP_MOD, 1);
-		prcm_clear_mod_irqs(CORE_MOD, 1);
-		prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
-		if (omap_rev() > OMAP3430_REV_ES1_0) {
-			prcm_clear_mod_irqs(CORE_MOD, 3);
-			prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
-		}
-
 		irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
 					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+		if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
+			c = _prcm_int_handle_wakeup();
+
+			/*
+			 * Is the MPU PRCM interrupt handler racing with the
+			 * IVA2 PRCM interrupt handler ?
+			 */
+			WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
+			     "but no wakeup sources are marked\n");
+		} else {
+			/* XXX we need to expand our PRCM interrupt handler */
+			WARN(1, "prcm: WARNING: PRCM interrupt received, but "
+			     "no code to handle it (%08x)\n", irqstatus_mpu);
+		}
+
 		prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
 					OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-- 
1.6.4.3

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

* [PATCH 4/5] OMAP3: PM: USBHOST: clear wakeup events on both hosts
  2009-10-02 18:14     ` [PATCH 3/5] OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts Kevin Hilman
@ 2009-10-02 18:14       ` Kevin Hilman
  2009-10-02 18:14         ` [PATCH 5/5] OMAP3: PM: Enable GPIO module-level wakeups Kevin Hilman
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vikram Pandita <vikram.pandita@ti.com>

USBHOST module has 2 fclocks (for HOST1 and HOST2), only one iclock
and only a single bit in the WKST register to indicate a wakeup event.

Because of the single WKST bit, we cannot know whether a wakeup event
was on HOST1 or HOST2, so enable both fclocks before clearing the
wakeup event to ensure both hosts can properly clear the event.

Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index d9440a1..cf6ea9f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -63,7 +63,7 @@ static struct powerdomain *mpu_pwrdm;
  */
 static int prcm_clear_mod_irqs(s16 module, u8 regs)
 {
-	u32 wkst, fclk, iclk;
+	u32 wkst, fclk, iclk, clken;
 	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
 	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
 	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
@@ -77,8 +77,15 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 		iclk = cm_read_mod_reg(module, iclk_off);
 		fclk = cm_read_mod_reg(module, fclk_off);
 		while (wkst) {
-			cm_set_mod_reg_bits(wkst, module, iclk_off);
-			cm_set_mod_reg_bits(wkst, module, fclk_off);
+			clken = wkst;
+			cm_set_mod_reg_bits(clken, module, iclk_off);
+			/*
+			 * For USBHOST, we don't know whether HOST1 or
+			 * HOST2 woke us up, so enable both f-clocks
+			 */
+			if (module == OMAP3430ES2_USBHOST_MOD)
+				clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
+			cm_set_mod_reg_bits(clken, module, fclk_off);
 			prm_write_mod_reg(wkst, module, wkst_off);
 			wkst = prm_read_mod_reg(module, wkst_off);
 			c++;
-- 
1.6.4.3

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

* [PATCH 5/5] OMAP3: PM: Enable GPIO module-level wakeups
  2009-10-02 18:14       ` [PATCH 4/5] OMAP3: PM: USBHOST: clear wakeup events on both hosts Kevin Hilman
@ 2009-10-02 18:14         ` Kevin Hilman
  0 siblings, 0 replies; 8+ messages in thread
From: Kevin Hilman @ 2009-10-02 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, only GPIOs in the wakeup domain (GPIOs in bank 0) are
enabled as wakups.  This patch also enables GPIOs in the PER
powerdomain (banks 2-6) to be used as possible wakeup sources.

In addition, this patch ensures that all GPIO wakeups can wakeup
the MPU using the PM_MPUGRPSEL_<pwrdm> registers.

NOTE: this doesn't enable the individual GPIOs as wakeups, this simply
enables the per-bank wakeups at the powerdomain level.

This problem was discovered by Mike Chan when preventing the CORE
powerdomain from going into retention/off.  When CORE was allowed to
hit retention, GPIO wakeups via IO pad were working fine, but when
CORE remained on, GPIO module-level wakeups were not working properly.

To test, prevent CORE from going inactive/retention/off, thus
preventing the IO chain from being armed:

  # echo 3 > /debug/pm_debug/core_pwrdm/suspend

This ensures that GPIO wakeups happen via module-level wakeups and
not via IO pad.

Tested on 3430SDP using the touchscreen GPIO (gpio 2, in WKUP)
Tested on Zoom2 using the QUART interrup GPIO  (gpio 102, in PER)

Also, c.f. OMAP PM wiki for troubleshooting GPIO wakeup issues:
http://elinux.org/OMAP_Power_Management

Reported-by: Mike Chan <mikechan@google.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm34xx.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index cf6ea9f..378c2f6 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -639,6 +639,16 @@ static void __init prcm_setup_regs(void)
 	prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
 			  OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 
+	/* Enable GPIO wakeups in PER */
+	prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
+			  OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
+			  OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
+	/* and allow them to wake up MPU */
+	prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
+			  OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
+			  OMAP3430_GRPSEL_GPIO6,
+			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
+
 	/* Don't attach IVA interrupts */
 	prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
 	prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
-- 
1.6.4.3

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

* [PATCH 0/5] OMAP PM fixes for 2.6.32
  2009-10-02 18:14 [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
  2009-10-02 18:14 ` [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler Kevin Hilman
@ 2009-10-05 17:57 ` Kevin Hilman
  2009-10-05 18:02 ` Kevin Hilman
  2 siblings, 0 replies; 8+ messages in thread
From: Kevin Hilman @ 2009-10-05 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

Kevin Hilman <khilman@deeprootsystems.com> writes:

> These fixes are primarily for PRCM interrupt handler bugs
> and GPIO wakeup support.
>
> Jon Hunter (1):
>   OMAP3: PM: Prevent hang in prcm_interrupt_handler
>
> Kevin Hilman (1):
>   OMAP3: PM: Enable GPIO module-level wakeups
>
> Paul Walmsley (2):
>   OMAP3: PM: PRCM interrupt: check MPUGRPSEL register
>   OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts
>
> Vikram Pandita (1):
>   OMAP3: PM: USBHOST: clear wakeup events on both hosts
>

Here's one more for the PM fixes queue from Atrem.

Kevin

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

* [PATCH 0/5] OMAP PM fixes for 2.6.32
  2009-10-02 18:14 [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
  2009-10-02 18:14 ` [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler Kevin Hilman
  2009-10-05 17:57 ` [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
@ 2009-10-05 18:02 ` Kevin Hilman
  2 siblings, 0 replies; 8+ messages in thread
From: Kevin Hilman @ 2009-10-05 18:02 UTC (permalink / raw)
  To: linux-arm-kernel

Tony,

If no other review commeents, this series (incluing patch 6) is based
on v2.6.32-rc1 and available for pull.

Kevin

The following changes since commit 17d857be649a21ca90008c6dc425d849fa83db5c:
  Linus Torvalds (1):
        Linux 2.6.32-rc1

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git pm-fixes-32

Artem Bityutskiy (1):
      OMAP3: PM: introduce a new powerdomain walk helper

Jon Hunter (1):
      OMAP3: PM: Prevent hang in prcm_interrupt_handler

Kevin Hilman (1):
      OMAP3: PM: Enable GPIO module-level wakeups

Paul Walmsley (2):
      OMAP3: PM: PRCM interrupt: check MPUGRPSEL register
      OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts

Vikram Pandita (1):
      OMAP3: PM: USBHOST: clear wakeup events on both hosts

 arch/arm/mach-omap2/pm-debug.c                |    4 +-
 arch/arm/mach-omap2/pm34xx.c                  |  187 ++++++++++++++-----------
 arch/arm/mach-omap2/powerdomain.c             |   39 ++++--
 arch/arm/plat-omap/include/mach/powerdomain.h |    2 +
 4 files changed, 137 insertions(+), 95 deletions(-)

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

end of thread, other threads:[~2009-10-05 18:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-02 18:14 [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
2009-10-02 18:14 ` [PATCH 1/5] OMAP3: PM: Prevent hang in prcm_interrupt_handler Kevin Hilman
2009-10-02 18:14   ` [PATCH 2/5] OMAP3: PM: PRCM interrupt: check MPUGRPSEL register Kevin Hilman
2009-10-02 18:14     ` [PATCH 3/5] OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts Kevin Hilman
2009-10-02 18:14       ` [PATCH 4/5] OMAP3: PM: USBHOST: clear wakeup events on both hosts Kevin Hilman
2009-10-02 18:14         ` [PATCH 5/5] OMAP3: PM: Enable GPIO module-level wakeups Kevin Hilman
2009-10-05 17:57 ` [PATCH 0/5] OMAP PM fixes for 2.6.32 Kevin Hilman
2009-10-05 18:02 ` Kevin Hilman

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