From 7d013fb36d6bcfcdab4c2d7226eb7a2d269e2bc6 Mon Sep 17 00:00:00 2001 From: sibeibei Date: Thu, 4 Dec 2025 20:10:11 +0800 Subject: [PATCH] fix: add mutex protection for software trigger RegDMA start to avoid data races --- .../include/esp_private/sleep_retention.h | 9 +++++++++ components/esp_hw_support/sleep_modem.c | 6 ++---- components/esp_hw_support/sleep_retention.c | 20 +++++++++++++++++++ .../esp32c5/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c5/include/soc/soc_caps.h | 1 + 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index 6603c5f0d7..0b211ff885 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -276,6 +276,15 @@ void sleep_retention_do_extra_retention(bool backup_or_restore); void sleep_retention_do_system_retention(bool backup_or_restore); #endif +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +/** + * @brief Software trigger REGDMA to do phy linked list retention + * + * @param backup_or_restore true for backup register context to memory + * or false for restore to register from memory + */ +void sleep_retention_do_phy_retention(bool backup_or_restore); +#endif /*SOC_PM_SUPPORT_PMU_MODEM_STATE */ #endif // SOC_PAU_SUPPORTED #ifdef __cplusplus diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index 259f822234..e0dd24f2e2 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -173,10 +173,8 @@ __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void) void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore) { - if (restore) { - pau_regdma_trigger_modem_link_restore(); - } else { - pau_regdma_trigger_modem_link_backup(); + sleep_retention_do_phy_retention(!restore); + if (!restore) { s_sleep_modem.wifi.modem_state_phy_done = 1; } } diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 01fbdb2c77..73fbac4533 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -1005,3 +1005,23 @@ void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) } } #endif + +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore) +{ +/* since the PHY link and other module links are within the sleep-retention entry (4) context, +* add mutex protection to avoid data race. +*/ +#if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + _lock_acquire_recursive(&s_retention.lock); +#endif + if (backup_or_restore) { + pau_regdma_trigger_modem_link_backup(); + } else { + pau_regdma_trigger_modem_link_restore(); + } +#if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + _lock_release_recursive(&s_retention.lock); +#endif +} +#endif /*SOC_PM_SUPPORT_PMU_MODEM_STATE */ diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 81ca8869a1..c91abdb203 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1559,6 +1559,10 @@ config SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC int default 4 +config SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY + bool + default y + config SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index d47fd35781..8165725743 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -627,6 +627,7 @@ #define SOC_PM_PAU_LINK_NUM (5) #define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1) #define SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC (4) // The range of values for the link index is [0, SOC_PM_PAU_LINK_NUM) +#define SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY (1) #define SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED (1)