Skip to content

Commit

Permalink
ASoC: uniphier: Fix double reset assersion when transitioning to susp…
Browse files Browse the repository at this point in the history
…end state

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: 139a342 ("ASoC: uniphier: add support for UniPhier AIO CPU DAI driver")
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Link: https://lore.kernel.org/r/1566281764-14059-1-git-send-email-hayashi.kunihiko@socionext.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
khayash1 authored and broonie committed Aug 20, 2019
1 parent 8661ab5 commit c372a35
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
31 changes: 21 additions & 10 deletions sound/soc/uniphier/aio-cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -458,19 +463,24 @@ 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;

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;
}
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions sound/soc/uniphier/aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit c372a35

Please sign in to comment.