diff options
author | Tony Lindgren <tony@atomide.com> | 2011-12-16 17:00:23 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-12-16 17:00:23 -0500 |
commit | 9d297f5ee1b92a84e2cd6c547c3ac1f893128359 (patch) | |
tree | cff90b5421967f17d11a7611a9c5f0fca0be4d67 /arch/arm/mach-omap2/prm44xx.c | |
parent | aacf094128759cfb29a3ce88f92d08b79b74a4e8 (diff) | |
parent | 2f31b51659c2d8315ea2888ba5b93076febe672b (diff) |
Merge branch 'tk_prm_chain_handler_devel_3.3' of git://git.pwsan.com/linux-2.6 into prcm
Conflicts:
arch/arm/mach-omap2/Makefile
Diffstat (limited to 'arch/arm/mach-omap2/prm44xx.c')
-rw-r--r-- | arch/arm/mach-omap2/prm44xx.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index dd885eecf22a..33dd655e6aab 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -27,6 +27,24 @@ | |||
27 | #include "prcm44xx.h" | 27 | #include "prcm44xx.h" |
28 | #include "prminst44xx.h" | 28 | #include "prminst44xx.h" |
29 | 29 | ||
30 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { | ||
31 | OMAP_PRCM_IRQ("wkup", 0, 0), | ||
32 | OMAP_PRCM_IRQ("io", 9, 1), | ||
33 | }; | ||
34 | |||
35 | static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { | ||
36 | .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, | ||
37 | .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET, | ||
38 | .nr_regs = 2, | ||
39 | .irqs = omap4_prcm_irqs, | ||
40 | .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), | ||
41 | .irq = OMAP44XX_IRQ_PRCM, | ||
42 | .read_pending_irqs = &omap44xx_prm_read_pending_irqs, | ||
43 | .ocp_barrier = &omap44xx_prm_ocp_barrier, | ||
44 | .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, | ||
45 | .restore_irqen = &omap44xx_prm_restore_irqen, | ||
46 | }; | ||
47 | |||
30 | /* PRM low-level functions */ | 48 | /* PRM low-level functions */ |
31 | 49 | ||
32 | /* Read a register in a CM/PRM instance in the PRM module */ | 50 | /* Read a register in a CM/PRM instance in the PRM module */ |
@@ -121,3 +139,101 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) | |||
121 | OMAP4430_PRM_DEVICE_INST, | 139 | OMAP4430_PRM_DEVICE_INST, |
122 | offset); | 140 | offset); |
123 | } | 141 | } |
142 | |||
143 | static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) | ||
144 | { | ||
145 | u32 mask, st; | ||
146 | |||
147 | /* XXX read mask from RAM? */ | ||
148 | mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs); | ||
149 | st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs); | ||
150 | |||
151 | return mask & st; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events | ||
156 | * @events: ptr to two consecutive u32s, preallocated by caller | ||
157 | * | ||
158 | * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM | ||
159 | * MPU IRQs, and store the result into the two u32s pointed to by @events. | ||
160 | * No return value. | ||
161 | */ | ||
162 | void omap44xx_prm_read_pending_irqs(unsigned long *events) | ||
163 | { | ||
164 | events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, | ||
165 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | ||
166 | |||
167 | events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET, | ||
168 | OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete | ||
173 | * | ||
174 | * Force any buffered writes to the PRM IP block to complete. Needed | ||
175 | * by the PRM IRQ handler, which reads and writes directly to the IP | ||
176 | * block, to avoid race conditions after acknowledging or clearing IRQ | ||
177 | * bits. No return value. | ||
178 | */ | ||
179 | void omap44xx_prm_ocp_barrier(void) | ||
180 | { | ||
181 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
182 | OMAP4_REVISION_PRM_OFFSET); | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs | ||
187 | * @saved_mask: ptr to a u32 array to save IRQENABLE bits | ||
188 | * | ||
189 | * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to | ||
190 | * @saved_mask. @saved_mask must be allocated by the caller. | ||
191 | * Intended to be used in the PRM interrupt handler suspend callback. | ||
192 | * The OCP barrier is needed to ensure the write to disable PRM | ||
193 | * interrupts reaches the PRM before returning; otherwise, spurious | ||
194 | * interrupts might occur. No return value. | ||
195 | */ | ||
196 | void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) | ||
197 | { | ||
198 | saved_mask[0] = | ||
199 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
200 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | ||
201 | saved_mask[1] = | ||
202 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
203 | OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | ||
204 | |||
205 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, | ||
206 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | ||
207 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, | ||
208 | OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); | ||
209 | |||
210 | /* OCP barrier */ | ||
211 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
212 | OMAP4_REVISION_PRM_OFFSET); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args | ||
217 | * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously | ||
218 | * | ||
219 | * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from | ||
220 | * @saved_mask. Intended to be used in the PRM interrupt handler resume | ||
221 | * callback to restore values saved by omap44xx_prm_save_and_clear_irqen(). | ||
222 | * No OCP barrier should be needed here; any pending PRM interrupts will fire | ||
223 | * once the writes reach the PRM. No return value. | ||
224 | */ | ||
225 | void omap44xx_prm_restore_irqen(u32 *saved_mask) | ||
226 | { | ||
227 | omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST, | ||
228 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | ||
229 | omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST, | ||
230 | OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); | ||
231 | } | ||
232 | |||
233 | static int __init omap4xxx_prcm_init(void) | ||
234 | { | ||
235 | if (cpu_is_omap44xx()) | ||
236 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); | ||
237 | return 0; | ||
238 | } | ||
239 | subsys_initcall(omap4xxx_prcm_init); | ||