aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-07-22 13:29:02 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-10-05 13:51:00 -0400
commit8cb0ac999f253212bb01cd3c0d686489ec5911ad (patch)
treef0fe5a692b1d4a9b85ade98fe8c628b0fa671ce3 /arch/arm/mach-omap2/pm34xx.c
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/mach-omap2/pm34xx.c')
-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 0e7bd8e55f76..d9440a18bd00 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -61,7 +61,7 @@ static struct powerdomain *mpu_pwrdm;
61 * that any peripheral wake-up events occurring while attempting to 61 * that any peripheral wake-up events occurring while attempting to
62 * clear the PM_WKST_x are detected and cleared. 62 * clear the PM_WKST_x are detected and cleared.
63 */ 63 */
64static void prcm_clear_mod_irqs(s16 module, u8 regs) 64static int prcm_clear_mod_irqs(s16 module, u8 regs)
65{ 65{
66 u32 wkst, fclk, iclk; 66 u32 wkst, fclk, iclk;
67 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; 67 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -69,6 +69,7 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
69 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1; 69 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
70 u16 grpsel_off = (regs == 3) ? 70 u16 grpsel_off = (regs == 3) ?
71 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL; 71 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
72 int c = 0;
72 73
73 wkst = prm_read_mod_reg(module, wkst_off); 74 wkst = prm_read_mod_reg(module, wkst_off);
74 wkst &= prm_read_mod_reg(module, grpsel_off); 75 wkst &= prm_read_mod_reg(module, grpsel_off);
@@ -80,10 +81,28 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
80 cm_set_mod_reg_bits(wkst, module, fclk_off); 81 cm_set_mod_reg_bits(wkst, module, fclk_off);
81 prm_write_mod_reg(wkst, module, wkst_off); 82 prm_write_mod_reg(wkst, module, wkst_off);
82 wkst = prm_read_mod_reg(module, wkst_off); 83 wkst = prm_read_mod_reg(module, wkst_off);
84 c++;
83 } 85 }
84 cm_write_mod_reg(iclk, module, iclk_off); 86 cm_write_mod_reg(iclk, module, iclk_off);
85 cm_write_mod_reg(fclk, module, fclk_off); 87 cm_write_mod_reg(fclk, module, fclk_off);
86 } 88 }
89
90 return c;
91}
92
93static int _prcm_int_handle_wakeup(void)
94{
95 int c;
96
97 c = prcm_clear_mod_irqs(WKUP_MOD, 1);
98 c += prcm_clear_mod_irqs(CORE_MOD, 1);
99 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
100 if (omap_rev() > OMAP3430_REV_ES1_0) {
101 c += prcm_clear_mod_irqs(CORE_MOD, 3);
102 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
103 }
104
105 return c;
87} 106}
88 107
89/* 108/*
@@ -106,18 +125,27 @@ static void prcm_clear_mod_irqs(s16 module, u8 regs)
106static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) 125static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
107{ 126{
108 u32 irqstatus_mpu; 127 u32 irqstatus_mpu;
128 int c = 0;
109 129
110 do { 130 do {
111 prcm_clear_mod_irqs(WKUP_MOD, 1);
112 prcm_clear_mod_irqs(CORE_MOD, 1);
113 prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
114 if (omap_rev() > OMAP3430_REV_ES1_0) {
115 prcm_clear_mod_irqs(CORE_MOD, 3);
116 prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
117 }
118
119 irqstatus_mpu = prm_read_mod_reg(OCP_MOD, 131 irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
120 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 132 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
133
134 if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
135 c = _prcm_int_handle_wakeup();
136
137 /*
138 * Is the MPU PRCM interrupt handler racing with the
139 * IVA2 PRCM interrupt handler ?
140 */
141 WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
142 "but no wakeup sources are marked\n");
143 } else {
144 /* XXX we need to expand our PRCM interrupt handler */
145 WARN(1, "prcm: WARNING: PRCM interrupt received, but "
146 "no code to handle it (%08x)\n", irqstatus_mpu);
147 }
148
121 prm_write_mod_reg(irqstatus_mpu, OCP_MOD, 149 prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
122 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 150 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
123 151