summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2021-03-10 12:28:08 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-03-17 16:34:31 +0100
commit295954c30e725d50a532a34929b591ec8dd3989a (patch)
tree634f16f4c1a30eaaca04c367adf059a345c0bb96
parent51123fd6324ebd421deb1f6741fb355652cf1426 (diff)
downloadlinux-stable-295954c30e725d50a532a34929b591ec8dd3989a.tar.gz
linux-stable-295954c30e725d50a532a34929b591ec8dd3989a.tar.bz2
linux-stable-295954c30e725d50a532a34929b591ec8dd3989a.zip
ALSA: hda: Avoid spurious unsol event handling during S3/S4
commit 5ff9dde42e8c72ed8102eb8cb62e03f9dc2103ab upstream. When HD-audio bus receives unsolicited events during its system suspend/resume (S3 and S4) phase, the controller driver may still try to process events although the codec chips are already (or yet) powered down. This might screw up the codec communication, resulting in CORB/RIRB errors. Such events should be rather skipped, as the codec chip status such as the jack status will be fully refreshed at the system resume time. Since we're tracking the system suspend/resume state in codec power.power_state field, let's add the check in the common unsol event handler entry point to filter out such events. BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1182377 Tested-by: Abhishek Sahu <abhsahu@nvidia.com> Cc: <stable@vger.kernel.org> # 183ab39eb0ea: ALSA: hda: Initialize power_state Link: https://lore.kernel.org/r/20210310112809.9215-3-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--sound/pci/hda/hda_bind.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index c175b2cf63f7..66010d0774b4 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -46,6 +46,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
if (codec->bus->shutdown)
return;
+ /* ignore unsol events during system suspend/resume */
+ if (codec->core.dev.power.power_state.event != PM_EVENT_ON)
+ return;
+
if (codec->patch_ops.unsol_event)
codec->patch_ops.unsol_event(codec, ev);
}