diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c index 716ecf0401fe..e26f39dfe059 100644 --- a/sound/soc/renesas/fsi.c +++ b/sound/soc/renesas/fsi.c @@ -730,6 +730,54 @@ static int fsi_clk_is_valid(struct fsi_priv *fsi) fsi->clock.rate; } +static int fsi_clk_prepare(struct fsi_priv *fsi) +{ + struct fsi_clk *clock = &fsi->clock; + struct clk *spu = fsi->master->clk_spu; + struct clk *xck = clock->xck; + struct clk *ick = clock->ick; + struct clk *div = clock->div; + int ret; + + ret = clk_prepare(spu); + if (ret) + return ret; + ret = clk_prepare(xck); + if (ret) + goto err_spu; + ret = clk_prepare(ick); + if (ret) + goto err_xck; + ret = clk_prepare(div); + if (ret) + goto err_ick; + + return 0; + +err_ick: + clk_unprepare(ick); +err_xck: + clk_unprepare(xck); +err_spu: + clk_unprepare(spu); + + return ret; +} + +static void fsi_clk_unprepare(struct fsi_priv *fsi) +{ + struct fsi_clk *clock = &fsi->clock; + struct clk *spu = fsi->master->clk_spu; + struct clk *xck = clock->xck; + struct clk *ick = clock->ick; + struct clk *div = clock->div; + + clk_unprepare(div); + clk_unprepare(ick); + clk_unprepare(xck); + clk_unprepare(spu); +} + static int fsi_clk_enable(struct device *dev, struct fsi_priv *fsi) { @@ -1580,7 +1628,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, fsi_clk_invalid(fsi); - return 0; + return fsi_clk_prepare(fsi); } static void fsi_dai_shutdown(struct snd_pcm_substream *substream, @@ -1588,6 +1636,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, { struct fsi_priv *fsi = fsi_get_priv(substream); + fsi_clk_unprepare(fsi); fsi_clk_invalid(fsi); }