History

ASoC: Intel: sof_sdw: handle errors on card registration

If the card registration fails, typically because of deferred probes, the device properties added for headset codecs are not removed, which leads to kernel oopses in driver bind/unbind tests. We already clean-up the device properties when the card is removed, this code can be moved as a helper and called upon card registration errors.

Pierre-Louis Bossart committed 4 years ago

Commit fe154c41 parent ed0a7fb1 file · +29 −22Browse files

Unified · Split

sound/soc/intel/boards/sof_sdw.c+29−22
@@ -1398,6 +1398,33 @@ static struct snd_soc_card card_sof_sdw = { · 1397 unmodified lines
1398 .late_probe = sof_sdw_card_late_probe,1398 .late_probe = sof_sdw_card_late_probe,
1399};1399};
1400 1400
1401static void mc_dailink_exit_loop(struct snd_soc_card *card)
1402{
1403 struct snd_soc_dai_link *link;
1404 int ret;
1405 int i, j;
1406
1407 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
1408 if (!codec_info_list[i].exit)
1409 continue;
1410 /*
1411 * We don't need to call .exit function if there is no matched
1412 * dai link found.
1413 */
1414 for_each_card_prelinks(card, j, link) {
1415 if (!strcmp(link->codecs[0].dai_name,
1416 codec_info_list[i].dai_name)) {
1417 ret = codec_info_list[i].exit(card, link);
1418 if (ret)
1419 dev_warn(card->dev,
1420 "codec exit failed %d\n",
1421 ret);
1422 break;
1423 }
1424 }
1425 }
1426}
1427
1401static int mc_probe(struct platform_device *pdev)1428static int mc_probe(struct platform_device *pdev)
1402{1429{
1403 struct snd_soc_card *card = &card_sof_sdw;1430 struct snd_soc_card *card = &card_sof_sdw;
@@ -1462,6 +1489,7 @@ static int mc_probe(struct platform_device *pdev) · 58 unmodified lines
1462 ret = devm_snd_soc_register_card(&pdev->dev, card);1489 ret = devm_snd_soc_register_card(&pdev->dev, card);
1463 if (ret) {1490 if (ret) {
1464 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);1491 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);
1492 mc_dailink_exit_loop(card);
1465 return ret;1493 return ret;
1466 }1494 }
1467 1495
@@ -1473,29 +1501,8 @@ static int mc_probe(struct platform_device *pdev) · 5 unmodified lines
1473static int mc_remove(struct platform_device *pdev)1501static int mc_remove(struct platform_device *pdev)
1474{1502{
1475 struct snd_soc_card *card = platform_get_drvdata(pdev);1503 struct snd_soc_card *card = platform_get_drvdata(pdev);
1476 struct snd_soc_dai_link *link;
1477 int ret;
1478 int i, j;
1479 1504
1480 for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {1505 mc_dailink_exit_loop(card);
1481 if (!codec_info_list[i].exit)
1482 continue;
1483 /*
1484 * We don't need to call .exit function if there is no matched
1485 * dai link found.
1486 */
1487 for_each_card_prelinks(card, j, link) {
1488 if (!strcmp(link->codecs[0].dai_name,
1489 codec_info_list[i].dai_name)) {
1490 ret = codec_info_list[i].exit(card, link);
1491 if (ret)
1492 dev_warn(&pdev->dev,
1493 "codec exit failed %d\n",
1494 ret);
1495 break;
1496 }
1497 }
1498 }
1499 1506
1500 return 0;1507 return 0;
1501}1508}