diff --git a/soc/silabs/common/soc_power_pmgr.c b/soc/silabs/common/soc_power_pmgr.c index 15a80694eb8..402701c1c23 100644 --- a/soc/silabs/common/soc_power_pmgr.c +++ b/soc/silabs/common/soc_power_pmgr.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); @@ -46,18 +48,6 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) break; } - /* FIXME: When this function is entered the Kernel has disabled - * interrupts using BASEPRI register. This is incorrect as it prevents - * waking up from any interrupt which priority is not 0. Work around the - * issue and disable interrupts using PRIMASK register as recommended - * by ARM. - */ - - /* Set PRIMASK */ - __disable_irq(); - /* Set BASEPRI to 0 */ - irq_unlock(0); - LOG_DBG("Entry to energy mode %d", energy_mode); if (energy_mode == SL_POWER_MANAGER_EM4) { @@ -77,9 +67,6 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) } LOG_DBG("Exit from energy mode %d", energy_mode); - - /* Clear PRIMASK */ - __enable_irq(); } void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) @@ -88,6 +75,33 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) ARG_UNUSED(substate_id); } +/* This function is called by sl_power_manager_sleep() after it has set the PRIMASK. */ +bool sl_power_manager_is_ok_to_sleep(void) +{ + /* FIXME: When this function is entered the Kernel has disabled + * interrupts using BASEPRI register. This is incorrect as it prevents + * waking up from any interrupt which priority is not 0. Work around the + * issue and disable interrupts using PRIMASK register as recommended + * by ARM. + */ + /* Set BASEPRI to 0. */ + irq_unlock(0); + + return true; +} + +/* This function is called by sl_power_manager_sleep() right after it was woken up from WFI. */ +void sli_power_manager_on_wakeup(void) +{ +#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON) + /* Handle the HFXO IRQ as soon as possible to retrieve the startup time. */ + sl_hfxo_manager_irq_handler(); +#endif + /* Forces a clock restore before handling interrupts. */ + sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1); + sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); +} + /** * Some SiLabs blobs, such as RAIL, call directly into sl_power_manager, and * for that they had to include sl_power_manager.h during build. Some of those