diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c index ff8e98fa24..71d643ff81 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c @@ -503,6 +503,7 @@ struct lpass_cdc_rx_macro_priv { bool is_fir_coeff_written[FIR_PATH_MAX][GRP_MAX]; bool is_fir_capable; bool dev_up; + bool pre_dev_up; bool hph_pwr_mode; bool hph_hd2_mode; struct mutex mclk_lock; @@ -1424,7 +1425,8 @@ static int lpass_cdc_rx_macro_mclk_enable( rx_priv->default_clk_id, rx_priv->clk_id, false); - lpass_cdc_rx_macro_core_vote(rx_priv, false); + if (!ret) + lpass_cdc_rx_macro_core_vote(rx_priv, false); rx_priv->clk_id = rx_priv->default_clk_id; } } @@ -1517,6 +1519,7 @@ static int lpass_cdc_rx_macro_event_handler(struct snd_soc_component *component, break; case LPASS_CDC_MACRO_EVT_SSR_DOWN: trace_printk("%s, enter SSR down\n", __func__); + rx_priv->pre_dev_up = false; rx_priv->dev_up = false; if (rx_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -1534,6 +1537,7 @@ static int lpass_cdc_rx_macro_event_handler(struct snd_soc_component *component, } break; case LPASS_CDC_MACRO_EVT_PRE_SSR_UP: + rx_priv->pre_dev_up = true; ret = lpass_cdc_rx_macro_core_vote(rx_priv, true); if (ret < 0) { dev_err_ratelimited(rx_priv->dev, @@ -4349,6 +4353,12 @@ static int lpass_cdc_rx_macro_core_vote(void *handle, bool enable) pr_err_ratelimited("%s: rx priv data is NULL\n", __func__); return -EINVAL; } + + if (!rx_priv->pre_dev_up && enable) { + pr_debug("%s: adsp is not up\n", __func__); + return -EINVAL; + } + if (enable) { pm_runtime_get_sync(rx_priv->dev); if (lpass_cdc_check_core_votes(rx_priv->dev)) @@ -4718,6 +4728,7 @@ static int lpass_cdc_rx_macro_probe(struct platform_device *pdev) if (!rx_priv) return -ENOMEM; + rx_priv->pre_dev_up = true; rx_priv->dev = &pdev->dev; ret = of_property_read_u32(pdev->dev.of_node, "reg", &rx_base_addr); diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-va-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-va-macro.c index c294fceea7..d220120600 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-va-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-va-macro.c @@ -176,6 +176,7 @@ struct lpass_cdc_va_macro_priv { int dapm_tx_clk_status; u16 current_clk_id; bool dev_up; + bool pre_dev_up; bool swr_dmic_enable; }; @@ -280,7 +281,8 @@ static int lpass_cdc_va_macro_mclk_enable( va_priv->default_clk_id, va_priv->clk_id, false); - lpass_cdc_va_macro_core_vote(va_priv, false); + if (!ret) + lpass_cdc_va_macro_core_vote(va_priv, false); } exit: mutex_unlock(&va_priv->mclk_lock); @@ -321,6 +323,7 @@ static int lpass_cdc_va_macro_event_handler(struct snd_soc_component *component, __func__); break; case LPASS_CDC_MACRO_EVT_PRE_SSR_UP: + va_priv->pre_dev_up = true; /* enable&disable VA_CORE_CLK to reset GFMUX reg */ ret = lpass_cdc_va_macro_core_vote(va_priv, true); if (ret < 0) { @@ -356,6 +359,7 @@ static int lpass_cdc_va_macro_event_handler(struct snd_soc_component *component, lpass_cdc_rsc_clk_reset(va_dev, VA_CORE_CLK); break; case LPASS_CDC_MACRO_EVT_SSR_DOWN: + va_priv->pre_dev_up = false; va_priv->dev_up = false; if (va_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -413,6 +417,7 @@ static int lpass_cdc_va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *va_dev = NULL; struct lpass_cdc_va_macro_priv *va_priv = NULL; + bool vote_err = false; if (!lpass_cdc_va_macro_get_data(component, &va_dev, &va_priv, __func__)) @@ -496,12 +501,14 @@ static int lpass_cdc_va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, __func__); if (va_priv->dev_up) break; + vote_err = true; } ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, VA_CORE_CLK, false); - lpass_cdc_va_macro_core_vote(va_priv, false); + if (!vote_err) + lpass_cdc_va_macro_core_vote(va_priv, false); if (ret) { dev_err_ratelimited(component->dev, "%s: request clock VA_CLK disable failed\n", @@ -741,6 +748,11 @@ static int lpass_cdc_va_macro_core_vote(void *handle, bool enable) pr_err_ratelimited("%s: va priv data is NULL\n", __func__); return -EINVAL; } + if (!va_priv->pre_dev_up && enable) { + pr_err("%s: adsp is not up\n", __func__); + return -EINVAL; + } + trace_printk("%s, enter: enable %d\n", __func__, enable); if (enable) { pm_runtime_get_sync(va_priv->dev); @@ -2525,6 +2537,7 @@ static int lpass_cdc_va_macro_probe(struct platform_device *pdev) mutex_init(&va_priv->swr_clk_lock); } va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio; + va_priv->pre_dev_up = true; mutex_init(&va_priv->mclk_lock); dev_set_drvdata(&pdev->dev, va_priv); diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c index 21893eaf05..157317cb54 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c @@ -315,6 +315,7 @@ struct lpass_cdc_wsa_macro_priv { u32 wsa_rload[LPASS_CDC_WSA_MACRO_RX1 + 1]; u8 idle_detect_en; int noise_gate_mode; + bool pre_dev_up; }; static struct snd_soc_dai_driver lpass_cdc_wsa_macro_dai[]; @@ -1031,6 +1032,7 @@ static int lpass_cdc_wsa_macro_event_handler(struct snd_soc_component *component switch (event) { case LPASS_CDC_MACRO_EVT_SSR_DOWN: + wsa_priv->pre_dev_up = false; trace_printk("%s, enter SSR down\n", __func__); if (wsa_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -1051,6 +1053,7 @@ static int lpass_cdc_wsa_macro_event_handler(struct snd_soc_component *component break; case LPASS_CDC_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); + wsa_priv->pre_dev_up = true; /* reset swr after ssr/pdr */ wsa_priv->reset_swr = true; if (wsa_priv->swr_ctrl_data) @@ -3303,6 +3306,11 @@ static int lpass_cdc_wsa_macro_core_vote(void *handle, bool enable) pr_err_ratelimited("%s: wsa priv data is NULL\n", __func__); return -EINVAL; } + if (!wsa_priv->pre_dev_up && enable) { + pr_debug("%s: adsp is not up\n", __func__); + return -EINVAL; + } + if (enable) { pm_runtime_get_sync(wsa_priv->dev); if (lpass_cdc_check_core_votes(wsa_priv->dev)) @@ -3761,6 +3769,7 @@ static int lpass_cdc_wsa_macro_probe(struct platform_device *pdev) if (!wsa_priv) return -ENOMEM; + wsa_priv->pre_dev_up = true; wsa_priv->dev = &pdev->dev; ret = of_property_read_u32(pdev->dev.of_node, "reg", &wsa_base_addr); diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c index 7061333609..bb8d4bcd42 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c @@ -315,6 +315,7 @@ struct lpass_cdc_wsa2_macro_priv { u32 wsa2_rload[LPASS_CDC_WSA2_MACRO_RX1 + 1]; u8 idle_detect_en; int noise_gate_mode; + bool pre_dev_up; }; static struct snd_soc_dai_driver lpass_cdc_wsa2_macro_dai[]; @@ -1030,6 +1031,7 @@ static int lpass_cdc_wsa2_macro_event_handler(struct snd_soc_component *componen switch (event) { case LPASS_CDC_MACRO_EVT_SSR_DOWN: + wsa2_priv->pre_dev_up = false; trace_printk("%s, enter SSR down\n", __func__); if (wsa2_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -1050,6 +1052,7 @@ static int lpass_cdc_wsa2_macro_event_handler(struct snd_soc_component *componen break; case LPASS_CDC_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); + wsa2_priv->pre_dev_up = true; /* reset swr after ssr/pdr */ wsa2_priv->reset_swr = true; if (wsa2_priv->swr_ctrl_data) @@ -3295,6 +3298,12 @@ static int lpass_cdc_wsa2_macro_core_vote(void *handle, bool enable) pr_err_ratelimited("%s: wsa2 priv data is NULL\n", __func__); return -EINVAL; } + + if (!wsa2_priv->pre_dev_up && enable) { + pr_debug("%s: adsp is not up\n", __func__); + return -EINVAL; + } + if (enable) { pm_runtime_get_sync(wsa2_priv->dev); if (lpass_cdc_check_core_votes(wsa2_priv->dev)) @@ -3751,6 +3760,7 @@ static int lpass_cdc_wsa2_macro_probe(struct platform_device *pdev) if (!wsa2_priv) return -ENOMEM; + wsa2_priv->pre_dev_up = true; wsa2_priv->dev = &pdev->dev; ret = of_property_read_u32(pdev->dev.of_node, "reg", &wsa2_base_addr); diff --git a/asoc/codecs/lpass-cdc/lpass-cdc.c b/asoc/codecs/lpass-cdc/lpass-cdc.c index ded26c3c0c..5805033a14 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc.c @@ -1376,6 +1376,7 @@ int lpass_cdc_runtime_resume(struct device *dev) int ret = 0; trace_printk("%s, enter\n", __func__); + dev_dbg(dev,"%s, enter\n", __func__); mutex_lock(&priv->vote_lock); if (priv->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); @@ -1415,6 +1416,8 @@ audio_vote: done: mutex_unlock(&priv->vote_lock); trace_printk("%s, leave\n", __func__); + dev_dbg(dev,"%s, leave, hw_vote %d, audio_vote %d\n", __func__, + priv->core_hw_vote_count, priv->core_audio_vote_count); pm_runtime_set_autosuspend_delay(priv->dev, LPASS_CDC_AUTO_SUSPEND_DELAY); return 0; } @@ -1425,6 +1428,7 @@ int lpass_cdc_runtime_suspend(struct device *dev) struct lpass_cdc_priv *priv = dev_get_drvdata(dev->parent); trace_printk("%s, enter\n", __func__); + dev_dbg(dev,"%s, enter\n", __func__); mutex_lock(&priv->vote_lock); if (priv->lpass_core_hw_vote != NULL) { if (--priv->core_hw_vote_count == 0) @@ -1454,6 +1458,8 @@ int lpass_cdc_runtime_suspend(struct device *dev) mutex_unlock(&priv->vote_lock); trace_printk("%s, leave\n", __func__); + dev_dbg(dev,"%s, leave, hw_vote %d, audio_vote %d\n", __func__, + priv->core_hw_vote_count, priv->core_audio_vote_count); return 0; } EXPORT_SYMBOL(lpass_cdc_runtime_suspend);