diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c index 36b48c7d59a57..b9a7e4a4ebe9b 100644 --- a/arch/risc-v/src/mpfs/mpfs_irq.c +++ b/arch/risc-v/src/mpfs/mpfs_irq.c @@ -133,13 +133,22 @@ void up_disable_irq(int irq) uintptr_t claim_address = mpfs_plic_get_claimbase(riscv_cpuid_to_hartid(i)); - /* Clear enable bit for the irq */ + /* Clear any already claimed IRQ (this must be done BEFORE + * disabling the interrupt source): + * + * To signal the completion of executing an interrupt handler, the + * processor core writes the received interrupt ID to the + * Claim/Complete register. The PLIC does not check whether the + * completion ID is the same as the last claim ID for that target. + * If the completion ID does not match an interrupt source that is + * currently enabled for the target, the completion is ignored. + */ - modifyreg32(iebase + (4 * (extirq / 32)), 1 << (extirq % 32), 0); + putreg32(extirq, claim_address); - /* Clear any already claimed IRQ */ + /* Clear enable bit for the irq */ - putreg32(extirq, claim_address); + modifyreg32(iebase + (4 * (extirq / 32)), 1 << (extirq % 32), 0); } } }