Unverified Commit 794df944 authored by Olivier Moysan's avatar Olivier Moysan Committed by Mark Brown
Browse files

ASoC: stm32: spdifrx: manage rebind issue



The commit e894efef ("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: default avatarOlivier Moysan <olivier.moysan@st.com>
Link: https://lore.kernel.org/r/20200318144125.9163-3-olivier.moysan@st.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent eff4d9ec
Loading
Loading
Loading
Loading
+32 −30
Original line number Diff line number Diff line
@@ -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,
	pcm_config = &stm32_spdifrx_pcm_config;
	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);
		return ret;
	}

	ret = snd_soc_register_component(&pdev->dev,
					 &stm32_spdifrx_component,
					 stm32_spdifrx_dai,
					 ARRAY_SIZE(stm32_spdifrx_dai));
	if (ret)
	if (ret) {
		snd_dmaengine_pcm_unregister(&pdev->dev);
		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);
	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);
	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