diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index 8ba7b615b42..3d18ec59dba 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_RISCV_HAS_PLIC #include @@ -75,3 +76,19 @@ int arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, } #endif /* CONFIG_SHARED_INTERRUPTS */ #endif /* CONFIG_DYNAMIC_INTERRUPTS */ + +#ifdef CONFIG_PM +void arch_isr_direct_pm(void) +{ + unsigned int key; + + key = irq_lock(); + + if (_kernel.idle) { + _kernel.idle = 0; + pm_system_resume(); + } + + irq_unlock(key); +} +#endif diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c index 4e122363508..df59b9f6d4b 100644 --- a/drivers/timer/nrf_grtc_timer.c +++ b/drivers/timer/nrf_grtc_timer.c @@ -459,12 +459,27 @@ uint32_t sys_clock_elapsed(void) return (uint32_t)(counter_sub(counter(), last_count) / CYC_PER_TICK); } +#if !defined(CONFIG_GEN_SW_ISR_TABLE) +ISR_DIRECT_DECLARE(nrfx_grtc_direct_irq_handler) +{ + nrfx_grtc_irq_handler(); + ISR_DIRECT_PM(); + return 1; +} +#endif + static int sys_clock_driver_init(void) { nrfx_err_t err_code; +#if defined(CONFIG_GEN_SW_ISR_TABLE) IRQ_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_isr, nrfx_grtc_irq_handler, 0); +#else + IRQ_DIRECT_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), + nrfx_grtc_direct_irq_handler, 0); + irq_enable(DT_IRQN(GRTC_NODE)); +#endif #if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && NRF_GRTC_HAS_CLKSEL #if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC) diff --git a/include/zephyr/arch/riscv/irq.h b/include/zephyr/arch/riscv/irq.h index 8408912716a..c3c4baff351 100644 --- a/include/zephyr/arch/riscv/irq.h +++ b/include/zephyr/arch/riscv/irq.h @@ -83,6 +83,15 @@ extern void z_riscv_irq_vector_set(unsigned int irq); z_riscv_irq_vector_set(irq_p); \ } +#ifdef CONFIG_PM +extern void arch_isr_direct_pm(void); +#define ARCH_ISR_DIRECT_PM() arch_isr_direct_pm() +#else +#define ARCH_ISR_DIRECT_PM() \ + do { \ + } while (false) +#endif + #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)