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
13981398 .late_probe = sof_sdw_card_late_probe,
13991399 };
14001400
1401+static 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+
14011428 static int mc_probe(struct platform_device *pdev)
14021429 {
14031430 struct snd_soc_card *card = &card_sof_sdw;
@@ -1462,6 +1489,7 @@ static int mc_probe(struct platform_device *pdev) · 58 unmodified lines
14621489 ret = devm_snd_soc_register_card(&pdev->dev, card);
14631490 if (ret) {
14641491 dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);
1492+ mc_dailink_exit_loop(card);
14651493 return ret;
14661494 }
14671495
@@ -1473,29 +1501,8 @@ static int mc_probe(struct platform_device *pdev) · 5 unmodified lines
14731501 static int mc_remove(struct platform_device *pdev)
14741502 {
14751503 struct snd_soc_card *card = platform_get_drvdata(pdev);
1476− struct snd_soc_dai_link *link;
1477− int ret;
1478− int i, j;
14791504
1480− for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
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− }
1505+ mc_dailink_exit_loop(card);
14991506
15001507 return 0;
15011508 }