Skip to content

Commit 2c63bea

Browse files
kv2019ibroonie
authored andcommitted
ASoC: SOF: Intel: fix HDA codec driver probe with multiple controllers
In case system has multiple HDA controllers, it can happen that same HDA codec driver is used for codecs of multiple controllers. In this case, SOF may fail to probe the HDA driver and SOF initialization fails. SOF HDA code currently relies that a call to request_module() will also run device matching logic to attach driver to the codec instance. However if driver for another HDA controller was already loaded and it already loaded the HDA codec driver, this breaks current logic in SOF. In this case the request_module() SOF does becomes a no-op and HDA Codec driver is not attached to the codec instance sitting on the HDA bus SOF is controlling. Typical scenario would be a system with both external and internal GPUs, with driver of the external GPU loaded first. Fix this by adding similar logic as is used in legacy HDA driver where an explicit device_attach() call is done after request_module(). Also add logic to propagate errors reported by device_attach() back to caller. This also works in the case where drivers are not built as modules. Signed-off-by: Kai Vehmanen <[email protected]> Signed-off-by: Pierre-Louis Bossart <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent ceca219 commit 2c63bea

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

sound/soc/sof/intel/hda-codec.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,18 @@
2424
#define IDISP_VID_INTEL 0x80860000
2525

2626
/* load the legacy HDA codec driver */
27-
#ifdef MODULE
28-
static void hda_codec_load_module(struct hda_codec *codec)
27+
static int hda_codec_load_module(struct hda_codec *codec)
2928
{
29+
#ifdef MODULE
3030
char alias[MODULE_NAME_LEN];
3131
const char *module = alias;
3232

3333
snd_hdac_codec_modalias(&codec->core, alias, sizeof(alias));
3434
dev_dbg(&codec->core.dev, "loading codec module: %s\n", module);
3535
request_module(module);
36-
}
37-
#else
38-
static void hda_codec_load_module(struct hda_codec *codec) {}
3936
#endif
37+
return device_attach(hda_codec_dev(codec));
38+
}
4039

4140
/* enable controller wake up event for all codecs with jack connectors */
4241
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
@@ -129,10 +128,16 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
129128
if ((mach_params && mach_params->common_hdmi_codec_drv) ||
130129
(resp & 0xFFFF0000) != IDISP_VID_INTEL) {
131130
hdev->type = HDA_DEV_LEGACY;
132-
hda_codec_load_module(&hda_priv->codec);
131+
ret = hda_codec_load_module(&hda_priv->codec);
132+
/*
133+
* handle ret==0 (no driver bound) as an error, but pass
134+
* other return codes without modification
135+
*/
136+
if (ret == 0)
137+
ret = -ENOENT;
133138
}
134139

135-
return 0;
140+
return ret;
136141
#else
137142
hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
138143
if (!hdev)

0 commit comments

Comments
 (0)