summaryrefslogtreecommitdiffstats
path: root/arch/m68k/sun3x
diff options
context:
space:
mode:
authorFinn Thain2018-12-01 01:53:10 +0100
committerGeert Uytterhoeven2019-03-25 10:22:24 +0100
commit1efdd4bd254311498123a15fa0acd565f454da97 (patch)
tree6eed2d1e020561326c3754973e588c947673a5b0 /arch/m68k/sun3x
parentLinux 5.1-rc1 (diff)
downloadkernel-qcow2-linux-1efdd4bd254311498123a15fa0acd565f454da97.tar.gz
kernel-qcow2-linux-1efdd4bd254311498123a15fa0acd565f454da97.tar.xz
kernel-qcow2-linux-1efdd4bd254311498123a15fa0acd565f454da97.zip
m68k: Call timer_interrupt() with interrupts disabled
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>
Diffstat (limited to 'arch/m68k/sun3x')
-rw-r--r--arch/m68k/sun3x/time.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
index 047e2bcee3d7..3c8a86d08508 100644
--- a/arch/m68k/sun3x/time.c
+++ b/arch/m68k/sun3x/time.c
@@ -80,15 +80,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