Skip to content

Commit a663052

Browse files
committed
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 c4c8dd6 ("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: c4c8dd6 ("ALSA: hda: Skip controller resume if not needed") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208649 Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 6fa38ef commit a663052

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

sound/pci/hda/hda_controller.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
/* 24 unused */
4242
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
4343
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
44-
/* 27 unused */
44+
#define AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP (1 << 27) /* Workaround for spurious wakeups after suspend */
4545
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
4646
#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
4747
#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */

sound/pci/hda/hda_intel.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ enum {
298298
/* PCH for HSW/BDW; with runtime PM */
299299
/* no i915 binding for this as HSW/BDW has another controller for HDMI */
300300
#define AZX_DCAPS_INTEL_PCH \
301-
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
301+
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
302+
AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP)
302303

303304
/* HSW HDMI */
304305
#define AZX_DCAPS_INTEL_HASWELL \
@@ -1028,7 +1029,14 @@ static int azx_suspend(struct device *dev)
10281029
chip = card->private_data;
10291030
bus = azx_bus(chip);
10301031
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1031-
pm_runtime_force_suspend(dev);
1032+
/* An ugly workaround: direct call of __azx_runtime_suspend() and
1033+
* __azx_runtime_resume() for old Intel platforms that suffer from
1034+
* spurious wakeups after S3 suspend
1035+
*/
1036+
if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP)
1037+
__azx_runtime_suspend(chip);
1038+
else
1039+
pm_runtime_force_suspend(dev);
10321040
if (bus->irq >= 0) {
10331041
free_irq(bus->irq, chip);
10341042
bus->irq = -1;
@@ -1057,7 +1065,10 @@ static int azx_resume(struct device *dev)
10571065
if (azx_acquire_irq(chip, 1) < 0)
10581066
return -EIO;
10591067

1060-
pm_runtime_force_resume(dev);
1068+
if (chip->driver_caps & AZX_DCAPS_SUSPEND_SPURIOUS_WAKEUP)
1069+
__azx_runtime_resume(chip, false);
1070+
else
1071+
pm_runtime_force_resume(dev);
10611072
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
10621073

10631074
trace_azx_resume(chip);

0 commit comments

Comments
 (0)