0011-surface-shutdown.patch 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. From 6ab472fbfe2677b038998f6482da35a7daf3c14d Mon Sep 17 00:00:00 2001
  2. From: Maximilian Luz <luzmaximilian@gmail.com>
  3. Date: Sun, 19 Feb 2023 22:12:24 +0100
  4. Subject: [PATCH] PCI: Add quirk to prevent calling shutdown mehtod
  5. Work around buggy EFI firmware: On some Microsoft Surface devices
  6. (Surface Pro 9 and Surface Laptop 5) the EFI ResetSystem call with
  7. EFI_RESET_SHUTDOWN doesn't function properly. Instead of shutting the
  8. system down, it returns and the system stays on.
  9. It turns out that this only happens after PCI shutdown callbacks ran for
  10. specific devices. Excluding those devices from the shutdown process
  11. makes the ResetSystem call work as expected.
  12. TODO: Maybe we can find a better way or the root cause of this?
  13. Not-Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
  14. Patchset: surface-shutdown
  15. ---
  16. drivers/pci/pci-driver.c | 3 +++
  17. drivers/pci/quirks.c | 36 ++++++++++++++++++++++++++++++++++++
  18. include/linux/pci.h | 1 +
  19. 3 files changed, 40 insertions(+)
  20. diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
  21. index af2996d0d17f..3ce0fb61257d 100644
  22. --- a/drivers/pci/pci-driver.c
  23. +++ b/drivers/pci/pci-driver.c
  24. @@ -505,6 +505,9 @@ static void pci_device_shutdown(struct device *dev)
  25. struct pci_dev *pci_dev = to_pci_dev(dev);
  26. struct pci_driver *drv = pci_dev->driver;
  27. + if (pci_dev->no_shutdown)
  28. + return;
  29. +
  30. pm_runtime_resume(dev);
  31. if (drv && drv->shutdown)
  32. diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
  33. index eff7f5df08e2..d1cb4ff3ebc5 100644
  34. --- a/drivers/pci/quirks.c
  35. +++ b/drivers/pci/quirks.c
  36. @@ -6253,3 +6253,39 @@ static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev)
  37. pdev->d3cold_delay = 1000;
  38. }
  39. DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec);
  40. +
  41. +static const struct dmi_system_id no_shutdown_dmi_table[] = {
  42. + /*
  43. + * Systems on which some devices should not be touched during shutdown.
  44. + */
  45. + {
  46. + .ident = "Microsoft Surface Pro 9",
  47. + .matches = {
  48. + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  49. + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Pro 9"),
  50. + },
  51. + },
  52. + {
  53. + .ident = "Microsoft Surface Laptop 5",
  54. + .matches = {
  55. + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  56. + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 5"),
  57. + },
  58. + },
  59. + {}
  60. +};
  61. +
  62. +static void quirk_no_shutdown(struct pci_dev *dev)
  63. +{
  64. + if (!dmi_check_system(no_shutdown_dmi_table))
  65. + return;
  66. +
  67. + dev->no_shutdown = 1;
  68. + pci_info(dev, "disabling shutdown ops for [%04x:%04x]\n",
  69. + dev->vendor, dev->device);
  70. +}
  71. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461e, quirk_no_shutdown); // Thunderbolt 4 USB Controller
  72. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port
  73. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x462f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port
  74. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x466d, quirk_no_shutdown); // Thunderbolt 4 NHI
  75. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x46a8, quirk_no_shutdown); // GPU
  76. diff --git a/include/linux/pci.h b/include/linux/pci.h
  77. index 6f9c5ed5eb3b..01ec9872f2bc 100644
  78. --- a/include/linux/pci.h
  79. +++ b/include/linux/pci.h
  80. @@ -465,6 +465,7 @@ struct pci_dev {
  81. unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */
  82. unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */
  83. unsigned int rom_attr_enabled:1; /* Display of ROM attribute enabled? */
  84. + unsigned int no_shutdown:1; /* Do not touch device on shutdown */
  85. pci_dev_flags_t dev_flags;
  86. atomic_t enable_cnt; /* pci_enable_device has been called */
  87. --
  88. 2.45.2