diff --git a/components/esp_hw_support/port/esp32s31/esp_clk_tree.c b/components/esp_hw_support/port/esp32s31/esp_clk_tree.c index 04c2c44c6d1..422a2c601a4 100644 --- a/components/esp_hw_support/port/esp32s31/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32s31/esp_clk_tree.c @@ -500,33 +500,31 @@ static const esp_clk_tree_gated_clk_t s_gated_ref_clks[] = { FORCE_INLINE_ATTR esp_err_t esp_clk_tree_enable_gated_clk(const esp_clk_tree_gated_clk_t *entry, bool enable) { int16_t prev_ref_cnt; - bool released_too_many = false; + /* Hold s_clk_tree_spinlock for refcnt only; parent/gate (may take PERIPH_RCC) + * run outside to avoid clk_tree <-> PERIPH_RCC deadlock. */ esp_os_enter_critical(&s_clk_tree_spinlock); if (enable) { prev_ref_cnt = s_mod_clk_gate_ref_cnt[entry->clk_id]++; - if (prev_ref_cnt == 0) { - if (entry->parent_power != NULL) { - entry->parent_power(true); - } - ENABLE_CLK_GATE(entry->set_gate, true); - } } else { prev_ref_cnt = s_mod_clk_gate_ref_cnt[entry->clk_id]--; if (prev_ref_cnt <= 0) { s_mod_clk_gate_ref_cnt[entry->clk_id] = 0; - released_too_many = true; - } else if (prev_ref_cnt == 1) { - ENABLE_CLK_GATE(entry->set_gate, false); - if (entry->parent_power != NULL) { - entry->parent_power(false); - } + esp_os_exit_critical(&s_clk_tree_spinlock); + ESP_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", entry->clk_id); + return ESP_OK; } } esp_os_exit_critical(&s_clk_tree_spinlock); - if (released_too_many) { - ESP_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", entry->clk_id); + if ((enable && prev_ref_cnt == 0) || (!enable && prev_ref_cnt == 1)) { + if (enable && entry->parent_power != NULL) { + entry->parent_power(true); + } + ENABLE_CLK_GATE(entry->set_gate, enable); + if (!enable && entry->parent_power != NULL) { + entry->parent_power(false); + } } return ESP_OK; } diff --git a/components/esp_security/src/esp_crypto_periph_clk.c b/components/esp_security/src/esp_crypto_periph_clk.c index cdd65057c12..bc5ec97c666 100644 --- a/components/esp_security/src/esp_crypto_periph_clk.c +++ b/components/esp_security/src/esp_crypto_periph_clk.c @@ -48,8 +48,10 @@ int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused)); #if SOC_AES_SUPPORTED void esp_crypto_aes_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } AES_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); aes_ll_enable_bus_clock(enable); if (enable) { aes_ll_reset_register(); @@ -61,14 +63,19 @@ void esp_crypto_aes_enable_periph_clk(bool enable) } #endif } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_SHA_SUPPORTED void esp_crypto_sha_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } SHA_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); sha_ll_enable_bus_clock(enable); if (enable) { sha_ll_reset_register(); @@ -80,14 +87,19 @@ void esp_crypto_sha_enable_periph_clk(bool enable) } #endif } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_MPI_SUPPORTED void esp_crypto_mpi_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } MPI_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); mpi_ll_enable_bus_clock(enable); if (enable) { mpi_ll_power_up(); @@ -96,14 +108,19 @@ void esp_crypto_mpi_enable_periph_clk(bool enable) mpi_ll_power_down(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_ECC_SUPPORTED void esp_crypto_ecc_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } ECC_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); ecc_ll_enable_bus_clock(enable); if (enable) { ecc_ll_power_up(); @@ -112,53 +129,73 @@ void esp_crypto_ecc_enable_periph_clk(bool enable) ecc_ll_power_down(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_HMAC_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2 void esp_crypto_hmac_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } HMAC_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); hmac_ll_enable_bus_clock(enable); if (enable) { hmac_ll_reset_register(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_DIG_SIGN_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2 void esp_crypto_ds_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } DS_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); ds_ll_enable_bus_clock(enable); if (enable) { ds_ll_reset_register(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_ECDSA_SUPPORTED void esp_crypto_ecdsa_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } ECDSA_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); ecdsa_ll_enable_bus_clock(enable); if (enable) { ecdsa_ll_reset_register(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif #if SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT void esp_crypto_key_mgr_enable_periph_clk(bool enable) { + if (enable) { + esp_crypto_common_clk_enable(true); + } KEY_MANAGER_RCC_ATOMIC() { - esp_crypto_common_clk_enable(enable); key_mgr_ll_power_up(); key_mgr_ll_enable_bus_clock(enable); key_mgr_ll_enable_peripheral_clock(enable); @@ -166,5 +203,8 @@ void esp_crypto_key_mgr_enable_periph_clk(bool enable) key_mgr_ll_reset_register(); } } + if (!enable) { + esp_crypto_common_clk_enable(false); + } } #endif