Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions sound/soc/intel/boards/bytcht_es8316.c
Original file line number Diff line number Diff line change
Expand Up @@ -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" };
Expand Down Expand Up @@ -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;
}
}

Expand All @@ -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)
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is rather theoretical, but this is a platform driver .return() method. What happens if it returns an error code? rmmod fails and the module remains loaded? Is this what we want?

Copy link
Member Author

@plbossart plbossart Jul 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters, the driver core ignores the remove() return value.

grep --color -nH --null -e 'drv->remove' *.c
dd.c\0541:		else if (drv->remove)
dd.c\0542:			drv->remove(dev);
dd.c\0569:	else if (drv->remove)
dd.c\0570:		drv->remove(dev);
dd.c\01107:		else if (drv->remove)
dd.c\01108:			drv->remove(dev);
driver.c\0159:	    (drv->bus->remove && drv->remove) ||
platform.c\0772:	if (drv->remove)
platform.c\0773:		ret = drv->remove(dev);

}

static struct platform_driver snd_byt_cht_es8316_mc_driver = {
Expand Down
30 changes: 27 additions & 3 deletions sound/soc/intel/boards/bytcr_rt5640.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about sharing this function? Maybe even just making it an inline in a suitable header, or creating a new header for it in this directory.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a header for this, so I left it as an optimization.

{
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" };
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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 = {
Expand All @@ -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);
Expand Down
34 changes: 29 additions & 5 deletions sound/soc/intel/boards/bytcr_rt5651.c
Original file line number Diff line number Diff line change
Expand Up @@ -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" };
Expand Down Expand Up @@ -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,
Expand All @@ -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;
}
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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 = {
Expand All @@ -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);
Expand Down
66 changes: 38 additions & 28 deletions sound/soc/intel/boards/sof_sdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = {
Expand Down
26 changes: 15 additions & 11 deletions sound/soc/intel/boards/sof_sdw_rt711.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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,
Expand Down