summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-10-23 09:46:49 -0400
committerMark Brown <broonie@kernel.org>2019-10-23 13:20:55 -0400
commitdc39596a906d5b604f4e64597b6e904fc14625e8 (patch)
tree240b6e0c2acada80ac7116f2b3c31b593838c04c
parentd10be65f87fc9d98ad3cbdc406e86745fe8c59e2 (diff)
ASoC: kirkwood: fix device remove ordering
The devm conversion of kirkwood was incorrect; on removal, devm takes effect after the "remove" function has returned. So, the effect of the conversion was to change the order during remove from: - snd_soc_unregister_component() (unpublishes interfaces) - clk_disable_unprepare() - cleanup resources After the conversion, this became: - clk_disable_unprepare() - while the device may still be active - snd_soc_unregister_component() - cleanup resources Hence, it introduces a bug, where the internal clock for the device may be shut down before the device itself has been shut down. It is known that Marvell SoCs, including Dove, locks up if registers for a peripheral that has its clocks disabled are accessed. Fixes: f98fc0f8154e ("ASoC: kirkwood: replace platform to component") Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Link: https://lore.kernel.org/r/E1iNGyP-0004oN-BA@rmk-PC.armlinux.org.uk Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 9575a636d016..2a4ffe945177 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -587,7 +587,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
587 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; 587 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
588 } 588 }
589 589
590 err = devm_snd_soc_register_component(&pdev->dev, &kirkwood_soc_component, 590 err = snd_soc_register_component(&pdev->dev, &kirkwood_soc_component,
591 soc_dai, 2); 591 soc_dai, 2);
592 if (err) { 592 if (err) {
593 dev_err(&pdev->dev, "snd_soc_register_component failed\n"); 593 dev_err(&pdev->dev, "snd_soc_register_component failed\n");
@@ -610,6 +610,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
610{ 610{
611 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 611 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
612 612
613 snd_soc_unregister_component(&pdev->dev);
613 if (!IS_ERR(priv->extclk)) 614 if (!IS_ERR(priv->extclk))
614 clk_disable_unprepare(priv->extclk); 615 clk_disable_unprepare(priv->extclk);
615 clk_disable_unprepare(priv->clk); 616 clk_disable_unprepare(priv->clk);