summaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorOlivier Moysan <olivier.moysan@st.com>2020-03-18 15:41:24 +0100
committerMark Brown <broonie@kernel.org>2020-03-18 19:55:25 +0000
commit794df9448edb55978e50372f083aeedade1b2844 (patch)
treeee3f039cc352725383faaa7cca0d6bb930a42b02 /sound/soc
parenteff4d9ecd05934ba95fca40952bd613d3e594d4e (diff)
downloadlinux-794df9448edb55978e50372f083aeedade1b2844.tar.bz2
ASoC: stm32: spdifrx: manage rebind issue
The commit e894efef9ac7 ("ASoC: core: add support to card rebind") allows to rebind the sound card after a rebind of one of its component. With this commit, the sound card is actually rebound, but may be no more functional. Corrections: - Call snd_dmaengine_pcm_register() before snd_soc_register_component(). - Call snd_dmaengine_pcm_unregister() and snd_soc_unregister_component() explicitly from SPDFIRX driver. Signed-off-by: Olivier Moysan <olivier.moysan@st.com> Link: https://lore.kernel.org/r/20200318144125.9163-3-olivier.moysan@st.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/stm/stm32_spdifrx.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index 49766afdae61..ae7a0f46a6fb 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -944,6 +944,22 @@ static int stm32_spdifrx_parse_of(struct platform_device *pdev,
return 0;
}
+static int stm32_spdifrx_remove(struct platform_device *pdev)
+{
+ struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev);
+
+ if (spdifrx->ctrl_chan)
+ dma_release_channel(spdifrx->ctrl_chan);
+
+ if (spdifrx->dmab)
+ snd_dma_free_pages(spdifrx->dmab);
+
+ snd_dmaengine_pcm_unregister(&pdev->dev);
+ snd_soc_unregister_component(&pdev->dev);
+
+ return 0;
+}
+
static int stm32_spdifrx_probe(struct platform_device *pdev)
{
struct stm32_spdifrx_data *spdifrx;
@@ -995,25 +1011,27 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
udelay(2);
reset_control_deassert(rst);
- ret = devm_snd_soc_register_component(&pdev->dev,
- &stm32_spdifrx_component,
- stm32_spdifrx_dai,
- ARRAY_SIZE(stm32_spdifrx_dai));
- if (ret)
- return ret;
-
- ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
- if (ret)
- goto error;
-
pcm_config = &stm32_spdifrx_pcm_config;
- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
+ ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "PCM DMA register error %d\n", ret);
- goto error;
+ return ret;
}
+ ret = snd_soc_register_component(&pdev->dev,
+ &stm32_spdifrx_component,
+ stm32_spdifrx_dai,
+ ARRAY_SIZE(stm32_spdifrx_dai));
+ if (ret) {
+ snd_dmaengine_pcm_unregister(&pdev->dev);
+ return ret;
+ }
+
+ ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
+ if (ret)
+ goto error;
+
ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr);
if (ret)
goto error;
@@ -1029,27 +1047,11 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
return ret;
error:
- if (!IS_ERR(spdifrx->ctrl_chan))
- dma_release_channel(spdifrx->ctrl_chan);
- if (spdifrx->dmab)
- snd_dma_free_pages(spdifrx->dmab);
+ stm32_spdifrx_remove(pdev);
return ret;
}
-static int stm32_spdifrx_remove(struct platform_device *pdev)
-{
- struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev);
-
- if (spdifrx->ctrl_chan)
- dma_release_channel(spdifrx->ctrl_chan);
-
- if (spdifrx->dmab)
- snd_dma_free_pages(spdifrx->dmab);
-
- return 0;
-}
-
MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);
#ifdef CONFIG_PM_SLEEP