it8xxx2: intc: Look for pending interrupt

The AIVECT (All Interrupt Vector Register) register provides us a quick
way to determine SOC interrupt number. But sometimes we get interrupt
number 0 from the register and caused assertion of unhandled interrupt.
To avoid the assertion, we look for all ISRs (Interrupt Status Register)
and IERs (Interrupt Enable Register) to find the highest priority pending
interrupt and return it to caller.

Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
This commit is contained in:
Dino Li 2022-06-28 18:12:05 +08:00 committed by Carles Cufí
commit 7c7611d17d

View file

@ -7,6 +7,8 @@
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/init.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(intc_it8xxx2, LOG_LEVEL_DBG);
#include <zephyr/sys/printk.h>
#include <zephyr/sw_isr_table.h>
#include "intc_ite_it8xxx2.h"
@ -206,6 +208,25 @@ uint8_t get_irq(void *arg)
} while (intc_irq != IVECT);
/* determine interrupt number */
intc_irq -= IVECT_OFFSET_WITH_IRQ;
/*
* Look for pending interrupt if there's interrupt number 0 from
* the AIVECT register.
*/
if (intc_irq == 0) {
uint8_t int_pending;
for (int i = (IT8XXX2_IER_COUNT - 1); i >= 0; i--) {
int_pending = (*reg_status[i] & *reg_enable[i]);
if (int_pending != 0) {
intc_irq = (MAX_REGISR_IRQ_NUM * i) +
find_msb_set(int_pending) - 1;
LOG_DBG("Pending interrupt found: %d",
intc_irq);
LOG_DBG("CPU mepc: 0x%lx", csr_read(mepc));
break;
}
}
}
/* clear interrupt status */
ite_intc_isr_clear(intc_irq);
/* return interrupt number */