Previously the mclk is enabled in probe() stage, which
is not necessary. Move mclk enablement to hw_params()
and mclk disablement to hw_free() will be more efficient.
'mclk_flag' is used for this case.

Signed-off-by: Shengjiu Wang <shengjiu.w...@nxp.com>
---
 sound/soc/fsl/fsl_micfil.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index c347cb3a4712..6ecf46e9ac4c 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -58,6 +58,7 @@ struct fsl_micfil {
        int vad_detected;
        struct fsl_micfil_verid verid;
        struct fsl_micfil_param param;
+       bool mclk_flag;  /* mclk enable flag */
 };
 
 struct fsl_micfil_soc_data {
@@ -693,7 +694,6 @@ static int fsl_micfil_reparent_rootclk(struct fsl_micfil 
*micfil, unsigned int s
        clk = micfil->mclk;
 
        /* Disable clock first, for it was enabled by pm_runtime */
-       clk_disable_unprepare(clk);
        fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk,
                                     micfil->pll11k_clk, ratio);
        ret = clk_prepare_enable(clk);
@@ -730,6 +730,8 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream 
*substream,
        if (ret)
                return ret;
 
+       micfil->mclk_flag = true;
+
        ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8);
        if (ret)
                return ret;
@@ -764,6 +766,17 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream 
*substream,
        return 0;
 }
 
+static int fsl_micfil_hw_free(struct snd_pcm_substream *substream,
+                             struct snd_soc_dai *dai)
+{
+       struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+
+       clk_disable_unprepare(micfil->mclk);
+       micfil->mclk_flag = false;
+
+       return 0;
+}
+
 static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
 {
        struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
@@ -806,6 +819,7 @@ static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
        .startup        = fsl_micfil_startup,
        .trigger        = fsl_micfil_trigger,
        .hw_params      = fsl_micfil_hw_params,
+       .hw_free        = fsl_micfil_hw_free,
 };
 
 static struct snd_soc_dai_driver fsl_micfil_dai = {
@@ -1279,7 +1293,8 @@ static int fsl_micfil_runtime_suspend(struct device *dev)
 
        regcache_cache_only(micfil->regmap, true);
 
-       clk_disable_unprepare(micfil->mclk);
+       if (micfil->mclk_flag)
+               clk_disable_unprepare(micfil->mclk);
        clk_disable_unprepare(micfil->busclk);
 
        return 0;
@@ -1294,10 +1309,12 @@ static int fsl_micfil_runtime_resume(struct device *dev)
        if (ret < 0)
                return ret;
 
-       ret = clk_prepare_enable(micfil->mclk);
-       if (ret < 0) {
-               clk_disable_unprepare(micfil->busclk);
-               return ret;
+       if (micfil->mclk_flag) {
+               ret = clk_prepare_enable(micfil->mclk);
+               if (ret < 0) {
+                       clk_disable_unprepare(micfil->busclk);
+                       return ret;
+               }
        }
 
        regcache_cache_only(micfil->regmap, false);
-- 
2.34.1


Reply via email to