lkml.org 
[lkml]   [2022]   [Jul]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 187/231] ASoC: Intel: sof_sdw: handle errors on card registration
    Date
    From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

    [ Upstream commit fe154c4ff376bc31041c6441958a08243df09c99 ]

    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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    sound/soc/intel/boards/sof_sdw.c | 51 ++++++++++++++++++--------------
    1 file changed, 29 insertions(+), 22 deletions(-)

    diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
    index 1f00679b4240..ad826ad82d51 100644
    --- a/sound/soc/intel/boards/sof_sdw.c
    +++ b/sound/soc/intel/boards/sof_sdw.c
    @@ -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;
    }
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-19 15:09    [W:4.042 / U:1.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site