mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-19 09:04:57 +00:00
ASoC: uniphier: Fix double reset assersion when transitioning to suspend state
[ Upstream commitc372a35550
] 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:139a342002
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
e6bc6e2c0d
commit
b1f1b83e25
2 changed files with 22 additions and 10 deletions
|
@ -424,8 +424,11 @@ int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct uniphier_aio *aio = uniphier_priv(dai);
|
struct uniphier_aio *aio = uniphier_priv(dai);
|
||||||
|
|
||||||
reset_control_assert(aio->chip->rst);
|
aio->chip->num_wup_aios--;
|
||||||
clk_disable_unprepare(aio->chip->clk);
|
if (!aio->chip->num_wup_aios) {
|
||||||
|
reset_control_assert(aio->chip->rst);
|
||||||
|
clk_disable_unprepare(aio->chip->clk);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -439,13 +442,15 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
|
||||||
if (!aio->chip->active)
|
if (!aio->chip->active)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = clk_prepare_enable(aio->chip->clk);
|
if (!aio->chip->num_wup_aios) {
|
||||||
if (ret)
|
ret = clk_prepare_enable(aio->chip->clk);
|
||||||
return ret;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = reset_control_deassert(aio->chip->rst);
|
ret = reset_control_deassert(aio->chip->rst);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out_clock;
|
goto err_out_clock;
|
||||||
|
}
|
||||||
|
|
||||||
aio_iecout_set_enable(aio->chip, true);
|
aio_iecout_set_enable(aio->chip, true);
|
||||||
aio_chip_init(aio->chip);
|
aio_chip_init(aio->chip);
|
||||||
|
@ -458,7 +463,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
|
||||||
|
|
||||||
ret = aio_init(sub);
|
ret = aio_init(sub);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out_clock;
|
goto err_out_reset;
|
||||||
|
|
||||||
if (!sub->setting)
|
if (!sub->setting)
|
||||||
continue;
|
continue;
|
||||||
|
@ -466,11 +471,16 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
|
||||||
aio_port_reset(sub);
|
aio_port_reset(sub);
|
||||||
aio_src_reset(sub);
|
aio_src_reset(sub);
|
||||||
}
|
}
|
||||||
|
aio->chip->num_wup_aios++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_out_reset:
|
||||||
|
if (!aio->chip->num_wup_aios)
|
||||||
|
reset_control_assert(aio->chip->rst);
|
||||||
err_out_clock:
|
err_out_clock:
|
||||||
clk_disable_unprepare(aio->chip->clk);
|
if (!aio->chip->num_wup_aios)
|
||||||
|
clk_disable_unprepare(aio->chip->clk);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -619,6 +629,7 @@ int uniphier_aio_probe(struct platform_device *pdev)
|
||||||
return PTR_ERR(chip->rst);
|
return PTR_ERR(chip->rst);
|
||||||
|
|
||||||
chip->num_aios = chip->chip_spec->num_dais;
|
chip->num_aios = chip->chip_spec->num_dais;
|
||||||
|
chip->num_wup_aios = chip->num_aios;
|
||||||
chip->aios = devm_kcalloc(dev,
|
chip->aios = devm_kcalloc(dev,
|
||||||
chip->num_aios, sizeof(struct uniphier_aio),
|
chip->num_aios, sizeof(struct uniphier_aio),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
|
@ -285,6 +285,7 @@ struct uniphier_aio_chip {
|
||||||
|
|
||||||
struct uniphier_aio *aios;
|
struct uniphier_aio *aios;
|
||||||
int num_aios;
|
int num_aios;
|
||||||
|
int num_wup_aios;
|
||||||
struct uniphier_aio_pll *plls;
|
struct uniphier_aio_pll *plls;
|
||||||
int num_plls;
|
int num_plls;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue