From: Kunihiko Hayashi <hayashi.kunih...@socionext.com>

[ Upstream commit c372a35550c8d60f673b20210eea58a06d6d38cb ]

When transitioning to supend state, uniphier_aio_dai_suspend() is called
and asserts reset lines and disables clocks.

However, if there are two or more DAIs, uniphier_aio_dai_suspend() are
called multiple times, and double reset assersion will cause.

This patch defines the counter that has the number of DAIs at first, and
whenever uniphier_aio_dai_suspend() are called, it decrements the
counter. And only if the counter is zero, it asserts reset lines and
disables clocks.

In the same way, uniphier_aio_dai_resume() are called, it increments the
counter after deasserting reset lines and enabling clocks.

Fixes: 139a34200233 ("ASoC: uniphier: add support for UniPhier AIO CPU DAI 
driver")
Signed-off-by: Kunihiko Hayashi <hayashi.kunih...@socionext.com>
Link: 
https://lore.kernel.org/r/1566281764-14059-1-git-send-email-hayashi.kunih...@socionext.com
Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 sound/soc/uniphier/aio-cpu.c | 31 +++++++++++++++++++++----------
 sound/soc/uniphier/aio.h     |  1 +
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index ee90e6c3937ce..2ae582a99b636 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -424,8 +424,11 @@ int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
 {
        struct uniphier_aio *aio = uniphier_priv(dai);
 
-       reset_control_assert(aio->chip->rst);
-       clk_disable_unprepare(aio->chip->clk);
+       aio->chip->num_wup_aios--;
+       if (!aio->chip->num_wup_aios) {
+               reset_control_assert(aio->chip->rst);
+               clk_disable_unprepare(aio->chip->clk);
+       }
 
        return 0;
 }
@@ -439,13 +442,15 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
        if (!aio->chip->active)
                return 0;
 
-       ret = clk_prepare_enable(aio->chip->clk);
-       if (ret)
-               return ret;
+       if (!aio->chip->num_wup_aios) {
+               ret = clk_prepare_enable(aio->chip->clk);
+               if (ret)
+                       return ret;
 
-       ret = reset_control_deassert(aio->chip->rst);
-       if (ret)
-               goto err_out_clock;
+               ret = reset_control_deassert(aio->chip->rst);
+               if (ret)
+                       goto err_out_clock;
+       }
 
        aio_iecout_set_enable(aio->chip, true);
        aio_chip_init(aio->chip);
@@ -458,7 +463,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
 
                ret = aio_init(sub);
                if (ret)
-                       goto err_out_clock;
+                       goto err_out_reset;
 
                if (!sub->setting)
                        continue;
@@ -466,11 +471,16 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
                aio_port_reset(sub);
                aio_src_reset(sub);
        }
+       aio->chip->num_wup_aios++;
 
        return 0;
 
+err_out_reset:
+       if (!aio->chip->num_wup_aios)
+               reset_control_assert(aio->chip->rst);
 err_out_clock:
-       clk_disable_unprepare(aio->chip->clk);
+       if (!aio->chip->num_wup_aios)
+               clk_disable_unprepare(aio->chip->clk);
 
        return ret;
 }
@@ -619,6 +629,7 @@ int uniphier_aio_probe(struct platform_device *pdev)
                return PTR_ERR(chip->rst);
 
        chip->num_aios = chip->chip_spec->num_dais;
+       chip->num_wup_aios = chip->num_aios;
        chip->aios = devm_kcalloc(dev,
                                  chip->num_aios, sizeof(struct uniphier_aio),
                                  GFP_KERNEL);
diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h
index ca6ccbae0ee8c..a7ff7e556429b 100644
--- a/sound/soc/uniphier/aio.h
+++ b/sound/soc/uniphier/aio.h
@@ -285,6 +285,7 @@ struct uniphier_aio_chip {
 
        struct uniphier_aio *aios;
        int num_aios;
+       int num_wup_aios;
        struct uniphier_aio_pll *plls;
        int num_plls;
 
-- 
2.20.1



Reply via email to