Hi Daniel, On Du, 2019-04-21 at 19:39 +0000, Daniel Baluta wrote: > From: Shengjiu Wang <shengjiu.wang@xxxxxxx> > > Turn off/on clocks when device enters suspend/resume. This > can help saving power. > > As a further optimization, we turn off/on mclk only when SAI > is in master mode because otherwise mclk is externally provided. > > Signed-off-by: Shengjiu Wang <shengjiu.wang@xxxxxxx> > Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxx> > --- > sound/soc/fsl/fsl_sai.c | 60 ++++++++++++++++++++++++++++++++++------- > 1 file changed, 50 insertions(+), 10 deletions(-) > > diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c > index 8623b7f882b9..13a462360ed3 100644 > --- a/sound/soc/fsl/fsl_sai.c > +++ b/sound/soc/fsl/fsl_sai.c > @@ -596,15 +596,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, > { > struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); > bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; > - struct device *dev = &sai->pdev->dev; > int ret; > > - ret = clk_prepare_enable(sai->bus_clk); > - if (ret) { > - dev_err(dev, "failed to enable bus clock: %d\n", ret); > - return ret; > - } > - > regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, > FSL_SAI_CR3_TRCE); > > @@ -621,8 +614,6 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, > bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; > > regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); > - > - clk_disable_unprepare(sai->bus_clk); > } > > static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { > @@ -932,6 +923,16 @@ static int fsl_sai_runtime_suspend(struct device *dev) > { > struct fsl_sai *sai = dev_get_drvdata(dev); > > + if (!sai->is_slave_mode) { This check is redundant as the bits in sai->mclk_streams are set/unset for master mode only, please check fsl_sai_hw_params and fsl_sai_hw_free functions. > + if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) > + clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); > + > + if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) > + clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); > + } > + > + clk_disable_unprepare(sai->bus_clk); > + > regcache_cache_only(sai->regmap, true); > regcache_mark_dirty(sai->regmap); > > @@ -941,6 +942,27 @@ static int fsl_sai_runtime_suspend(struct device *dev) > static int fsl_sai_runtime_resume(struct device *dev) > { > struct fsl_sai *sai = dev_get_drvdata(dev); > + int ret; > + > + ret = clk_prepare_enable(sai->bus_clk); > + if (ret) { > + dev_err(dev, "failed to enable bus clock: %d\n", ret); > + return ret; > + } > + > + if (!sai->is_slave_mode) { > + if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) { > + ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]); > + if (ret) > + goto disable_bus_clk; > + } > + > + if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) { > + ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]); > + if (ret) > + goto disable_tx_clk; > + } > + } > > regcache_cache_only(sai->regmap, false); > regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); > @@ -948,7 +970,25 @@ static int fsl_sai_runtime_resume(struct device *dev) > usleep_range(1000, 2000); > regmap_write(sai->regmap, FSL_SAI_TCSR, 0); > regmap_write(sai->regmap, FSL_SAI_RCSR, 0); > - return regcache_sync(sai->regmap); > + > + ret = regcache_sync(sai->regmap); > + if (ret) > + goto disable_rx_clk; > + > + return 0; > + > +disable_rx_clk: > + if (!sai->is_slave_mode && > + (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))) > + clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); > +disable_tx_clk: > + if (!sai->is_slave_mode && > + (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))) > + clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); > +disable_bus_clk: > + clk_disable_unprepare(sai->bus_clk); > + > + return ret; > } > #endif /* CONFIG_PM */ > > -- > 2.17.1 > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx https://mailman.alsa-project.org/mailman/listinfo/alsa-devel