From 5bc7d9da73c2f50f1cd1bf876613807e580dd52b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 21 Jul 2020 18:15:42 -0500 Subject: [PATCH] ASoC: Intel: boards: remove device properties Some Intel machine drivers set device properties but rely on the device core to remove them. To help with future API rename or removals based on a direct use of fwnodes, follow the recommendation to remove device properties in the driver. This change was already added for SoundWire boards, but is extended to cover the case where the card registration fails (e.g. due to a bad topology or configuration). Legacy drivers are also modified in the same way. In a follow-up optimization, a generic helper could be created to avoid the copy-paste of remove_properties(). Tested with SoundWire/rt711 and Cherrytrail/rt5640 (no hardware available for the two other configurations). Suggested-by: Andy Shevchenko Signed-off-by: Pierre-Louis Bossart --- sound/soc/intel/boards/bytcht_es8316.c | 25 ++++++++-- sound/soc/intel/boards/bytcr_rt5640.c | 30 ++++++++++-- sound/soc/intel/boards/bytcr_rt5651.c | 34 +++++++++++-- sound/soc/intel/boards/sof_sdw.c | 66 +++++++++++++++----------- sound/soc/intel/boards/sof_sdw_rt711.c | 26 +++++----- 5 files changed, 131 insertions(+), 50 deletions(-) diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 414ae4bb5224a9..2cf3928780c07d 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -462,6 +462,20 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { {} }; +static int remove_properties(struct bus_type *bus, char *codec_name) +{ + struct device *dev; + + dev = bus_find_device_by_name(bus, NULL, codec_name); + if (!dev) + return -EINVAL; + + device_remove_properties(dev); + put_device(dev); + + return 0; +} + static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) { static const char * const mic_name[] = { "in1", "in2" }; @@ -575,7 +589,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) dev_err(dev, "get speaker GPIO failed: %d\n", ret); /* fall through */ case -EPROBE_DEFER: - return ret; + goto err; } } @@ -598,10 +612,14 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (ret) { gpiod_put(priv->speaker_en_gpio); dev_err(dev, "snd_soc_register_card failed: %d\n", ret); - return ret; + goto err; } platform_set_drvdata(pdev, &byt_cht_es8316_card); return 0; + +err: + remove_properties(&i2c_bus_type, codec_name); + return ret; } static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev) @@ -610,7 +628,8 @@ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev) struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); gpiod_put(priv->speaker_en_gpio); - return 0; + + return remove_properties(&i2c_bus_type, codec_name); } static struct platform_driver snd_byt_cht_es8316_mc_driver = { diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index a46777b8048530..802e772416febb 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1156,6 +1156,20 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */ }; +static int remove_properties(struct bus_type *bus, char *codec_name) +{ + struct device *dev; + + dev = bus_find_device_by_name(bus, NULL, codec_name); + if (!dev) + return -EINVAL; + + device_remove_properties(dev); + put_device(dev); + + return 0; +} + static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; @@ -1300,7 +1314,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) * for all other errors, including -EPROBE_DEFER */ if (ret_val != -ENOENT) - return ret_val; + goto err; byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN; } } @@ -1325,17 +1339,26 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card, platform_name); if (ret_val) - return ret_val; + goto err; ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); if (ret_val) { dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); - return ret_val; + goto err; } platform_set_drvdata(pdev, &byt_rt5640_card); return ret_val; + +err: + remove_properties(&i2c_bus_type, byt_rt5640_codec_name); + return ret_val; +} + +static int snd_byt_rt5640_mc_remove(struct platform_device *pdev) +{ + return remove_properties(&i2c_bus_type, byt_rt5640_codec_name); } static struct platform_driver snd_byt_rt5640_mc_driver = { @@ -1346,6 +1369,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = { #endif }, .probe = snd_byt_rt5640_mc_probe, + .remove = snd_byt_rt5640_mc_remove }; module_platform_driver(snd_byt_rt5640_mc_driver); diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 57bec0554ba82d..c1c2a5641d07bf 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -868,6 +868,20 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */ }; +static int remove_properties(struct bus_type *bus, char *codec_name) +{ + struct device *dev; + + dev = bus_find_device_by_name(bus, NULL, codec_name); + if (!dev) + return -EINVAL; + + device_remove_properties(dev); + put_device(dev); + + return 0; +} + static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) { static const char * const mic_name[] = { "dmic", "in1", "in2", "in12" }; @@ -1012,7 +1026,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) /* fall through */ case -EPROBE_DEFER: put_device(codec_dev); - return ret_val; + goto err; } } priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev, @@ -1032,7 +1046,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) /* fall through */ case -EPROBE_DEFER: put_device(codec_dev); - return ret_val; + goto err; } } } @@ -1062,7 +1076,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) * for all other errors, including -EPROBE_DEFER */ if (ret_val != -ENOENT) - return ret_val; + goto err; byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN; } } @@ -1091,17 +1105,26 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card, platform_name); if (ret_val) - return ret_val; + goto err; ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card); if (ret_val) { dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); - return ret_val; + goto err; } platform_set_drvdata(pdev, &byt_rt5651_card); return ret_val; + +err: + remove_properties(&i2c_bus_type, byt_rt5651_codec_name); + return ret_val; +} + +static int snd_byt_rt5651_mc_remove(struct platform_device *pdev) +{ + return remove_properties(&i2c_bus_type, byt_rt5651_codec_name); } static struct platform_driver snd_byt_rt5651_mc_driver = { @@ -1112,6 +1135,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = { #endif }, .probe = snd_byt_rt5651_mc_probe, + .remove = snd_byt_rt5651_mc_remove, }; module_platform_driver(snd_byt_rt5651_mc_driver); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 100c0a83a6ad7a..8865ccd8abbda7 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -945,6 +945,34 @@ static int sof_card_dai_links_create(struct device *dev, return 0; } +static int sof_card_dai_links_exit(struct device *dev, 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(dev, link); + if (ret) + dev_warn(dev, "dai_name %s codec exit failed %d\n", + codec_info_list[i].dai_name, ret); + break; + } + } + } + + return 0; +} + static int sof_sdw_card_late_probe(struct snd_soc_card *card) { int i, ret; @@ -1020,51 +1048,33 @@ static int mc_probe(struct platform_device *pdev) "cfg-spk:%d cfg-amp:%d", (sof_sdw_quirk & SOF_SDW_FOUR_SPK) ? 4 : 2, amp_num); - if (!card->components) - return -ENOMEM; - + if (!card->components) { + ret = -ENOMEM; + goto err; + } card->long_name = sdw_card_long_name; /* Register the card */ ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) { dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); - return ret; + goto err; } platform_set_drvdata(pdev, card); return ret; + +err: + sof_card_dai_links_exit(&pdev->dev, card); + return ret; } 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(&pdev->dev, link); - if (ret) - dev_warn(&pdev->dev, - "codec exit failed %d\n", - ret); - break; - } - } - } - - return 0; + return sof_card_dai_links_exit(&pdev->dev, card); } static struct platform_driver sof_sdw_driver = { diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 606009fa390107..3d7773ee819c15 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -40,6 +40,20 @@ static int rt711_add_codec_device_props(const char *sdw_dev_name) return ret; } +static int remove_properties(struct bus_type *bus, const char *codec_name) +{ + struct device *dev; + + dev = bus_find_device_by_name(bus, NULL, codec_name); + if (!dev) + return -EINVAL; + + device_remove_properties(dev); + put_device(dev); + + return 0; +} + static const struct snd_soc_dapm_widget rt711_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -135,17 +149,7 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd) int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link) { - struct device *sdw_dev; - - sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, - dai_link->codecs[0].name); - if (!sdw_dev) - return -EINVAL; - - device_remove_properties(sdw_dev); - put_device(sdw_dev); - - return 0; + return remove_properties(&sdw_bus_type, dai_link->codecs[0].name); } int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,