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 --- sound/soc/stm/stm32_spdifrx.c | 62 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 30 deletions(-)
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 301f8463390f..1bfa3b2ba974 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; @@ -1031,27 +1049,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