aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-07-22 10:29:02 -0700
committerKevin Hilman <khilman@deeprootsystems.com>2009-10-05 10:51:00 -0700
commit8cb0ac999f253212bb01cd3c0d686489ec5911ad (patch)
treef0fe5a692b1d4a9b85ade98fe8c628b0fa671ce3 /arch/arm
parent5d80597801ff0d7e6b184504c04e9c1b3b61d16d (diff)
OMAP3: PM: PRCM interrupt: only handle selected PRCM interrupts
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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/pm34xx.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0e7bd8e55f7..d9440a18bd0 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);