Skip to content

Commit af37494

Browse files
Linus Walleijgregkh
authored andcommitted
ASoC: dapm: handle probe deferrals
[ Upstream commit 37e1df8c95e2c8a57c77eafc097648f6e40a60ff ] This starts to handle probe deferrals on regulators and clocks on the ASoC DAPM. I came to this patch after audio stopped working on Ux500 ages ago and I finally looked into it to see what is wrong. I had messages like this in the console since a while back: ab8500-codec.0: ASoC: Failed to request audioclk: -517 ab8500-codec.0: ASoC: Failed to create DAPM control audioclk ab8500-codec.0: Failed to create new controls -12 snd-soc-mop500.0: ASoC: failed to instantiate card -12 snd-soc-mop500.0: Error: snd_soc_register_card failed (-12)! snd-soc-mop500: probe of snd-soc-mop500.0 failed with error -12 Apparently because the widget table for the codec looks like this (sound/soc/codecs/ab8500-codec.c): static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { /* Clocks */ SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), /* Regulators */ SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0), SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0), SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0), SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0), So when we call snd_soc_register_codec() and any of these widgets get a deferred probe we do not get an -EPROBE_DEFER (-517) back as we should and instead we just fail. Apparently the code assumes that clocks and regulators must be available at this point and not defer. After this patch it rather looks like this: ab8500-codec.0: Failed to create new controls -517 snd-soc-mop500.0: ASoC: failed to instantiate card -517 snd-soc-mop500.0: Error: snd_soc_register_card failed (-517)! (...) abx500-clk.0: registered clocks for ab850x snd-soc-mop500.0: ab8500-codec-dai.0 <-> ux500-msp-i2s.1 mapping ok snd-soc-mop500.0: ab8500-codec-dai.1 <-> ux500-msp-i2s.3 mapping ok I'm pretty happy about the patch as it it, but I'm a bit uncertain on how to proceed: there are a lot of users of the external functions snd_soc_dapm_new_control() (111 sites) and that will now return an occassional error pointer, which is not handled in the calling sites. I want an indication from the maintainers whether I should just go in and augment all these call sites, or if deferred probe is frowned upon when it leads to this much overhead. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e8c3d4 commit af37494

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

sound/soc/soc-dapm.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
358358
snd_soc_dapm_new_control_unlocked(widget->dapm,
359359
&template);
360360
kfree(name);
361+
if (IS_ERR(data->widget)) {
362+
ret = PTR_ERR(data->widget);
363+
goto err_data;
364+
}
361365
if (!data->widget) {
362366
ret = -ENOMEM;
363367
goto err_data;
@@ -392,6 +396,10 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
392396
data->widget = snd_soc_dapm_new_control_unlocked(
393397
widget->dapm, &template);
394398
kfree(name);
399+
if (IS_ERR(data->widget)) {
400+
ret = PTR_ERR(data->widget);
401+
goto err_data;
402+
}
395403
if (!data->widget) {
396404
ret = -ENOMEM;
397405
goto err_data;
@@ -3278,11 +3286,22 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
32783286

32793287
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
32803288
w = snd_soc_dapm_new_control_unlocked(dapm, widget);
3289+
/* Do not nag about probe deferrals */
3290+
if (IS_ERR(w)) {
3291+
int ret = PTR_ERR(w);
3292+
3293+
if (ret != -EPROBE_DEFER)
3294+
dev_err(dapm->dev,
3295+
"ASoC: Failed to create DAPM control %s (%d)\n",
3296+
widget->name, ret);
3297+
goto out_unlock;
3298+
}
32813299
if (!w)
32823300
dev_err(dapm->dev,
32833301
"ASoC: Failed to create DAPM control %s\n",
32843302
widget->name);
32853303

3304+
out_unlock:
32863305
mutex_unlock(&dapm->card->dapm_mutex);
32873306
return w;
32883307
}
@@ -3304,6 +3323,8 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
33043323
w->regulator = devm_regulator_get(dapm->dev, w->name);
33053324
if (IS_ERR(w->regulator)) {
33063325
ret = PTR_ERR(w->regulator);
3326+
if (ret == -EPROBE_DEFER)
3327+
return ERR_PTR(ret);
33073328
dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
33083329
w->name, ret);
33093330
return NULL;
@@ -3322,6 +3343,8 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
33223343
w->clk = devm_clk_get(dapm->dev, w->name);
33233344
if (IS_ERR(w->clk)) {
33243345
ret = PTR_ERR(w->clk);
3346+
if (ret == -EPROBE_DEFER)
3347+
return ERR_PTR(ret);
33253348
dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
33263349
w->name, ret);
33273350
return NULL;
@@ -3435,6 +3458,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
34353458
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
34363459
for (i = 0; i < num; i++) {
34373460
w = snd_soc_dapm_new_control_unlocked(dapm, widget);
3461+
if (IS_ERR(w)) {
3462+
ret = PTR_ERR(w);
3463+
/* Do not nag about probe deferrals */
3464+
if (ret == -EPROBE_DEFER)
3465+
break;
3466+
dev_err(dapm->dev,
3467+
"ASoC: Failed to create DAPM control %s (%d)\n",
3468+
widget->name, ret);
3469+
break;
3470+
}
34383471
if (!w) {
34393472
dev_err(dapm->dev,
34403473
"ASoC: Failed to create DAPM control %s\n",
@@ -3701,6 +3734,15 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
37013734
dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
37023735

37033736
w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
3737+
if (IS_ERR(w)) {
3738+
ret = PTR_ERR(w);
3739+
/* Do not nag about probe deferrals */
3740+
if (ret != -EPROBE_DEFER)
3741+
dev_err(card->dev,
3742+
"ASoC: Failed to create %s widget (%d)\n",
3743+
link_name, ret);
3744+
goto outfree_kcontrol_news;
3745+
}
37043746
if (!w) {
37053747
dev_err(card->dev, "ASoC: Failed to create %s widget\n",
37063748
link_name);

sound/soc/soc-topology.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,15 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
14811481
widget = snd_soc_dapm_new_control(dapm, &template);
14821482
else
14831483
widget = snd_soc_dapm_new_control_unlocked(dapm, &template);
1484+
if (IS_ERR(widget)) {
1485+
ret = PTR_ERR(widget);
1486+
/* Do not nag about probe deferrals */
1487+
if (ret != -EPROBE_DEFER)
1488+
dev_err(tplg->dev,
1489+
"ASoC: failed to create widget %s controls (%d)\n",
1490+
w->name, ret);
1491+
goto hdr_err;
1492+
}
14841493
if (widget == NULL) {
14851494
dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n",
14861495
w->name);

0 commit comments

Comments
 (0)