From 76896fa1d1f6ae878883a054edfce3e611a74151 Mon Sep 17 00:00:00 2001 From: Hessel van der Molen Date: Wed, 30 Oct 2024 17:33:08 +0100 Subject: [PATCH 1/2] [nrf fromlist] arch: arm: cortex_m: pm_s2ram: fix system_off rv as rv of s2ram_suspend The return value of the system_off call is overwritten by the the call to pm_s2ram_mark_check_and_clear. As arch_pm_s2ram_suspend needs to specify why system_off failed, we need to make sure the rv of system_off is moved to a safe register before calling pm_s2ram_mark_check_and_clear and moved to r0 als rv of arch_pm_s2ram_suspend when the suspend call exits. Upstream PR #: 80642 Signed-off-by: Hessel van der Molen --- arch/arm/core/cortex_m/pm_s2ram.S | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/core/cortex_m/pm_s2ram.S b/arch/arm/core/cortex_m/pm_s2ram.S index 27c2a1e96a7..aed8cf5b692 100644 --- a/arch/arm/core/cortex_m/pm_s2ram.S +++ b/arch/arm/core/cortex_m/pm_s2ram.S @@ -85,6 +85,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) * not successful (in r0 the return value). */ + /* Move return value of system_off to callee-saved register. */ + mov r4, r0 + /* * Reset the marking of suspend to RAM, return is ignored. */ @@ -92,7 +95,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) bl pm_s2ram_mark_check_and_clear mov lr, r1 - /* Move system_off back to r0 as return value */ + /* Move the stored return value of system_off back to r0, + * setting it as return value for this function. + */ mov r0, r4 pop {r4-r12, lr} From 50d2a724c87bef5f6e836c399a2a06f8a23094ad Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Tue, 12 Nov 2024 11:24:40 +0100 Subject: [PATCH 2/2] [nrf fromlist] soc: nordic: nrf54h: disable IRQ before PM config IRQs must be disabled before starting any procedures to prepare for low-power states. Upstream PR #: 79067 Signed-off-by: Adam Kondraciuk --- soc/nordic/nrf54h/pm_s2ram.c | 3 --- soc/nordic/nrf54h/power.c | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/soc/nordic/nrf54h/pm_s2ram.c b/soc/nordic/nrf54h/pm_s2ram.c index 88529c4bb75..20c28e42df5 100644 --- a/soc/nordic/nrf54h/pm_s2ram.c +++ b/soc/nordic/nrf54h/pm_s2ram.c @@ -111,18 +111,15 @@ int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off) { int ret; - __disable_irq(); nvic_suspend(&backup_data.nvic_context); mpu_suspend(&backup_data.mpu_context); ret = arch_pm_s2ram_suspend(system_off); if (ret < 0) { - __enable_irq(); return ret; } mpu_resume(&backup_data.mpu_context); nvic_resume(&backup_data.nvic_context); - __enable_irq(); return ret; } diff --git a/soc/nordic/nrf54h/power.c b/soc/nordic/nrf54h/power.c index 8b73dbaee30..c6cf44953fa 100644 --- a/soc/nordic/nrf54h/power.c +++ b/soc/nordic/nrf54h/power.c @@ -188,15 +188,19 @@ static void s2ram_enter(void) void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state == PM_STATE_SUSPEND_TO_IDLE) { + __disable_irq(); s2idle_enter(substate_id); /* Resume here. */ s2idle_exit(substate_id); + __enable_irq(); } #if defined(CONFIG_PM_S2RAM) else if (state == PM_STATE_SUSPEND_TO_RAM) { + __disable_irq(); s2ram_enter(); /* On resuming or error we return exactly *HERE* */ s2ram_exit(); + __enable_irq(); } #endif else {