diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-12-01 11:53:10 +1100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-29 10:21:50 +0100 |
commit | eb0d764eb0f5663b1d93935a72c29c496ec4f5cc (patch) | |
tree | 8b9b9ee2a83f284af73e093a3939c1133ccd2257 /arch/m68k/sun3x | |
parent | 0f8e73eb058750c8cd38be8cbfa048d71c7e2ec5 (diff) |
m68k: Call timer_interrupt() with interrupts disabled
[ Upstream commit 1efdd4bd254311498123a15fa0acd565f454da97 ]
Some platforms execute their timer handler with the interrupt priority
level set below 6. That means the handler could be interrupted by another
driver and this could lead to re-entry of the timer core.
Avoid this by use of local_irq_save/restore for timer interrupt dispatch.
This provides mutual exclusion around the timer interrupt flag access
which is needed later in this series for the clocksource conversion.
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/alpine.DEB.2.21.1811131407120.2697@nanos.tec.linutronix.de
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch/m68k/sun3x')
-rw-r--r-- | arch/m68k/sun3x/time.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c index c8eb08add6b0..7a195313ff4f 100644 --- a/arch/m68k/sun3x/time.c +++ b/arch/m68k/sun3x/time.c @@ -77,15 +77,19 @@ u32 sun3x_gettimeoffset(void) } #if 0 -static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t sun3x_timer_tick(int irq, void *dev_id) { - void (*vector)(int, void *, struct pt_regs *) = dev_id; + irq_handler_t timer_routine = dev_id; + unsigned long flags; - /* Clear the pending interrupt - pulse the enable line low */ - disable_irq(5); - enable_irq(5); + local_irq_save(flags); + /* Clear the pending interrupt - pulse the enable line low */ + disable_irq(5); + enable_irq(5); + timer_routine(0, NULL); + local_irq_restore(flags); - vector(irq, NULL, regs); + return IRQ_HANDLED; } #endif |