summaryrefslogtreecommitdiff
path: root/arch/m68k/mvme147/config.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-12-01 11:53:10 +1100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-27 14:51:23 +0100
commita825e9a7ced544fafc7fdf23cc19ff7216d518ac (patch)
tree02446b368099653a2e143cbd3a4124d433cbc0e3 /arch/m68k/mvme147/config.c
parent283163a39a7923da0509270139f6bd48fc82cca9 (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/mvme147/config.c')
-rw-r--r--arch/m68k/mvme147/config.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index adea549d240e..93c68d2b8e0e 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -45,11 +45,6 @@ extern void mvme147_reset (void);
static int bcd2int (unsigned char b);
-/* Save tick handler routine pointer, will point to xtime_update() in
- * kernel/time/timekeeping.c, called via mvme147_process_int() */
-
-irq_handler_t tick_handler;
-
int __init mvme147_parse_bootinfo(const struct bi_record *bi)
{
@@ -104,16 +99,23 @@ void __init config_mvme147(void)
static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
{
+ irq_handler_t timer_routine = dev_id;
+ unsigned long flags;
+
+ local_irq_save(flags);
m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
- return tick_handler(irq, dev_id);
+ timer_routine(0, NULL);
+ local_irq_restore(flags);
+
+ return IRQ_HANDLED;
}
void mvme147_sched_init (irq_handler_t timer_routine)
{
- tick_handler = timer_routine;
- if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL))
+ if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1",
+ timer_routine))
pr_err("Couldn't register timer interrupt\n");
/* Init the clock with a value */