Merge branch 'fix/fix_clk_tree_abba_deadlock_v6.1' into 'release/v6.1'

fix(esp32s31): break clk_tree and deadlock with PERIPH_RCC (v6.1)

See merge request espressif/esp-idf!52947
This commit is contained in:
Jiang Jiang Jian
2026-09-20 14:32:29 +08:00
2 changed files with 61 additions and 23 deletions

View File

@@ -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) 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; 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); esp_os_enter_critical(&s_clk_tree_spinlock);
if (enable) { if (enable) {
prev_ref_cnt = s_mod_clk_gate_ref_cnt[entry->clk_id]++; 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 { } else {
prev_ref_cnt = s_mod_clk_gate_ref_cnt[entry->clk_id]--; prev_ref_cnt = s_mod_clk_gate_ref_cnt[entry->clk_id]--;
if (prev_ref_cnt <= 0) { if (prev_ref_cnt <= 0) {
s_mod_clk_gate_ref_cnt[entry->clk_id] = 0; s_mod_clk_gate_ref_cnt[entry->clk_id] = 0;
released_too_many = true; esp_os_exit_critical(&s_clk_tree_spinlock);
} else if (prev_ref_cnt == 1) { ESP_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", entry->clk_id);
ENABLE_CLK_GATE(entry->set_gate, false); return ESP_OK;
if (entry->parent_power != NULL) {
entry->parent_power(false);
}
} }
} }
esp_os_exit_critical(&s_clk_tree_spinlock); esp_os_exit_critical(&s_clk_tree_spinlock);
if (released_too_many) { if ((enable && prev_ref_cnt == 0) || (!enable && prev_ref_cnt == 1)) {
ESP_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", entry->clk_id); 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; return ESP_OK;
} }

View File

@@ -48,8 +48,10 @@ int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused));
#if SOC_AES_SUPPORTED #if SOC_AES_SUPPORTED
void esp_crypto_aes_enable_periph_clk(bool enable) void esp_crypto_aes_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
AES_RCC_ATOMIC() { AES_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
aes_ll_enable_bus_clock(enable); aes_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
aes_ll_reset_register(); aes_ll_reset_register();
@@ -61,14 +63,19 @@ void esp_crypto_aes_enable_periph_clk(bool enable)
} }
#endif #endif
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_SHA_SUPPORTED #if SOC_SHA_SUPPORTED
void esp_crypto_sha_enable_periph_clk(bool enable) void esp_crypto_sha_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
SHA_RCC_ATOMIC() { SHA_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
sha_ll_enable_bus_clock(enable); sha_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
sha_ll_reset_register(); sha_ll_reset_register();
@@ -80,14 +87,19 @@ void esp_crypto_sha_enable_periph_clk(bool enable)
} }
#endif #endif
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_MPI_SUPPORTED #if SOC_MPI_SUPPORTED
void esp_crypto_mpi_enable_periph_clk(bool enable) void esp_crypto_mpi_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
MPI_RCC_ATOMIC() { MPI_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
mpi_ll_enable_bus_clock(enable); mpi_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
mpi_ll_power_up(); mpi_ll_power_up();
@@ -96,14 +108,19 @@ void esp_crypto_mpi_enable_periph_clk(bool enable)
mpi_ll_power_down(); mpi_ll_power_down();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_ECC_SUPPORTED #if SOC_ECC_SUPPORTED
void esp_crypto_ecc_enable_periph_clk(bool enable) void esp_crypto_ecc_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
ECC_RCC_ATOMIC() { ECC_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
ecc_ll_enable_bus_clock(enable); ecc_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
ecc_ll_power_up(); ecc_ll_power_up();
@@ -112,53 +129,73 @@ void esp_crypto_ecc_enable_periph_clk(bool enable)
ecc_ll_power_down(); ecc_ll_power_down();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_HMAC_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2 #if SOC_HMAC_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2
void esp_crypto_hmac_enable_periph_clk(bool enable) void esp_crypto_hmac_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
HMAC_RCC_ATOMIC() { HMAC_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
hmac_ll_enable_bus_clock(enable); hmac_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
hmac_ll_reset_register(); hmac_ll_reset_register();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_DIG_SIGN_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2 #if SOC_DIG_SIGN_SUPPORTED && !CONFIG_IDF_TARGET_ESP32S2
void esp_crypto_ds_enable_periph_clk(bool enable) void esp_crypto_ds_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
DS_RCC_ATOMIC() { DS_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
ds_ll_enable_bus_clock(enable); ds_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
ds_ll_reset_register(); ds_ll_reset_register();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_ECDSA_SUPPORTED #if SOC_ECDSA_SUPPORTED
void esp_crypto_ecdsa_enable_periph_clk(bool enable) void esp_crypto_ecdsa_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
ECDSA_RCC_ATOMIC() { ECDSA_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
ecdsa_ll_enable_bus_clock(enable); ecdsa_ll_enable_bus_clock(enable);
if (enable) { if (enable) {
ecdsa_ll_reset_register(); ecdsa_ll_reset_register();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif
#if SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT #if SOC_KEY_MANAGER_SUPPORT_KEY_DEPLOYMENT
void esp_crypto_key_mgr_enable_periph_clk(bool enable) void esp_crypto_key_mgr_enable_periph_clk(bool enable)
{ {
if (enable) {
esp_crypto_common_clk_enable(true);
}
KEY_MANAGER_RCC_ATOMIC() { KEY_MANAGER_RCC_ATOMIC() {
esp_crypto_common_clk_enable(enable);
key_mgr_ll_power_up(); key_mgr_ll_power_up();
key_mgr_ll_enable_bus_clock(enable); key_mgr_ll_enable_bus_clock(enable);
key_mgr_ll_enable_peripheral_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(); key_mgr_ll_reset_register();
} }
} }
if (!enable) {
esp_crypto_common_clk_enable(false);
}
} }
#endif #endif