aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiong Zhang <xiong.y.zhang@intel.com>2015-12-18 00:29:18 -0500
committerTakashi Iwai <tiwai@suse.de>2015-12-18 03:49:13 -0500
commit3e6db33aaf1d42a30339f831ec4850570d6cc7a3 (patch)
tree37981c7b9042afc5e5bc9ad79b092bc4daa215fb
parentb6903c0ed9f0bcbbe88f67f7ed43d1721cbc6235 (diff)
ALSA: hda - Set SKL+ hda controller power at freeze() and thaw()
It takes three minutes to enter into hibernation on some OEM SKL machines and we see many codec spurious response after thaw() opertion. This is because HDA is still in D0 state after freeze() call and pci_pm_freeze/pci_pm_freeze_noirq() don't set D3 hot in pci_bus driver. It seems bios still access HDA when system enter into freeze state, HDA will receive codec response interrupt immediately after thaw() call. Because of this unexpected interrupt, HDA enter into a abnormal state and slow down the system enter into hibernation. In this patch, we put HDA into D3 hot state in azx_freeze_noirq() and put HDA into D0 state in azx_thaw_noirq(). V2: Only apply this fix to SKL+ Fix compile error when CONFIG_PM_SLEEP isn't defined [Yet another fix for CONFIG_PM_SLEEP ifdef and the additional comment by tiwai] Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_intel.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bff5c8b329d1..3b3658297070 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -954,6 +954,36 @@ static int azx_resume(struct device *dev)
954} 954}
955#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */ 955#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
956 956
957#ifdef CONFIG_PM_SLEEP
958/* put codec down to D3 at hibernation for Intel SKL+;
959 * otherwise BIOS may still access the codec and screw up the driver
960 */
961#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
962#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
963#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
964#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
965
966static int azx_freeze_noirq(struct device *dev)
967{
968 struct pci_dev *pci = to_pci_dev(dev);
969
970 if (IS_SKL_PLUS(pci))
971 pci_set_power_state(pci, PCI_D3hot);
972
973 return 0;
974}
975
976static int azx_thaw_noirq(struct device *dev)
977{
978 struct pci_dev *pci = to_pci_dev(dev);
979
980 if (IS_SKL_PLUS(pci))
981 pci_set_power_state(pci, PCI_D0);
982
983 return 0;
984}
985#endif /* CONFIG_PM_SLEEP */
986
957#ifdef CONFIG_PM 987#ifdef CONFIG_PM
958static int azx_runtime_suspend(struct device *dev) 988static int azx_runtime_suspend(struct device *dev)
959{ 989{
@@ -1063,6 +1093,10 @@ static int azx_runtime_idle(struct device *dev)
1063 1093
1064static const struct dev_pm_ops azx_pm = { 1094static const struct dev_pm_ops azx_pm = {
1065 SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume) 1095 SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
1096#ifdef CONFIG_PM_SLEEP
1097 .freeze_noirq = azx_freeze_noirq,
1098 .thaw_noirq = azx_thaw_noirq,
1099#endif
1066 SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle) 1100 SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
1067}; 1101};
1068 1102