diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index cee08dcdbd57..2a2f7852d0df 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -614,11 +614,12 @@ static int bolero_ssr_enable(struct device *dev, void *data) if (priv->rsc_clk_cb) priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_UP); - if (priv->macro_params[VA_MACRO].event_handler) - priv->macro_params[VA_MACRO].event_handler( - priv->component, - BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0); - + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (priv->macro_params[macro_idx].event_handler) + priv->macro_params[macro_idx].event_handler( + priv->component, + BOLERO_MACRO_EVT_CLK_RESET, 0x0); + } regcache_cache_only(priv->regmap, false); mutex_lock(&priv->clk_lock); priv->dev_up = true; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index e533eb85731c..3bb82b97f2b1 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -38,6 +38,7 @@ enum { BOLERO_MACRO_EVT_SSR_DOWN, BOLERO_MACRO_EVT_SSR_UP, BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, + BOLERO_MACRO_EVT_CLK_RESET, BOLERO_MACRO_EVT_REG_WAKE_IRQ }; diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 82f387926e4f..d325d76adc03 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-clk-rsc.h" @@ -91,6 +92,51 @@ static char __iomem *bolero_clk_rsc_get_clk_muxsel(struct bolero_clk_rsc *priv, return NULL; } +int bolero_rsc_clk_reset(struct device *dev, int clk_id) +{ + struct device *clk_dev = NULL; + struct bolero_clk_rsc *priv = NULL; + int count = 0; + + if (!dev) { + pr_err("%s: dev is null %d\n", __func__); + return -EINVAL; + } + + if (clk_id < 0 || clk_id >= MAX_CLK - NPL_CLK_OFFSET) { + pr_err("%s: Invalid clk_id: %d\n", + __func__, clk_id); + return -EINVAL; + } + + clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); + if (!clk_dev) { + pr_err("%s: Invalid rsc clk device\n", __func__); + return -EINVAL; + } + + priv = dev_get_drvdata(clk_dev); + if (!priv) { + pr_err("%s: Invalid rsc clk priviate data\n", __func__); + return -EINVAL; + } + mutex_lock(&priv->rsc_clk_lock); + while (__clk_is_enabled(priv->clk[clk_id])) { + clk_disable_unprepare(priv->clk[clk_id + NPL_CLK_OFFSET]); + clk_disable_unprepare(priv->clk[clk_id]); + count++; + } + dev_dbg(priv->dev, + "%s: clock reset after ssr, count %d\n", __func__, count); + while (count--) { + clk_prepare_enable(priv->clk[clk_id]); + clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]); + } + mutex_unlock(&priv->rsc_clk_lock); + return 0; +} +EXPORT_SYMBOL(bolero_rsc_clk_reset); + static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, int clk_id, bool enable) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.h b/asoc/codecs/bolero/bolero-clk-rsc.h index b378f73b34d4..fc3c02f602f3 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.h +++ b/asoc/codecs/bolero/bolero-clk-rsc.h @@ -18,6 +18,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, int default_clk_id, int clk_id_req, bool enable); +int bolero_rsc_clk_reset(struct device *dev, int clk_id); #else static inline void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) @@ -37,6 +38,9 @@ static inline int bolero_clk_rsc_request_clock(struct device *dev, { return 0; } - +static inline int bolero_rsc_clk_reset(struct device *dev, int clk_id) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CLK_RSC_H */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0be5c4e9a495..8702dba68444 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1241,6 +1241,9 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK); + break; } return ret; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index cb3aa59e4cb1..20606f68beab 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -360,6 +360,9 @@ static int tx_macro_event_handler(struct snd_soc_component *component, tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK); + break; } return 0; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index ba9c7f12b0d3..a94ca7701203 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -234,6 +234,9 @@ static int va_macro_event_handler(struct snd_soc_component *component, "%s: va_mclk_users is non-zero still, audio SSR fail!!\n", __func__); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); + break; default: break; } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index f41392df4c1e..5b07cbd9915a 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -924,6 +924,9 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK); + break; } return 0; }