ASoC: stm32: spdifrx: manage rebind issue

The commit e894efef9a ("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>
This commit is contained in:
Olivier Moysan 2020-03-18 15:41:24 +01:00 committed by Mark Brown
parent eff4d9ecd0
commit 794df9448e
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -944,6 +944,22 @@ static int stm32_spdifrx_parse_of(struct platform_device *pdev,
return 0; 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) static int stm32_spdifrx_probe(struct platform_device *pdev)
{ {
struct stm32_spdifrx_data *spdifrx; struct stm32_spdifrx_data *spdifrx;
@ -995,25 +1011,27 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
udelay(2); udelay(2);
reset_control_deassert(rst); reset_control_deassert(rst);
ret = devm_snd_soc_register_component(&pdev->dev, pcm_config = &stm32_spdifrx_pcm_config;
&stm32_spdifrx_component, ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
stm32_spdifrx_dai, if (ret) {
ARRAY_SIZE(stm32_spdifrx_dai)); if (ret != -EPROBE_DEFER)
if (ret) dev_err(&pdev->dev, "PCM DMA register error %d\n", ret);
return ret; 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); ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);
if (ret) if (ret)
goto error; goto error;
pcm_config = &stm32_spdifrx_pcm_config;
ret = devm_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;
}
ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr); ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr);
if (ret) if (ret)
goto error; goto error;
@ -1029,27 +1047,11 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
return ret; return ret;
error: error:
if (!IS_ERR(spdifrx->ctrl_chan)) stm32_spdifrx_remove(pdev);
dma_release_channel(spdifrx->ctrl_chan);
if (spdifrx->dmab)
snd_dma_free_pages(spdifrx->dmab);
return ret; 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); MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP