aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2014-02-25 08:40:30 -0500
committerTero Kristo <t-kristo@ti.com>2014-07-04 10:02:00 -0400
commit0efc0f6ec2d6c6497e401df171705c5762f5a061 (patch)
treefbe9d4c8e36c64dcf2c36fed671ac53fe2e82e55
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
ARM: OMAP3: PRM: move prcm wakeup helper to prm driver
Done in preparation to make the prm an individual driver. Signed-off-by: Tero Kristo <t-kristo@ti.com>
-rw-r--r--arch/arm/mach-omap2/pm34xx.c66
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c53
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h1
3 files changed, 64 insertions, 56 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 507d8eeaab95..74d03f26d962 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -133,60 +133,13 @@ static void omap3_save_secure_ram_context(void)
133 } 133 }
134} 134}
135 135
136/*
137 * PRCM Interrupt Handler Helper Function
138 *
139 * The purpose of this function is to clear any wake-up events latched
140 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
141 * may occur whilst attempting to clear a PM_WKST_x register and thus
142 * set another bit in this register. A while loop is used to ensure
143 * that any peripheral wake-up events occurring while attempting to
144 * clear the PM_WKST_x are detected and cleared.
145 */
146static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
147{
148 u32 wkst, fclk, iclk, clken;
149 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
150 u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
151 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
152 u16 grpsel_off = (regs == 3) ?
153 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
154 int c = 0;
155
156 wkst = omap2_prm_read_mod_reg(module, wkst_off);
157 wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
158 wkst &= ~ignore_bits;
159 if (wkst) {
160 iclk = omap2_cm_read_mod_reg(module, iclk_off);
161 fclk = omap2_cm_read_mod_reg(module, fclk_off);
162 while (wkst) {
163 clken = wkst;
164 omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
165 /*
166 * For USBHOST, we don't know whether HOST1 or
167 * HOST2 woke us up, so enable both f-clocks
168 */
169 if (module == OMAP3430ES2_USBHOST_MOD)
170 clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
171 omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
172 omap2_prm_write_mod_reg(wkst, module, wkst_off);
173 wkst = omap2_prm_read_mod_reg(module, wkst_off);
174 wkst &= ~ignore_bits;
175 c++;
176 }
177 omap2_cm_write_mod_reg(iclk, module, iclk_off);
178 omap2_cm_write_mod_reg(fclk, module, fclk_off);
179 }
180
181 return c;
182}
183
184static irqreturn_t _prcm_int_handle_io(int irq, void *unused) 136static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
185{ 137{
186 int c; 138 int c;
187 139
188 c = prcm_clear_mod_irqs(WKUP_MOD, 1, 140 c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1,
189 ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); 141 ~(OMAP3430_ST_IO_MASK |
142 OMAP3430_ST_IO_CHAIN_MASK));
190 143
191 return c ? IRQ_HANDLED : IRQ_NONE; 144 return c ? IRQ_HANDLED : IRQ_NONE;
192} 145}
@@ -200,13 +153,14 @@ static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
200 * these are handled in a separate handler to avoid acking 153 * these are handled in a separate handler to avoid acking
201 * IO events before parsing in mux code 154 * IO events before parsing in mux code
202 */ 155 */
203 c = prcm_clear_mod_irqs(WKUP_MOD, 1, 156 c = omap3xxx_prm_clear_mod_irqs(WKUP_MOD, 1,
204 OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); 157 OMAP3430_ST_IO_MASK |
205 c += prcm_clear_mod_irqs(CORE_MOD, 1, 0); 158 OMAP3430_ST_IO_CHAIN_MASK);
206 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); 159 c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 1, 0);
160 c += omap3xxx_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
207 if (omap_rev() > OMAP3430_REV_ES1_0) { 161 if (omap_rev() > OMAP3430_REV_ES1_0) {
208 c += prcm_clear_mod_irqs(CORE_MOD, 3, 0); 162 c += omap3xxx_prm_clear_mod_irqs(CORE_MOD, 3, 0);
209 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); 163 c += omap3xxx_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
210 } 164 }
211 165
212 return c ? IRQ_HANDLED : IRQ_NONE; 166 return c ? IRQ_HANDLED : IRQ_NONE;
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index 4bd7a2dca8af..014ba70d2dfb 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -26,6 +26,8 @@
26#include "prm2xxx_3xxx.h" 26#include "prm2xxx_3xxx.h"
27#include "cm2xxx_3xxx.h" 27#include "cm2xxx_3xxx.h"
28#include "prm-regbits-34xx.h" 28#include "prm-regbits-34xx.h"
29#include "cm3xxx.h"
30#include "cm-regbits-34xx.h"
29 31
30static const struct omap_prcm_irq omap3_prcm_irqs[] = { 32static const struct omap_prcm_irq omap3_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0), 33 OMAP_PRCM_IRQ("wkup", 0, 0),
@@ -206,6 +208,57 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
206} 208}
207 209
208/** 210/**
211 * omap3xxx_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
212 * @module: PRM module to clear wakeups from
213 * @regs: register set to clear, 1 or 3
214 * @ignore_bits: wakeup status bits to ignore
215 *
216 * The purpose of this function is to clear any wake-up events latched
217 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
218 * may occur whilst attempting to clear a PM_WKST_x register and thus
219 * set another bit in this register. A while loop is used to ensure
220 * that any peripheral wake-up events occurring while attempting to
221 * clear the PM_WKST_x are detected and cleared.
222 */
223int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
224{
225 u32 wkst, fclk, iclk, clken;
226 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
227 u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
228 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
229 u16 grpsel_off = (regs == 3) ?
230 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
231 int c = 0;
232
233 wkst = omap2_prm_read_mod_reg(module, wkst_off);
234 wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
235 wkst &= ~ignore_bits;
236 if (wkst) {
237 iclk = omap2_cm_read_mod_reg(module, iclk_off);
238 fclk = omap2_cm_read_mod_reg(module, fclk_off);
239 while (wkst) {
240 clken = wkst;
241 omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
242 /*
243 * For USBHOST, we don't know whether HOST1 or
244 * HOST2 woke us up, so enable both f-clocks
245 */
246 if (module == OMAP3430ES2_USBHOST_MOD)
247 clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
248 omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
249 omap2_prm_write_mod_reg(wkst, module, wkst_off);
250 wkst = omap2_prm_read_mod_reg(module, wkst_off);
251 wkst &= ~ignore_bits;
252 c++;
253 }
254 omap2_cm_write_mod_reg(iclk, module, iclk_off);
255 omap2_cm_write_mod_reg(fclk, module, fclk_off);
256 }
257
258 return c;
259}
260
261/**
209 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain 262 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
210 * 263 *
211 * Clear any previously-latched I/O wakeup events and ensure that the 264 * Clear any previously-latched I/O wakeup events and ensure that the
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index 1dacfc5b1959..14a5fbc8ac57 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -162,6 +162,7 @@ extern void omap3xxx_prm_dpll3_reset(void);
162 162
163extern int __init omap3xxx_prm_init(void); 163extern int __init omap3xxx_prm_init(void);
164extern u32 omap3xxx_prm_get_reset_sources(void); 164extern u32 omap3xxx_prm_get_reset_sources(void);
165int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits);
165 166
166#endif /* __ASSEMBLER */ 167#endif /* __ASSEMBLER */
167 168