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. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20220606203752.144159-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
ed0a7fb29c
commit
fe154c4ff3
|
@ -1398,6 +1398,33 @@ static struct snd_soc_card card_sof_sdw = {
|
|||
.late_probe = sof_sdw_card_late_probe,
|
||||
};
|
||||
|
||||
static void mc_dailink_exit_loop(struct snd_soc_card *card)
|
||||
{
|
||||
struct snd_soc_dai_link *link;
|
||||
int ret;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
|
||||
if (!codec_info_list[i].exit)
|
||||
continue;
|
||||
/*
|
||||
* We don't need to call .exit function if there is no matched
|
||||
* dai link found.
|
||||
*/
|
||||
for_each_card_prelinks(card, j, link) {
|
||||
if (!strcmp(link->codecs[0].dai_name,
|
||||
codec_info_list[i].dai_name)) {
|
||||
ret = codec_info_list[i].exit(card, link);
|
||||
if (ret)
|
||||
dev_warn(card->dev,
|
||||
"codec exit failed %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int mc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = &card_sof_sdw;
|
||||
|
@ -1462,6 +1489,7 @@ static int mc_probe(struct platform_device *pdev)
|
|||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "snd_soc_register_card failed %d\n", ret);
|
||||
mc_dailink_exit_loop(card);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1473,29 +1501,8 @@ static int mc_probe(struct platform_device *pdev)
|
|||
static int mc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct snd_soc_dai_link *link;
|
||||
int ret;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
|
||||
if (!codec_info_list[i].exit)
|
||||
continue;
|
||||
/*
|
||||
* We don't need to call .exit function if there is no matched
|
||||
* dai link found.
|
||||
*/
|
||||
for_each_card_prelinks(card, j, link) {
|
||||
if (!strcmp(link->codecs[0].dai_name,
|
||||
codec_info_list[i].dai_name)) {
|
||||
ret = codec_info_list[i].exit(card, link);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
"codec exit failed %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mc_dailink_exit_loop(card);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue