|
@@ -954,6 +954,36 @@ static int azx_resume(struct device *dev)
|
|
|
}
|
|
|
#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
|
|
|
|
|
|
+#ifdef CONFIG_PM_SLEEP
|
|
|
+/* put codec down to D3 at hibernation for Intel SKL+;
|
|
|
+ * otherwise BIOS may still access the codec and screw up the driver
|
|
|
+ */
|
|
|
+#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
|
|
|
+#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
|
|
|
+#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
|
|
+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
|
|
|
+
|
|
|
+static int azx_freeze_noirq(struct device *dev)
|
|
|
+{
|
|
|
+ struct pci_dev *pci = to_pci_dev(dev);
|
|
|
+
|
|
|
+ if (IS_SKL_PLUS(pci))
|
|
|
+ pci_set_power_state(pci, PCI_D3hot);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int azx_thaw_noirq(struct device *dev)
|
|
|
+{
|
|
|
+ struct pci_dev *pci = to_pci_dev(dev);
|
|
|
+
|
|
|
+ if (IS_SKL_PLUS(pci))
|
|
|
+ pci_set_power_state(pci, PCI_D0);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif /* CONFIG_PM_SLEEP */
|
|
|
+
|
|
|
#ifdef CONFIG_PM
|
|
|
static int azx_runtime_suspend(struct device *dev)
|
|
|
{
|
|
@@ -1063,6 +1093,10 @@ static int azx_runtime_idle(struct device *dev)
|
|
|
|
|
|
static const struct dev_pm_ops azx_pm = {
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
|
|
|
+#ifdef CONFIG_PM_SLEEP
|
|
|
+ .freeze_noirq = azx_freeze_noirq,
|
|
|
+ .thaw_noirq = azx_thaw_noirq,
|
|
|
+#endif
|
|
|
SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
|
|
|
};
|
|
|
|