diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | 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 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 | */ |
64 | static void prcm_clear_mod_irqs(s16 module, u8 regs) | 64 | static 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 | |||
93 | static 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) | |||
106 | static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | 125 | static 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 | ||