From d411514a5f5b943063c10e0e39989b3da5b4b0e1 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Wed, 14 Nov 2018 11:49:53 -0800 Subject: [PATCH] xtensa: Don't call ISRs for disabled interrupts Xtensa interrupts are handled generically, by testing a set of flagged interrupts in the INTERRUPT register. It's not possible to know exactly which device "caused" an interrupt. The entry code was dispatching correctly, but it was failing to test the enable state in INTENABLE. Such an interrupt will never "fire", but it might still be flagged, and if we happen to end up handling an interrupt of the same priority (due to some other device) the entry handler would incorrectly invoke the disabled interrupt. Found by dumb luck and a comedy of errors: the recent timer driver change swapped the counter in use, which changed the interrupt number to one shared with the I2C driver, whose early interrupts (odd that this device is interrupting on boot when not in use, but whatever) would then discover the OTHER timer counter had been flagged and try to invoke an ISR for that other counter, which was the _irq_spurious() spurious interrupt handler. Signed-off-by: Andy Ross --- arch/xtensa/core/xtensa-asm2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/core/xtensa-asm2.c b/arch/xtensa/core/xtensa-asm2.c index 078f789b3c8..feb2b8ee949 100644 --- a/arch/xtensa/core/xtensa-asm2.c +++ b/arch/xtensa/core/xtensa-asm2.c @@ -135,9 +135,10 @@ static void dump_stack(int *stack) #define DEF_INT_C_HANDLER(l) \ void *xtensa_int##l##_c(void *interrupted_stack) \ { \ - int irqs, m; \ + u32_t irqs, intenable, m; \ __asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \ - \ + __asm__ volatile("rsr.intenable %0" : "=r"(intenable)); \ + irqs &= intenable; \ while ((m = _xtensa_handle_one_int##l(irqs))) { \ irqs ^= m; \ __asm__ volatile("wsr.intclear %0" : : "r"(m)); \