MLK-17034-1: ASoC: fsl_esai: Move clock operation to pm runtime function
authorShengjiu Wang <shengjiu.wang@nxp.com>
Tue, 28 Nov 2017 08:17:08 +0000 (16:17 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:49:46 +0000 (14:49 -0500)
In imx8 when systerm enter suspend state, the power of subsystem will be
off, The clock enable state will be lost after resume, but the runtime
resume function will be called after resume by pm, so need to move clock
enablement to runtime resume and clock disablement to runtime suspend.
Then after resume the clock enable state can be recovered.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
sound/soc/fsl/fsl_esai.c

index bcc8f88..baa998c 100644 (file)
@@ -532,30 +532,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-       int ret;
-
-       /*
-        * Some platforms might use the same bit to gate all three or two of
-        * clocks, so keep all clocks open/close at the same time for safety
-        */
-       ret = clk_prepare_enable(esai_priv->coreclk);
-       if (ret)
-               return ret;
-       if (!IS_ERR(esai_priv->spbaclk)) {
-               ret = clk_prepare_enable(esai_priv->spbaclk);
-               if (ret)
-                       goto err_spbaclk;
-       }
-       if (!IS_ERR(esai_priv->extalclk)) {
-               ret = clk_prepare_enable(esai_priv->extalclk);
-               if (ret)
-                       goto err_extalck;
-       }
-       if (!IS_ERR(esai_priv->fsysclk)) {
-               ret = clk_prepare_enable(esai_priv->fsysclk);
-               if (ret)
-                       goto err_fsysclk;
-       }
 
        if (!dai->active) {
                /* Set synchronous mode */
@@ -594,16 +570,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
 
        return 0;
 
-err_fsysclk:
-       if (!IS_ERR(esai_priv->extalclk))
-               clk_disable_unprepare(esai_priv->extalclk);
-err_extalck:
-       if (!IS_ERR(esai_priv->spbaclk))
-               clk_disable_unprepare(esai_priv->spbaclk);
-err_spbaclk:
-       clk_disable_unprepare(esai_priv->coreclk);
-
-       return ret;
 }
 
 static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
@@ -678,13 +644,6 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
 
        esai_priv->substream[substream->stream] = NULL;
 
-       if (!IS_ERR(esai_priv->fsysclk))
-               clk_disable_unprepare(esai_priv->fsysclk);
-       if (!IS_ERR(esai_priv->extalclk))
-               clk_disable_unprepare(esai_priv->extalclk);
-       if (!IS_ERR(esai_priv->spbaclk))
-               clk_disable_unprepare(esai_priv->spbaclk);
-       clk_disable_unprepare(esai_priv->coreclk);
 }
 
 static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -1192,6 +1151,29 @@ static int fsl_esai_runtime_resume(struct device *dev)
        struct fsl_esai *esai = dev_get_drvdata(dev);
        int ret;
 
+       /*
+        * Some platforms might use the same bit to gate all three or two of
+        * clocks, so keep all clocks open/close at the same time for safety
+        */
+       ret = clk_prepare_enable(esai->coreclk);
+       if (ret)
+               return ret;
+       if (!IS_ERR(esai->spbaclk)) {
+               ret = clk_prepare_enable(esai->spbaclk);
+               if (ret)
+                       goto disable_core_clk;
+       }
+       if (!IS_ERR(esai->extalclk)) {
+               ret = clk_prepare_enable(esai->extalclk);
+               if (ret)
+                       goto disable_spba_clk;
+       }
+       if (!IS_ERR(esai->fsysclk)) {
+               ret = clk_prepare_enable(esai->fsysclk);
+               if (ret)
+                       goto disable_extal_clk;
+       }
+
        regcache_cache_only(esai->regmap, false);
        regcache_mark_dirty(esai->regmap);
 
@@ -1203,13 +1185,27 @@ static int fsl_esai_runtime_resume(struct device *dev)
 
        ret = regcache_sync(esai->regmap);
        if (ret)
-               return ret;
+               goto disable_fsys_clk;
 
        /* FIFO reset done */
        regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
        regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
 
        return 0;
+
+disable_fsys_clk:
+       if (!IS_ERR(esai->fsysclk))
+               clk_disable_unprepare(esai->fsysclk);
+disable_extal_clk:
+       if (!IS_ERR(esai->extalclk))
+               clk_disable_unprepare(esai->extalclk);
+disable_spba_clk:
+       if (!IS_ERR(esai->spbaclk))
+               clk_disable_unprepare(esai->spbaclk);
+disable_core_clk:
+       clk_disable_unprepare(esai->coreclk);
+
+       return ret;
 }
 
 static int fsl_esai_runtime_suspend(struct device *dev)
@@ -1218,6 +1214,14 @@ static int fsl_esai_runtime_suspend(struct device *dev)
 
        regcache_cache_only(esai->regmap, true);
 
+       if (!IS_ERR(esai->fsysclk))
+               clk_disable_unprepare(esai->fsysclk);
+       if (!IS_ERR(esai->extalclk))
+               clk_disable_unprepare(esai->extalclk);
+       if (!IS_ERR(esai->spbaclk))
+               clk_disable_unprepare(esai->spbaclk);
+       clk_disable_unprepare(esai->coreclk);
+
        return 0;
 }
 #endif