daac927ae7
Derived from latest 6.7 patches
Links:
- kernel: 34ad5b493b
- tree-devel: https://github.com/linux-surface/kernel/tree/v6.8-surface-devel
- tree-patches: https://github.com/linux-surface/kernel/tree/v6.8-surface
98 lines
3.5 KiB
Diff
98 lines
3.5 KiB
Diff
From aa49dc59b192cc038ca789ac70215d7492f043cb 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 51ec9e7e784f..40554890d721 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 d797df6e5f3e..c674ee496a0b 100644
|
|
--- a/drivers/pci/quirks.c
|
|
+++ b/drivers/pci/quirks.c
|
|
@@ -6250,3 +6250,39 @@ static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev)
|
|
pdev->d3cold_delay = 1000;
|
|
}
|
|
DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec);
|
|
+
|
|
+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 7ab0d13672da..8d8d9225e0db 100644
|
|
--- a/include/linux/pci.h
|
|
+++ b/include/linux/pci.h
|
|
@@ -465,6 +465,7 @@ struct pci_dev {
|
|
unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */
|
|
unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */
|
|
unsigned int rom_attr_enabled:1; /* Display of ROM attribute enabled? */
|
|
+ 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.44.0
|
|
|