diff options
author | Takashi Iwai <tiwai@suse.de> | 2020-07-27 18:44:43 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-07-27 18:45:38 +0200 |
commit | a6630529aecb5a3e84370c376ed658e892e6261e (patch) | |
tree | 7730334474e0b16c765ddb9771c60fb97300fc58 /sound/pci | |
parent | 6fa38ef1534e7e9320aa15e329eb1404ab2f70ac (diff) |
ALSA: hda: Workaround for spurious wakeups on some Intel platforms
We've received a regression report on Intel HD-audio controller that
wakes up immediately after S3 suspend. The bisection leads to the
commit c4c8dd6ef807 ("ALSA: hda: Skip controller resume if not
needed"). This commit replaces the system-suspend to use
pm_runtime_force_suspend() instead of the direct call of
__azx_runtime_suspend(). However, by some really mysterious reason,
pm_runtime_force_suspend() causes a spurious wakeup (although it calls
the same __azx_runtime_suspend() internally).
As an ugly workaround for now, revert the behavior to call
__azx_runtime_suspend() and __azx_runtime_resume() for those old Intel
platforms that may exhibit such a problem, while keeping the new
standard pm_runtime_force_suspend() and pm_runtime_force_resume()
pair for the remaining chips.
Fixes: c4c8dd6ef807 ("ALSA: hda: Skip controller resume if not needed")
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208649
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20200727164443.4233-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_controller.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 17 |
2 files changed, 15 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 82e26442724b..a356fb0e5773 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -41,7 +41,7 @@ /* 24 unused */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ -/* 27 unused */ +#define AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP (1 << 27) /* Workaround for spurious wakeups after suspend */ #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ #define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 11ec5c56c80e..9d14c40c07ea 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -298,7 +298,8 @@ enum { /* PCH for HSW/BDW; with runtime PM */ /* no i915 binding for this as HSW/BDW has another controller for HDMI */ #define AZX_DCAPS_INTEL_PCH \ - (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) + (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ + AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) /* HSW HDMI */ #define AZX_DCAPS_INTEL_HASWELL \ @@ -1028,7 +1029,14 @@ static int azx_suspend(struct device *dev) chip = card->private_data; bus = azx_bus(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - pm_runtime_force_suspend(dev); + /* An ugly workaround: direct call of __azx_runtime_suspend() and + * __azx_runtime_resume() for old Intel platforms that suffer from + * spurious wakeups after S3 suspend + */ + if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) + __azx_runtime_suspend(chip); + else + pm_runtime_force_suspend(dev); if (bus->irq >= 0) { free_irq(bus->irq, chip); bus->irq = -1; @@ -1057,7 +1065,10 @@ static int azx_resume(struct device *dev) if (azx_acquire_irq(chip, 1) < 0) return -EIO; - pm_runtime_force_resume(dev); + if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP) + __azx_runtime_resume(chip, false); + else + pm_runtime_force_resume(dev); snd_power_change_state(card, SNDRV_CTL_POWER_D0); trace_azx_resume(chip); |