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:
parent
bf37acc3c0
commit
7c7611d17d
1 changed files with 21 additions and 0 deletions
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue