aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-10-27 06:34:02 -0400
committerMark Brown <broonie@kernel.org>2016-10-28 13:21:13 -0400
commit73f5dfc68316bef2ab7062ecdefd4b0ca941b4c1 (patch)
treed0e26273bb32d1ae302b64e3cd26848cd158a084
parent1001354ca34179f3db924eb66672442a173147dc (diff)
ASoC: samsung: get access to DMA engine early to defer probe properly
ASoC Samsung sub-drivers tried to get access to their DMA engine controllers as a last step in driver probe. If a DMA engine was not available yet, samsung_asoc_dma_platform_register() function ended in -EPROBE_DEFER, but the driver already registered its component to ASoC core. This patch moves samsung_asoc_dma_platform_register() call before registering any components, to the common place, where driver was gathering all needed resources. In case of Samsung Exynos i2s driver the issue was even worse. The driver managed already to register its secondary DAI platform device before even getting the DMA engine access. That together with -EPROBE_DEFER error code from samsung_i2s_probe() immediately triggered another round of deferred probe retry and in turn endless loop of driver probing. This patch fixes broken boot on Odroid XU3 and other Exynos5422-based boards. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/samsung/ac97.c10
-rw-r--r--sound/soc/samsung/i2s.c19
-rw-r--r--sound/soc/samsung/pcm.c19
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c16
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c14
-rw-r--r--sound/soc/samsung/spdif.c14
6 files changed, 47 insertions, 45 deletions
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 97d6700b1009..cbc0023c2bc8 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -383,11 +383,6 @@ static int s3c_ac97_probe(struct platform_device *pdev)
383 goto err4; 383 goto err4;
384 } 384 }
385 385
386 ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
387 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
388 if (ret)
389 goto err5;
390
391 ret = samsung_asoc_dma_platform_register(&pdev->dev, 386 ret = samsung_asoc_dma_platform_register(&pdev->dev,
392 ac97_pdata->dma_filter, 387 ac97_pdata->dma_filter,
393 NULL, NULL); 388 NULL, NULL);
@@ -396,6 +391,11 @@ static int s3c_ac97_probe(struct platform_device *pdev)
396 goto err5; 391 goto err5;
397 } 392 }
398 393
394 ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
395 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
396 if (ret)
397 goto err5;
398
399 return 0; 399 return 0;
400err5: 400err5:
401 free_irq(irq_res->start, NULL); 401 free_irq(irq_res->start, NULL);
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 7e32cf4581f8..7825bff45ae3 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1237,14 +1237,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1237 dev_err(&pdev->dev, "Unable to get drvdata\n"); 1237 dev_err(&pdev->dev, "Unable to get drvdata\n");
1238 return -EFAULT; 1238 return -EFAULT;
1239 } 1239 }
1240 ret = devm_snd_soc_register_component(&sec_dai->pdev->dev, 1240 ret = samsung_asoc_dma_platform_register(&pdev->dev,
1241 &samsung_i2s_component, 1241 sec_dai->filter, "tx-sec", NULL);
1242 &sec_dai->i2s_dai_drv, 1);
1243 if (ret != 0) 1242 if (ret != 0)
1244 return ret; 1243 return ret;
1245 1244
1246 return samsung_asoc_dma_platform_register(&pdev->dev, 1245 return devm_snd_soc_register_component(&sec_dai->pdev->dev,
1247 sec_dai->filter, "tx-sec", NULL); 1246 &samsung_i2s_component,
1247 &sec_dai->i2s_dai_drv, 1);
1248 } 1248 }
1249 1249
1250 pri_dai = i2s_alloc_dai(pdev, false); 1250 pri_dai = i2s_alloc_dai(pdev, false);
@@ -1314,6 +1314,11 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1314 if (quirks & QUIRK_PRI_6CHAN) 1314 if (quirks & QUIRK_PRI_6CHAN)
1315 pri_dai->i2s_dai_drv.playback.channels_max = 6; 1315 pri_dai->i2s_dai_drv.playback.channels_max = 6;
1316 1316
1317 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
1318 NULL, NULL);
1319 if (ret < 0)
1320 goto err_disable_clk;
1321
1317 if (quirks & QUIRK_SEC_DAI) { 1322 if (quirks & QUIRK_SEC_DAI) {
1318 sec_dai = i2s_alloc_dai(pdev, true); 1323 sec_dai = i2s_alloc_dai(pdev, true);
1319 if (!sec_dai) { 1324 if (!sec_dai) {
@@ -1353,10 +1358,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1353 if (ret < 0) 1358 if (ret < 0)
1354 goto err_free_dai; 1359 goto err_free_dai;
1355 1360
1356 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
1357 NULL, NULL);
1358 if (ret < 0)
1359 goto err_free_dai;
1360 1361
1361 pm_runtime_enable(&pdev->dev); 1362 pm_runtime_enable(&pdev->dev);
1362 1363
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 43e367a9acc3..c484985812ed 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -565,24 +565,25 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
565 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; 565 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
566 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; 566 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
567 567
568 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
569 NULL, NULL);
570 if (ret) {
571 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
572 goto err5;
573 }
574
568 pm_runtime_enable(&pdev->dev); 575 pm_runtime_enable(&pdev->dev);
569 576
570 ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component, 577 ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component,
571 &s3c_pcm_dai[pdev->id], 1); 578 &s3c_pcm_dai[pdev->id], 1);
572 if (ret != 0) { 579 if (ret != 0) {
573 dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); 580 dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
574 goto err5; 581 goto err6;
575 }
576
577 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
578 NULL, NULL);
579 if (ret) {
580 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
581 goto err5;
582 } 582 }
583 583
584 return 0; 584 return 0;
585 585err6:
586 pm_runtime_disable(&pdev->dev);
586err5: 587err5:
587 clk_disable_unprepare(pcm->pclk); 588 clk_disable_unprepare(pcm->pclk);
588err4: 589err4:
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 3e89fbc0c51d..0a4718207e6e 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -168,19 +168,19 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
168 s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD; 168 s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
169 s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; 169 s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
170 170
171 ret = s3c_i2sv2_register_component(&pdev->dev, -1, 171 ret = samsung_asoc_dma_platform_register(&pdev->dev,
172 &s3c2412_i2s_component, 172 pdata->dma_filter,
173 &s3c2412_i2s_dai); 173 NULL, NULL);
174 if (ret) { 174 if (ret) {
175 pr_err("failed to register the dai\n"); 175 pr_err("failed to register the DMA: %d\n", ret);
176 return ret; 176 return ret;
177 } 177 }
178 178
179 ret = samsung_asoc_dma_platform_register(&pdev->dev, 179 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
180 pdata->dma_filter, 180 &s3c2412_i2s_component,
181 NULL, NULL); 181 &s3c2412_i2s_dai);
182 if (ret) 182 if (ret)
183 pr_err("failed to register the DMA: %d\n", ret); 183 pr_err("failed to register the dai\n");
184 184
185 return ret; 185 return ret;
186} 186}
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index c78a936a3099..9052f6a7073e 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -474,18 +474,18 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
474 s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO; 474 s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
475 s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; 475 s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
476 476
477 ret = devm_snd_soc_register_component(&pdev->dev, 477 ret = samsung_asoc_dma_platform_register(&pdev->dev,
478 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); 478 pdata->dma_filter,
479 NULL, NULL);
479 if (ret) { 480 if (ret) {
480 pr_err("failed to register the dai\n"); 481 pr_err("failed to register the dma: %d\n", ret);
481 return ret; 482 return ret;
482 } 483 }
483 484
484 ret = samsung_asoc_dma_platform_register(&pdev->dev, 485 ret = devm_snd_soc_register_component(&pdev->dev,
485 pdata->dma_filter, 486 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
486 NULL, NULL);
487 if (ret) 487 if (ret)
488 pr_err("failed to register the dma: %d\n", ret); 488 pr_err("failed to register the dai\n");
489 489
490 return ret; 490 return ret;
491} 491}
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 26c1fbed4d35..704b7b12bf8b 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -416,6 +416,13 @@ static int spdif_probe(struct platform_device *pdev)
416 goto err3; 416 goto err3;
417 } 417 }
418 418
419 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
420 NULL, NULL);
421 if (ret) {
422 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
423 goto err4;
424 }
425
419 dev_set_drvdata(&pdev->dev, spdif); 426 dev_set_drvdata(&pdev->dev, spdif);
420 427
421 ret = devm_snd_soc_register_component(&pdev->dev, 428 ret = devm_snd_soc_register_component(&pdev->dev,
@@ -435,13 +442,6 @@ static int spdif_probe(struct platform_device *pdev)
435 442
436 spdif->dma_playback = &spdif_stereo_out; 443 spdif->dma_playback = &spdif_stereo_out;
437 444
438 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
439 NULL, NULL);
440 if (ret) {
441 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
442 goto err4;
443 }
444
445 return 0; 445 return 0;
446err4: 446err4:
447 iounmap(spdif->regs); 447 iounmap(spdif->regs);