@@ -5702,3 +5702,35 @@ static void pci_fixup_enable_vmd_nvme_ltr(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_EXPRESS, 0, pci_fixup_enable_vmd_nvme_ltr);
+
+static void pci_fixup_serialize_tgl_me_pm(struct pci_dev *pdev)
+{
+ struct pci_dev *rciep = NULL;
+
+ if (!pdev->bus)
+ return;
+
+ for_each_pci_dev(rciep) {
+ /* Most of TGL RCiEPs don't have type PCI_EXP_TYPE_RC_END,
+ * check parent bridge instead. */
+ if (!rciep->bus)
+ continue;
+
+ if (rciep->bus->self != pdev->bus->self)
+ continue;
+
+ if (&rciep->dev == &pdev->dev)
+ continue;
+
+ if (device_link_add(&rciep->dev, &pdev->dev,
+ DL_FLAG_STATELESS))
+ pci_info(rciep, "Suspend before and resume after %s\n",
+ pci_name(pdev));
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fb, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fc, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f9, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15fa, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f4, pci_fixup_serialize_tgl_me_pm);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x15f5, pci_fixup_serialize_tgl_me_pm);
BugLink: https://bugs.launchpad.net/bugs/1919321 On TGL systems, PCI_COMMAND may randomly flip to 0 on system resume. This is devastating to drivers that use pci_set_master(), like NVMe and xHCI, to enable DMA in their resume routine, as pci_set_master() can inadvertently disable PCI_COMMAND_IO and PCI_COMMAND_MEMORY, making resources inaccessible. The issue is reproducible on all kernel releases, but obviously the situation is exacerbated by commit 6cecf02e77ab ('Revert "e1000e: disable s0ix entry and exit flows for ME systems"'). Seems like ME is out to lunch until it's finally out of ULP polling. So ensure e1000e PM ops are serialized by enforcing device links to workaround the issue. This is another hacky hackish hack that we can't upstream :) Of course this will make suspend and resume a bit slower, but at least we protect other PCI devices by keeping ME from going full basket case. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212039 Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> --- drivers/pci/quirks.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)