]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI/ASPM: Add pcie_aspm_remove_cap() to override advertised link states
authorBjorn Helgaas <bhelgaas@google.com>
Mon, 10 Nov 2025 22:22:26 +0000 (16:22 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 13 Nov 2025 00:51:27 +0000 (18:51 -0600)
Add pcie_aspm_remove_cap().  A quirk can use this to prevent use of ASPM
L0s or L1 link states, even if the device advertised support for them.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Link: https://patch.msgid.link/20251110222929.2140564-3-helgaas@kernel.org
drivers/pci/pci.h
drivers/pci/pcie/aspm.c

index 4492b809094b5794bd94dfbc20102cb208c3fa2f..36f8c0985430a4aad259859abb2d5ce0b4da8555 100644 (file)
@@ -958,6 +958,7 @@ void pci_save_aspm_l1ss_state(struct pci_dev *dev);
 void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
 
 #ifdef CONFIG_PCIEASPM
+void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap);
 void pcie_aspm_init_link_state(struct pci_dev *pdev);
 void pcie_aspm_exit_link_state(struct pci_dev *pdev);
 void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked);
@@ -965,6 +966,7 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
 void pci_configure_ltr(struct pci_dev *pdev);
 void pci_bridge_reconfigure_ltr(struct pci_dev *pdev);
 #else
+static inline void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap) { }
 static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
 static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
 static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev, bool locked) { }
index 15d50c089070377b52b77a4bbd13b1bdf16addd1..f61d98897503704e7b22209f434756866974e365 100644 (file)
@@ -1542,6 +1542,19 @@ int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
 }
 EXPORT_SYMBOL(pci_enable_link_state_locked);
 
+void pcie_aspm_remove_cap(struct pci_dev *pdev, u32 lnkcap)
+{
+       if (lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
+               pdev->aspm_l0s_support = 0;
+       if (lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
+               pdev->aspm_l1_support = 0;
+
+       pci_info(pdev, "ASPM: Link Capabilities%s%s treated as unsupported to avoid device defect\n",
+                lnkcap & PCI_EXP_LNKCAP_ASPM_L0S ? " L0s" : "",
+                lnkcap & PCI_EXP_LNKCAP_ASPM_L1 ? " L1" : "");
+
+}
+
 static int pcie_aspm_set_policy(const char *val,
                                const struct kernel_param *kp)
 {