soc: mec172x: Fix interrupt unmasking in SoC PM restore path

Zephyr PM expects the SoC layer upon wake to unmask interrupts
the PM layer masked. MEC172x was re-enabling interrupt globally
in the Cortex-M4 but not clearing the mask set by Zephyr PM.
This worked in previous Zephyr releases but broke in the latest
Zephyr changes. Fixed the SoC to re-enable interrupts globally
and call irq_unlock(0) as Zephyr PM does if pm_state_exit_post_ops
is not implemented. Tested on MEC172x EVB with PLL clock out pin
enabled and verified PLL goes off in deep sleep, system wakes,
and interrupts are firing.

Signed-off-by: scott worley <scott.worley@microchip.com>
This commit is contained in:
scott worley 2023-03-27 09:18:17 -04:00 committed by Carles Cufí
commit cfcd92b893

View file

@ -162,22 +162,14 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id)
/*
* Zephyr PM code expects us to enabled interrupt at post op exit. Zephyr used
* arch_irq_lock() which sets BASEPRI to a non-zero value masking all interrupts
* preventing wake. MCHP z_power_soc_(deep)_sleep sets PRIMASK=1 and BASEPRI=0
* allowing wake from any enabled interrupt and prevent CPU from entering any
* ISR on wake except for faults. We re-enable interrupt by setting PRIMASK to 0.
* Side-effect is we set BASEPRI=0. Is this the same value as Zephyr uses during
* NVIC initialization?
* arch_irq_lock() which sets BASEPRI to a non-zero value masking interrupts at
* >= numerical priority. MCHP z_power_soc_(deep)_sleep sets PRIMASK=1 and BASEPRI=0
* allowing wake from any enabled interrupt and prevents the CPU from entering any
* ISR on wake except for faults. We re-enable interrupts by undoing global disable
* and alling irq_unlock with the same value, 0 zephyr core uses.
*/
__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
{
switch (state) {
case PM_STATE_SUSPEND_TO_IDLE:
case PM_STATE_SUSPEND_TO_RAM:
__enable_irq();
break;
default:
irq_unlock(0); /* this writes CM4 BASEPRI=0 */
break;
}
irq_unlock(0);
}