Skip to content

Instantly share code, notes, and snippets.

@lattice0
Created June 16, 2018 03:31
Show Gist options
  • Save lattice0/98da46e241a93367a75ba45daba5386b to your computer and use it in GitHub Desktop.
Save lattice0/98da46e241a93367a75ba45daba5386b to your computer and use it in GitHub Desktop.
---
drivers/pci/pcie/aspm.c | 14 ++++++++++----
drivers/pci/quirks.c | 9 ++++++++-
include/linux/pci-aspm.h | 1 +
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 3b9b4d50cd98..9434382d26dc 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1028,7 +1028,7 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
up_read(&pci_bus_sem);
}
-static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
+static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, bool quirk)
{
struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link;
@@ -1049,7 +1049,7 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
* a similar mechanism using "PciASPMOptOut", which is also
* ignored in this situation.
*/
- if (aspm_disabled) {
+ if (aspm_disabled && !quirk) {
dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
return;
}
@@ -1075,7 +1075,7 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
{
- __pci_disable_link_state(pdev, state, false);
+ __pci_disable_link_state(pdev, state, false, false);
}
EXPORT_SYMBOL(pci_disable_link_state_locked);
@@ -1090,10 +1090,16 @@ EXPORT_SYMBOL(pci_disable_link_state_locked);
*/
void pci_disable_link_state(struct pci_dev *pdev, int state)
{
- __pci_disable_link_state(pdev, state, true);
+ __pci_disable_link_state(pdev, state, true, false);
}
EXPORT_SYMBOL(pci_disable_link_state);
+void pci_disable_link_state_quirk(struct pci_dev *pdev, int state)
+{
+ __pci_disable_link_state(pdev, state, true, true);
+}
+EXPORT_SYMBOL(pci_disable_link_state_quirk);
+
static int pcie_aspm_set_policy(const char *val,
const struct kernel_param *kp)
{
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 26b3ed731208..05568d14c210 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2083,7 +2083,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
static void quirk_disable_aspm_l0s(struct pci_dev *dev)
{
dev_info(&dev->dev, "Disabling L0s\n");
- pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
+ pci_disable_link_state_quirk(dev, PCIE_LINK_STATE_L0S);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s);
@@ -2100,6 +2100,13 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
+static void quirk_disable_aspm_l1(struct pci_dev *dev)
+{
+ dev_info(&dev->dev, "Disabling L1\n");
+ pci_disable_link_state_quirk(dev, PCIE_LINK_STATE_L1);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa804, quirk_disable_aspm_l1);
+
static void fixup_rev1_53c810(struct pci_dev *dev)
{
u32 class = dev->class;
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
index df28af5cef21..853d975c82a8 100644
--- a/include/linux/pci-aspm.h
+++ b/include/linux/pci-aspm.h
@@ -25,6 +25,7 @@
#ifdef CONFIG_PCIEASPM
void pci_disable_link_state(struct pci_dev *pdev, int state);
+void pci_disable_link_state_quirk(struct pci_dev *pdev, int state);
void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
void pcie_no_aspm(void);
#else
--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment