diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 79de77cbda8..ff30b8b9837 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1264,16 +1264,18 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection) esp_clk_private_lock(); // Maybe acquired from esp_clk_slowclk_cal_set #endif +#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX + // The other core will be stalled by high-priority interrupt and spins on variables in internal RAM, + // which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed. + // Must do it before stalling another core, since s_iwdt_configure_lock spinlock is acquired in + // esp_int_wdt_livelock_workaround, which may cause deadlock. + esp_int_wdt_livelock_workaround(false); +#endif /* Disable interrupts and stall another core in case another task writes * to RTC memory while we calculate RTC memory CRC. */ esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_pause(); -#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX - // The other core will be stalled by high-priority interrupt and spins on variables in internal RAM, - // which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed. - esp_int_wdt_livelock_workaround(false); -#endif // record current RTC time s_config.rtc_ticks_at_sleep_start = rtc_time_get(); @@ -1357,12 +1359,12 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection) } #endif /* SOC_RTC_WDT_SUPPORTED */ + esp_ipc_isr_stall_resume(); + esp_ipc_isr_release_other_cpu(); #if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX // Configure WDT to use livelock workaround timeout after releasing other CPU esp_int_wdt_livelock_workaround(true); #endif - esp_ipc_isr_stall_resume(); - esp_ipc_isr_release_other_cpu(); #if !CONFIG_FREERTOS_UNICORE esp_clk_private_unlock(); esp_os_exit_critical_safe(&rtc_spinlock);