diff options
author | Tony Lindgren <tony@atomide.com> | 2006-09-25 05:41:40 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2006-09-25 05:41:40 -0400 |
commit | 14188b3a4cbffd317ac65434750481d2ee14e09e (patch) | |
tree | 96749861adc371357a0ea873987b6f2782cacea6 /arch | |
parent | e4d5ee8109c210b65becfc1ef7697a0ce4eaf3c4 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-omap/timer32k.c | 26 |
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 | */ |
197 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | 197 | static 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 | |||
221 | static 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 | |||
227 | static 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 | ||