aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2006-09-25 05:41:40 -0400
committerTony Lindgren <tony@atomide.com>2006-09-25 05:41:40 -0400
commit14188b3a4cbffd317ac65434750481d2ee14e09e (patch)
tree96749861adc371357a0ea873987b6f2782cacea6
parente4d5ee8109c210b65becfc1ef7697a0ce4eaf3c4 (diff)
ARM: OMAP: Fix spinlock recursion for dyntick
Fix spinlock recursion for dyntick. Modified version based on Imre Deak's earlier patch. Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/plat-omap/timer32k.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
index f7b4e89de518..cf6df3378d37 100644
--- a/arch/arm/plat-omap/timer32k.c
+++ b/arch/arm/plat-omap/timer32k.c
@@ -194,14 +194,11 @@ unsigned long long sched_clock(void)
194 * issues with dynamic tick. In the dynamic tick case, we need to lock 194 * issues with dynamic tick. In the dynamic tick case, we need to lock
195 * with irqsave. 195 * with irqsave.
196 */ 196 */
197static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, 197static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
198 struct pt_regs *regs) 198 struct pt_regs *regs)
199{ 199{
200 unsigned long flags;
201 unsigned long now; 200 unsigned long now;
202 201
203 write_seqlock_irqsave(&xtime_lock, flags);
204
205 omap_32k_timer_ack_irq(); 202 omap_32k_timer_ack_irq();
206 now = omap_32k_sync_timer_read(); 203 now = omap_32k_sync_timer_read();
207 204
@@ -217,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
217 * continuous timer can be overridden from pm_idle to be longer. 214 * continuous timer can be overridden from pm_idle to be longer.
218 */ 215 */
219 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); 216 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
217
218 return IRQ_HANDLED;
219}
220
221static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id,
222 struct pt_regs *regs)
223{
224 return _omap_32k_timer_interrupt(irq, dev_id, regs);
225}
226
227static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
228 struct pt_regs *regs)
229{
230 unsigned long flags;
231
232 write_seqlock_irqsave(&xtime_lock, flags);
233 _omap_32k_timer_interrupt(irq, dev_id, regs);
220 write_sequnlock_irqrestore(&xtime_lock, flags); 234 write_sequnlock_irqrestore(&xtime_lock, flags);
221 235
222 return IRQ_HANDLED; 236 return IRQ_HANDLED;
@@ -262,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = {
262 .enable = omap_32k_timer_enable_dyn_tick, 276 .enable = omap_32k_timer_enable_dyn_tick,
263 .disable = omap_32k_timer_disable_dyn_tick, 277 .disable = omap_32k_timer_disable_dyn_tick,
264 .reprogram = omap_32k_timer_reprogram, 278 .reprogram = omap_32k_timer_reprogram,
265 .handler = omap_32k_timer_interrupt, 279 .handler = omap_32k_timer_handler,
266}; 280};
267#endif /* CONFIG_NO_IDLE_HZ */ 281#endif /* CONFIG_NO_IDLE_HZ */
268 282