Fix regression in how intel_haswell_fixup_connect_list() results are used in hda_read_pin_conn(). Use of snd_hda_get_raw_connections() in hda_read_pin_conn() bypasses the cache and thus also bypasses the overridden pin connection list. On platforms that require the connection list fixup, mux list will be empty and HDMI playback will fail to -EBUSY at open.
Move intel_haswell_fixup_connect_list() call to hda_read_pin_conn() as it's not used elsewhere.
Fixes: 9c32fea83692 ("ALSA: hda - Add DP-MST support for non-acomp codecs") BugLink: https://github.com/thesofproject/linux/issues/1537 Cc: Nikhil Mahale nmahale@nvidia.com Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/pci/hda/patch_hdmi.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 55d20e40a195..c111bdd566c9 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1293,6 +1293,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, return err; }
+static void intel_haswell_fixup_connect_list(struct hda_codec *codec, + hda_nid_t nid); + /* * HDA/HDMI auto parsing */ @@ -1302,6 +1305,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); hda_nid_t pin_nid = per_pin->pin_nid; int dev_id = per_pin->dev_id; + int conns;
if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { codec_warn(codec, @@ -1312,10 +1316,19 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
snd_hda_set_dev_select(codec, pin_nid, dev_id);
+ if (spec->intel_hsw_fixup) { + intel_haswell_fixup_connect_list(codec, pin_nid); + conns = snd_hda_get_connections(codec, pin_nid, + per_pin->mux_nids, + HDA_MAX_CONNECTIONS); + } else { + conns = snd_hda_get_raw_connections(codec, pin_nid, + per_pin->mux_nids, + HDA_MAX_CONNECTIONS); + } + /* all the device entries on the same pin have the same conn list */ - per_pin->num_mux_nids = - snd_hda_get_raw_connections(codec, pin_nid, per_pin->mux_nids, - HDA_MAX_CONNECTIONS); + per_pin->num_mux_nids = conns;
return 0; } @@ -1713,9 +1726,6 @@ static void hdmi_repoll_eld(struct work_struct *work) mutex_unlock(&spec->pcm_lock); }
-static void intel_haswell_fixup_connect_list(struct hda_codec *codec, - hda_nid_t nid); - static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct hdmi_spec *spec = codec->spec; @@ -1790,8 +1800,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) per_pin->dev_id = i; per_pin->non_pcm = false; snd_hda_set_dev_select(codec, pin_nid, i); - if (spec->intel_hsw_fixup) - intel_haswell_fixup_connect_list(codec, pin_nid); err = hdmi_read_pin_conn(codec, pin_idx); if (err < 0) return err;