linux-surface/patches/6.5/0010-surface-shutdown.patch
Maximilian Luz 2cdefec861
Update v6.5 patches
Changes:
 - Add initial SAM/EC support for Surface Laptop 2, including support for
   - Keyboard and other HID devices (sensors, pen stash, but not
     touchpad)
   - Battery information
   - Tablet mode / screen orientation
 - Rebase onto v6.5.12

Links:
 - kernel: df0bd8ffbe
2023-11-20 20:04:24 +01:00

98 lines
3.6 KiB
Diff

From a92ba5b15fc9b3237a87804a78b31e7824c44ce2 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 41ee3dd8cecb8..0bc473c2c1873 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 eb65170b97ff0..4a65456b7df1d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6140,3 +6140,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 c8688d13cc224..3632703a58ff5 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.42.1