Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Olivier Moysan and committed by
Mark Brown
794df944 eff4d9ec

+32 -30
+32 -30
sound/soc/stm/stm32_spdifrx.c
··· 944 944 return 0; 945 945 } 946 946 947 + static int stm32_spdifrx_remove(struct platform_device *pdev) 948 + { 949 + struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); 950 + 951 + if (spdifrx->ctrl_chan) 952 + dma_release_channel(spdifrx->ctrl_chan); 953 + 954 + if (spdifrx->dmab) 955 + snd_dma_free_pages(spdifrx->dmab); 956 + 957 + snd_dmaengine_pcm_unregister(&pdev->dev); 958 + snd_soc_unregister_component(&pdev->dev); 959 + 960 + return 0; 961 + } 962 + 947 963 static int stm32_spdifrx_probe(struct platform_device *pdev) 948 964 { 949 965 struct stm32_spdifrx_data *spdifrx; ··· 1011 995 udelay(2); 1012 996 reset_control_deassert(rst); 1013 997 1014 - ret = devm_snd_soc_register_component(&pdev->dev, 1015 - &stm32_spdifrx_component, 1016 - stm32_spdifrx_dai, 1017 - ARRAY_SIZE(stm32_spdifrx_dai)); 1018 - if (ret) 998 + pcm_config = &stm32_spdifrx_pcm_config; 999 + ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0); 1000 + if (ret) { 1001 + if (ret != -EPROBE_DEFER) 1002 + dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); 1019 1003 return ret; 1004 + } 1005 + 1006 + ret = snd_soc_register_component(&pdev->dev, 1007 + &stm32_spdifrx_component, 1008 + stm32_spdifrx_dai, 1009 + ARRAY_SIZE(stm32_spdifrx_dai)); 1010 + if (ret) { 1011 + snd_dmaengine_pcm_unregister(&pdev->dev); 1012 + return ret; 1013 + } 1020 1014 1021 1015 ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx); 1022 1016 if (ret) 1023 1017 goto error; 1024 - 1025 - pcm_config = &stm32_spdifrx_pcm_config; 1026 - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0); 1027 - if (ret) { 1028 - if (ret != -EPROBE_DEFER) 1029 - dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); 1030 - goto error; 1031 - } 1032 1018 1033 1019 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr); 1034 1020 if (ret) ··· 1047 1029 return ret; 1048 1030 1049 1031 error: 1050 - if (!IS_ERR(spdifrx->ctrl_chan)) 1051 - dma_release_channel(spdifrx->ctrl_chan); 1052 - if (spdifrx->dmab) 1053 - snd_dma_free_pages(spdifrx->dmab); 1032 + stm32_spdifrx_remove(pdev); 1054 1033 1055 1034 return ret; 1056 - } 1057 - 1058 - static int stm32_spdifrx_remove(struct platform_device *pdev) 1059 - { 1060 - struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); 1061 - 1062 - if (spdifrx->ctrl_chan) 1063 - dma_release_channel(spdifrx->ctrl_chan); 1064 - 1065 - if (spdifrx->dmab) 1066 - snd_dma_free_pages(spdifrx->dmab); 1067 - 1068 - return 0; 1069 1035 } 1070 1036 1071 1037 MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);