diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-12-01 03:53:10 +0300 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2019-03-25 12:22:24 +0300 |
commit | 1efdd4bd254311498123a15fa0acd565f454da97 (patch) | |
tree | 6eed2d1e020561326c3754973e588c947673a5b0 /arch/m68k/amiga | |
parent | 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b (diff) | |
download | linux-1efdd4bd254311498123a15fa0acd565f454da97.tar.xz |
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/amiga')
-rw-r--r-- | arch/m68k/amiga/cia.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 2081b8cd5591..b9aee983e6f4 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -88,10 +88,19 @@ static irqreturn_t cia_handler(int irq, void *dev_id) struct ciabase *base = dev_id; int mach_irq; unsigned char ints; + unsigned long flags; + /* Interrupts get disabled while the timer irq flag is cleared and + * the timer interrupt serviced. + */ mach_irq = base->cia_irq; + local_irq_save(flags); ints = cia_set_irq(base, CIA_ICR_ALL); amiga_custom.intreq = base->int_mask; + if (ints & 1) + generic_handle_irq(mach_irq); + local_irq_restore(flags); + mach_irq++, ints >>= 1; for (; ints; mach_irq++, ints >>= 1) { if (ints & 1) generic_handle_irq(mach_irq); |