]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
authorbui duc phuc <phucduc.bui@gmail.com>
Tue, 9 Jun 2026 11:38:35 +0000 (18:38 +0700)
committerMark Brown <broonie@kernel.org>
Tue, 9 Jun 2026 23:33:52 +0000 (00:33 +0100)
Add fsi_clk_prepare() and fsi_clk_unprepare() helpers and call them
from fsi_dai_startup() and fsi_dai_shutdown().
This ensures clk_prepare() and clk_unprepare() are executed from
sleepable contexts and keeps clocks prepared only while audio streams
are active.

Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Link: https://patch.msgid.link/20260609113836.45079-11-phucduc.bui@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/renesas/fsi.c

index 716ecf0401fe33c0df221d4b2800b565e222c5c2..e26f39dfe05988b11ac4bd60a262f846061ba0e9 100644 (file)
@@ -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);
 }