From 064ce3a17203f7c07d688aaad005f59aee96c3a9 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sat, 1 Dec 2018 11:53:10 +1100 Subject: 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 Link: http://lkml.kernel.org/r/alpine.DEB.2.21.1811131407120.2697@nanos.tec.linutronix.de Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/mvme16x/config.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'arch/m68k/mvme16x/config.c') diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 58e240939d26..ac49fa7ec46b 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -51,11 +51,6 @@ extern void mvme16x_reset (void); int bcd2int (unsigned char b); -/* Save tick handler routine pointer, will point to xtime_update() in - * kernel/time/timekeeping.c, called via mvme16x_process_int() */ - -static irq_handler_t tick_handler; - unsigned short mvme16x_config; EXPORT_SYMBOL(mvme16x_config); @@ -354,8 +349,15 @@ static irqreturn_t mvme16x_abort_int (int irq, void *dev_id) static irqreturn_t mvme16x_timer_int (int irq, void *dev_id) { - *(volatile unsigned char *)0xfff4201b |= 8; - return tick_handler(irq, dev_id); + irq_handler_t timer_routine = dev_id; + unsigned long flags; + + local_irq_save(flags); + *(volatile unsigned char *)0xfff4201b |= 8; + timer_routine(0, NULL); + local_irq_restore(flags); + + return IRQ_HANDLED; } void mvme16x_sched_init (irq_handler_t timer_routine) @@ -363,14 +365,13 @@ void mvme16x_sched_init (irq_handler_t timer_routine) uint16_t brdno = be16_to_cpu(mvme_bdid.brdno); int irq; - tick_handler = timer_routine; /* Using PCCchip2 or MC2 chip tick timer 1 */ *(volatile unsigned long *)0xfff42008 = 0; *(volatile unsigned long *)0xfff42004 = 10000; /* 10ms */ *(volatile unsigned char *)0xfff42017 |= 3; *(volatile unsigned char *)0xfff4201b = 0x16; - if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, 0, - "timer", mvme16x_timer_int)) + if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, 0, "timer", + timer_routine)) panic ("Couldn't register timer int"); if (brdno == 0x0162 || brdno == 0x172) -- cgit v1.2.3