Unverified Commit c372a355 authored by Kunihiko Hayashi's avatar Kunihiko Hayashi Committed by Mark Brown
Browse files

ASoC: uniphier: Fix double reset assersion when transitioning to suspend 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: 139a3420 ("ASoC: uniphier: add support for UniPhier AIO CPU DAI driver")
Signed-off-by: default avatarKunihiko Hayashi <hayashi.kunihiko@socionext.com>
Link: https://lore.kernel.org/r/1566281764-14059-1-git-send-email-hayashi.kunihiko@socionext.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8661ab5b
Loading
Loading
Loading
Loading
+21 −10
Original line number Diff line number Diff line
@@ -424,8 +424,11 @@ int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
{
	struct uniphier_aio *aio = uniphier_priv(dai);

	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,6 +442,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
	if (!aio->chip->active)
		return 0;

	if (!aio->chip->num_wup_aios) {
		ret = clk_prepare_enable(aio->chip->clk);
		if (ret)
			return ret;
@@ -446,6 +450,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
		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,10 +471,15 @@ 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:
	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);
+1 −0
Original line number Diff line number Diff line
@@ -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;