提交 ebe043a3 编写于 作者: C Cezary Rojewski 提交者: Takashi Iwai

ALSA: hda: Fix put_device() inconsistency in error path

AVS HDAudio bus driver does not tie with codec drivers tighly. Codec
device and its respective driver cleanup procedures are split and may
not occur one after the other. Device cleanup is performed only on
snd_hdac_ext_bus_device_remove() i.e. it's the bus driver's
responsibility. If codec component probing fails, put_device() found in
snd_hda_codec_device_new() may lead to page fault. Relocate it to
snd_hda_codec_new() to address the problem on ASoC side while keeping
status quo for snd_hda_intel.
Signed-off-by: NCezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20220706120230.427296-5-cezary.rojewski@intel.comSigned-off-by: NTakashi Iwai <tiwai@suse.de>
上级 9c76958b
...@@ -950,6 +950,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, ...@@ -950,6 +950,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
unsigned int codec_addr, struct hda_codec **codecp) unsigned int codec_addr, struct hda_codec **codecp)
{ {
struct hda_codec *codec; struct hda_codec *codec;
int ret;
codec = snd_hda_codec_device_init(bus, codec_addr, "hdaudioC%dD%d", codec = snd_hda_codec_device_init(bus, codec_addr, "hdaudioC%dD%d",
card->number, codec_addr); card->number, codec_addr);
...@@ -957,7 +958,11 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, ...@@ -957,7 +958,11 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
return PTR_ERR(codec); return PTR_ERR(codec);
*codecp = codec; *codecp = codec;
return snd_hda_codec_device_new(bus, card, codec_addr, *codecp, true); ret = snd_hda_codec_device_new(bus, card, codec_addr, *codecp, true);
if (ret)
put_device(hda_codec_dev(*codecp));
return ret;
} }
EXPORT_SYMBOL_GPL(snd_hda_codec_new); EXPORT_SYMBOL_GPL(snd_hda_codec_new);
...@@ -1012,19 +1017,17 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, ...@@ -1012,19 +1017,17 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
if (codec->bus->modelname) { if (codec->bus->modelname) {
codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
if (!codec->modelname) { if (!codec->modelname)
err = -ENOMEM; return -ENOMEM;
goto error;
}
} }
fg = codec->core.afg ? codec->core.afg : codec->core.mfg; fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
err = read_widget_caps(codec, fg); err = read_widget_caps(codec, fg);
if (err < 0) if (err < 0)
goto error; return err;
err = read_pin_defaults(codec); err = read_pin_defaults(codec);
if (err < 0) if (err < 0)
goto error; return err;
/* power-up all before initialization */ /* power-up all before initialization */
hda_set_power_state(codec, AC_PWRST_D0); hda_set_power_state(codec, AC_PWRST_D0);
...@@ -1042,7 +1045,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, ...@@ -1042,7 +1045,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
/* ASoC features component management instead */ /* ASoC features component management instead */
err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops); err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops);
if (err < 0) if (err < 0)
goto error; return err;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1055,10 +1058,6 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, ...@@ -1055,10 +1058,6 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
#endif #endif
return 0; return 0;
error:
put_device(hda_codec_dev(codec));
return err;
} }
EXPORT_SYMBOL_GPL(snd_hda_codec_device_new); EXPORT_SYMBOL_GPL(snd_hda_codec_device_new);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册