Skip to content

Commit

Permalink
it8xxx2: re-factor idle routine
Browse files Browse the repository at this point in the history
Don't leave idle state if soc isn't waked-up by an interrupt.
(We change to check interrupt controller register)

Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
  • Loading branch information
Dino-Li authored and MaureenHelm committed Apr 1, 2022
1 parent af2e765 commit 5b9db5a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 26 deletions.
7 changes: 5 additions & 2 deletions drivers/interrupt_controller/intc_ite_it8xxx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ uint8_t ite_intc_get_irq_num(void)
return intc_irq;
}

bool ite_intc_no_irq(void)
{
return (IVECT == IVECT_OFFSET_WITH_IRQ);
}

uint8_t get_irq(void *arg)
{
ARG_UNUSED(arg);
Expand All @@ -197,8 +202,6 @@ uint8_t get_irq(void *arg)
intc_irq -= IVECT_OFFSET_WITH_IRQ;
/* clear interrupt status */
ite_intc_isr_clear(intc_irq);
/* Clear flag on each interrupt. */
wait_interrupt_fired = 0;
/* return interrupt number */
return intc_irq;
}
Expand Down
3 changes: 0 additions & 3 deletions drivers/interrupt_controller/intc_ite_it8xxx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,4 @@
#include <dt-bindings/interrupt-controller/ite-intc.h>
#include <soc.h>

/* use data type int here not bool to get better instruction number. */
volatile int wait_interrupt_fired;

#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_ITE_IT8XXX2_H_ */
1 change: 1 addition & 0 deletions soc/riscv/riscv-ite/common/soc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern int ite_intc_irq_is_enable(unsigned int irq);
extern void ite_intc_irq_polarity_set(unsigned int irq, unsigned int flags);
extern void ite_intc_isr_clear(unsigned int irq);
void ite_intc_init(void);
bool ite_intc_no_irq(void);
#endif /* CONFIG_ITE_IT8XXX2_INTC */

#ifdef CONFIG_SOC_IT8XXX2_PLL_FLASH_48M
Expand Down
46 changes: 25 additions & 21 deletions soc/riscv/riscv-ite/it8xxx2/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,36 +176,40 @@ BUILD_ASSERT(CONFIG_FLASH_INIT_PRIORITY < CONFIG_IT8XXX2_PLL_SEQUENCE_PRIORITY,
"CONFIG_FLASH_INIT_PRIORITY must be less than CONFIG_IT8XXX2_PLL_SEQUENCE_PRIORITY");
#endif /* CONFIG_SOC_IT8XXX2_PLL_FLASH_48M */

extern volatile int wait_interrupt_fired;

/* The routine must be called with interrupts locked */
void riscv_idle(enum chip_pll_mode mode, unsigned int key)
{
/* Disable M-mode external interrupt */
/*
* The routine is called with interrupts locked (in kernel/idle()).
* But on kernel/context test_kernel_cpu_idle test, the routine will be
* called without interrupts locked. Hence we disable M-mode external
* interrupt here to protect the below content.
*/
csr_clear(mie, MIP_MEIP);

sys_trace_idle();
/* Chip doze after wfi instruction */
chip_pll_ctrl(mode);
/* Set flag before entering low power mode. */
wait_interrupt_fired = 1;
/* unlock interrupts */
irq_unlock(key);
/* Wait for interrupt */
__asm__ volatile ("wfi");

/* Enable M-mode external interrupt */
csr_set(mie, MIP_MEIP);
do {
/* Wait for interrupt */
__asm__ volatile ("wfi");
/*
* Sometimes wfi instruction may fail due to CPU's MTIP@mip
* register is non-zero.
* If the ite_intc_no_irq() is true at this point,
* it means that EC waked-up by the above issue not an
* interrupt. Hence we loop running wfi instruction here until
* wfi success.
*/
} while (ite_intc_no_irq());

/*
* Sometimes wfi instruction may fail due to CPU's MTIP@mip
* register is non-zero.
* If the wait_interrupt_fired flag is true at this point,
* it means that EC waked-up by the above issue not an
* interrupt. Hence we loop running wfi instruction here until
* wfi success.
* Enable M-mode external interrupt
* An interrupt can not be fired yet until we enable global interrupt
*/
while (wait_interrupt_fired) {
__asm__ volatile ("wfi");
}
csr_set(mie, MIP_MEIP);
/* Restore global interrupt lockout state */
irq_unlock(key);
}

void arch_cpu_idle(void)
Expand Down

0 comments on commit 5b9db5a

Please sign in to comment.