From 691be973c0621255abb31572a98e35c57be70212 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Mar 2016 15:10:08 +0100 Subject: [PATCH 1/6] ALSA: hda - Really restrict i915 notifier to HSW+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit [b62232d429fa: ALSA: hda - Limit i915 HDMI binding only for HSW and later] tried to limit the usage of i915 audio notifier to the recent Intel models and switch to the old method on pre-Haswell models. However, it assumed that the i915 component binding hasn't been done on such models, and the assumption was wrong: namely, Baytrail had already the i915 component binding due to powerwell control. Thus, the workaround wasn't applied to Baytrail. For fixing this properly, this patch introduces a new flag indicating the usage of audio notifier and codec_has_acomp() refers to this flag instead of checking the existence of audio component. Reported-by: Ville Syrjälä Cc: # v4.5 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 49ee4e55dd16..8cdb804aa9cf 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -152,6 +152,7 @@ struct hdmi_spec { struct hda_pcm_stream pcm_playback; /* i915/powerwell (Haswell+/Valleyview+) specific */ + bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */ struct i915_audio_component_audio_ops i915_audio_ops; bool i915_bound; /* was i915 bound in this driver? */ @@ -159,8 +160,11 @@ struct hdmi_spec { }; #ifdef CONFIG_SND_HDA_I915 -#define codec_has_acomp(codec) \ - ((codec)->bus->core.audio_component != NULL) +static inline bool codec_has_acomp(struct hda_codec *codec) +{ + struct hdmi_spec *spec = codec->spec; + return spec->use_acomp_notifier; +} #else #define codec_has_acomp(codec) false #endif @@ -2248,12 +2252,18 @@ static int patch_generic_hdmi(struct hda_codec *codec) codec->spec = spec; hdmi_array_init(spec, 4); +#ifdef CONFIG_SND_HDA_I915 /* Try to bind with i915 for Intel HSW+ codecs (if not done yet) */ - if (!codec_has_acomp(codec) && - (codec->core.vendor_id >> 16) == 0x8086 && - is_haswell_plus(codec)) - if (!snd_hdac_i915_init(&codec->bus->core)) - spec->i915_bound = true; + if ((codec->core.vendor_id >> 16) == 0x8086 && + is_haswell_plus(codec)) { + if (!codec->bus->core.audio_component) + if (!snd_hdac_i915_init(&codec->bus->core)) + spec->i915_bound = true; + /* use i915 audio component notifier for hotplug */ + if (codec->bus->core.audio_component) + spec->use_acomp_notifier = true; + } +#endif if (is_haswell_plus(codec)) { intel_haswell_enable_all_pins(codec, true); From bd48128539ab89986b24ad08ecd3e027dd1993a1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Mar 2016 18:01:53 +0100 Subject: [PATCH 2/6] ALSA: hda - Fix forgotten HDMI monitor_present update We forgot to copy monitor_present value when updating the ELD information. This won't change the ELD retrieval and the jack notification behavior, but appears only in the proc output. In that sense, it's no fatal error, but a bug is a bug is a bug. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8cdb804aa9cf..e7d9453ecd10 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1358,6 +1358,7 @@ static void update_eld(struct hda_codec *codec, eld->eld_size) != 0) eld_changed = true; + pin_eld->monitor_present = eld->monitor_present; pin_eld->eld_valid = eld->eld_valid; pin_eld->eld_size = eld->eld_size; if (eld->eld_valid) From 93a9ff151754fbdf951b1b993bcf96453f6e36b3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Mar 2016 19:45:13 +0100 Subject: [PATCH 3/6] ALSA: hda - Fix spurious kernel WARNING on Baytrail HDMI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit snd_hdac_sync_audio_rate() call is mandatory only for HSW and later models, but we call the function unconditionally blindly assuming that the function doesn't do anything harmful. But since recently, the function checks the validity of the passed pin NID, and eventually spews the warning if an unexpected pin is passed. This is seen on old chips like Baytrail. The fix is to limit the call of this function again only for the chips with the proper binding. This can be identified by the same flag as the eld notifier. Reported-by: Ville Syrjälä Tested-by: Ville Syrjälä Cc: # v4.5 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e7d9453ecd10..56d3575ee6cc 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1741,7 +1741,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ /* Todo: add DP1.2 MST audio support later */ - snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate); + if (codec_has_acomp(codec)) + snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate); non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); mutex_lock(&per_pin->lock); From 7169701ad3f9fadd7413b354ae317e67c0b37389 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 19 Mar 2016 10:40:21 +0100 Subject: [PATCH 4/6] ALSA: hda - Workaround for unbalanced i915 power refcount by concurrent probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent addition of on-demand i915 audio component binding in the codec driver seems leading to the unbalanced i915 power refcount, according to Intel CI tests. Typically, it gets a kernel WARNING like: WARNING: CPU: 3 PID: 173 at sound/hda/hdac_i915.c:91 snd_hdac_display_power+0xf1/0x110 [snd_hda_core]() Call Trace: [] dump_stack+0x67/0x92 [] warn_slowpath_common+0x81/0xc0 [] warn_slowpath_null+0x15/0x20 [] snd_hdac_display_power+0xf1/0x110 [snd_hda_core] [] azx_intel_link_power+0xd/0x10 [snd_hda_intel] [] azx_link_power+0x1a/0x30 [snd_hda_codec] [] snd_hdac_link_power+0x29/0x40 [snd_hda_core] [] hda_codec_runtime_suspend+0x76/0xa0 [snd_hda_codec] ..... The scenario is like below: - HD-audio driver and i915 driver are probed concurrently at the (almost) same time; HDA bus tries to bind with i915, but it fails because i915 initialization is still being processed. - Later on, HD-audio probes the HDMI codec, where it again tries to bind with i915. At this time, it succeeds. - At finishing the probe of HDA, it decreases the refcount as if it were already bound at the bus probe, since the component is bound now. This triggers a kernel WARNING due to the unbalance. As a workaround, in this patch, we just disable the on-demand i915 component binding in the codec driver. This essentially reverts back to the state of 4.4 kernel. We know that this is no real solution, but it's a minimalistic simple change that can be applied to 4.5.x kernel as stable. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94566 Reported-by: Ville Syrjälä Cc: # v4.5 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 56d3575ee6cc..7ae614d27954 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2258,9 +2258,15 @@ static int patch_generic_hdmi(struct hda_codec *codec) /* Try to bind with i915 for Intel HSW+ codecs (if not done yet) */ if ((codec->core.vendor_id >> 16) == 0x8086 && is_haswell_plus(codec)) { +#if 0 + /* on-demand binding leads to an unbalanced refcount when + * both i915 and hda drivers are probed concurrently; + * disabled temporarily for now + */ if (!codec->bus->core.audio_component) if (!snd_hdac_i915_init(&codec->bus->core)) spec->i915_bound = true; +#endif /* use i915 audio component notifier for hotplug */ if (codec->bus->core.audio_component) spec->use_acomp_notifier = true; From 0ef21100ae912f76ed89f76ecd894f4ffb3689c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Cl=C3=A9ment?= Date: Sat, 19 Mar 2016 13:17:42 +0100 Subject: [PATCH 5/6] ALSA: usb-audio: add Microsoft HD-5001 to quirks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Microsoft HD-5001 webcam microphone does not support sample rate reading as the HD-5000 one. This results in dmesg errors and sound hanging with pulseaudio. Signed-off-by: Victor Clément Cc: Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a889d433cbdf..fb62bce2435c 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1126,6 +1126,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) switch (chip->usb_id) { case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */ case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */ + case USB_ID(0x045E, 0x076E): /* MS Lifecam HD-5001 */ case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ From c64c1437afb14ebc900e40910f31ffb20bf652ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 21 Mar 2016 16:07:30 +0100 Subject: [PATCH 6/6] ALSA: hda - Fix missing ELD update at unplugging i915 get_eld ops may return an error when no encoder is connected, and currently we regard the error as fatal and skip the whole ELD handling. This ended up with the missing ELD update at unplugging. This patch fixes the issue by treating the error as the unplugged state, instead of skipping the rest. Reported-by: Libin Yang Cc: # v4.5 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 7ae614d27954..5af372d01834 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1484,11 +1484,10 @@ static void sync_eld_via_acomp(struct hda_codec *codec, int size; mutex_lock(&per_pin->lock); + eld->monitor_present = false; size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid, &eld->monitor_present, eld->eld_buffer, ELD_MAX_SIZE); - if (size < 0) - goto unlock; if (size > 0) { size = min(size, ELD_MAX_SIZE); if (snd_hdmi_parse_eld(codec, &eld->info,