Commit d18ca863 authored by Joao Paulo Goncalves's avatar Joao Paulo Goncalves Committed by Mark Brown

ASoC: ti: davinci-mcasp: Fix race condition during probe

When using davinci-mcasp as CPU DAI with simple-card, there are some
conditions that cause simple-card to finish registering a sound card before
davinci-mcasp finishes registering all sound components. This creates a
non-working sound card from userspace with no problem indication apart
from not being able to play/record audio on a PCM stream. The issue
arises during simultaneous probe execution of both drivers. Specifically,
the simple-card driver, awaiting a CPU DAI, proceeds as soon as
davinci-mcasp registers its DAI. However, this process can lead to the
client mutex lock (client_mutex in soc-core.c) being held or davinci-mcasp
being preempted before PCM DMA registration on davinci-mcasp finishes.
This situation occurs when the probes of both drivers run concurrently.
Below is the code path for this condition. To solve the issue, defer
davinci-mcasp CPU DAI registration to the last step in the audio part of
it. This way, simple-card CPU DAI parsing will be deferred until all
audio components are registered.

Fail Code Path:

simple-card.c: probe starts
simple-card.c: simple_dai_link_of: simple_parse_node(..,cpu,..) returns EPROBE_DEFER, no CPU DAI yet
davinci-mcasp.c: probe starts
davinci-mcasp.c: devm_snd_soc_register_component() register CPU DAI
simple-card.c: probes again, finish CPU DAI parsing and call devm_snd_soc_register_card()
simple-card.c: finish probe
davinci-mcasp.c: *dma_pcm_platform_register() register PCM  DMA
davinci-mcasp.c: probe finish

Cc: stable@vger.kernel.org
Fixes: 9fbd58cf ("ASoC: davinci-mcasp: Choose PCM driver based on configured DMA controller")
Signed-off-by: default avatarJoao Paulo Goncalves <joao.goncalves@toradex.com>
Acked-by: default avatarPeter Ujfalusi <peter.ujfalusi@gmail.com>
Reviewed-by: default avatarJai Luthra <j-luthra@ti.com>
Link: https://lore.kernel.org/r/20240417184138.1104774-1-jpaulo.silvagoncalves@gmail.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4cbb5050
...@@ -2417,12 +2417,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -2417,12 +2417,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
mcasp_reparent_fck(pdev); mcasp_reparent_fck(pdev);
ret = devm_snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
&davinci_mcasp_dai[mcasp->op_mode], 1);
if (ret != 0)
goto err;
ret = davinci_mcasp_get_dma_type(mcasp); ret = davinci_mcasp_get_dma_type(mcasp);
switch (ret) { switch (ret) {
case PCM_EDMA: case PCM_EDMA:
...@@ -2449,6 +2443,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -2449,6 +2443,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err; goto err;
} }
ret = devm_snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
&davinci_mcasp_dai[mcasp->op_mode], 1);
if (ret != 0)
goto err;
no_audio: no_audio:
ret = davinci_mcasp_init_gpiochip(mcasp); ret = davinci_mcasp_init_gpiochip(mcasp);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment