12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- From 1b70d0b363bf61ae919369e35599fdcc4bee85c1 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Sun, 19 Feb 2023 22:12:24 +0100
- Subject: [PATCH] PCI: Add quirk to prevent calling shutdown mehtod
- Work around buggy EFI firmware: On some Microsoft Surface devices
- (Surface Pro 9 and Surface Laptop 5) the EFI ResetSystem call with
- EFI_RESET_SHUTDOWN doesn't function properly. Instead of shutting the
- system down, it returns and the system stays on.
- It turns out that this only happens after PCI shutdown callbacks ran for
- specific devices. Excluding those devices from the shutdown process
- makes the ResetSystem call work as expected.
- TODO: Maybe we can find a better way or the root cause of this?
- Not-Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Patchset: surface-shutdown
- ---
- drivers/pci/pci-driver.c | 3 +++
- drivers/pci/quirks.c | 36 ++++++++++++++++++++++++++++++++++++
- include/linux/pci.h | 1 +
- 3 files changed, 40 insertions(+)
- diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
- index ae9baf801681..fdfaec2312a0 100644
- --- a/drivers/pci/pci-driver.c
- +++ b/drivers/pci/pci-driver.c
- @@ -507,6 +507,9 @@ static void pci_device_shutdown(struct device *dev)
- struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
-
- + if (pci_dev->no_shutdown)
- + return;
- +
- pm_runtime_resume(dev);
-
- if (drv && drv->shutdown)
- diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
- index c525867760bf..b67d9181a608 100644
- --- a/drivers/pci/quirks.c
- +++ b/drivers/pci/quirks.c
- @@ -6041,3 +6041,39 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
- #endif
- +
- +static const struct dmi_system_id no_shutdown_dmi_table[] = {
- + /*
- + * Systems on which some devices should not be touched during shutdown.
- + */
- + {
- + .ident = "Microsoft Surface Pro 9",
- + .matches = {
- + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
- + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Pro 9"),
- + },
- + },
- + {
- + .ident = "Microsoft Surface Laptop 5",
- + .matches = {
- + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
- + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 5"),
- + },
- + },
- + {}
- +};
- +
- +static void quirk_no_shutdown(struct pci_dev *dev)
- +{
- + if (!dmi_check_system(no_shutdown_dmi_table))
- + return;
- +
- + dev->no_shutdown = 1;
- + pci_info(dev, "disabling shutdown ops for [%04x:%04x]\n",
- + dev->vendor, dev->device);
- +}
- +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461e, quirk_no_shutdown); // Thunderbolt 4 USB Controller
- +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port
- +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x462f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port
- +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x466d, quirk_no_shutdown); // Thunderbolt 4 NHI
- +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x46a8, quirk_no_shutdown); // GPU
- diff --git a/include/linux/pci.h b/include/linux/pci.h
- index c69a2cc1f412..a23262cfc9b7 100644
- --- a/include/linux/pci.h
- +++ b/include/linux/pci.h
- @@ -464,6 +464,7 @@ struct pci_dev {
- unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */
- unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */
- unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */
- + unsigned int no_shutdown:1; /* Do not touch device on shutdown */
- pci_dev_flags_t dev_flags;
- atomic_t enable_cnt; /* pci_enable_device has been called */
-
- --
- 2.41.0
|