]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
PCI/ASPM: Warn when driver asks to disable ASPM, but we can't do it
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 21 May 2013 16:56:51 +0000 (10:56 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 21 May 2013 16:56:51 +0000 (10:56 -0600)
Some devices have hardware problems related to using ASPM.  Drivers for
these devices use pci_disable_link_state() to prevent their device from
entering L0s or L1.  But on platforms where the OS doesn't have permission
to manage ASPM, pci_disable_link_state() doesn't actually disable ASPM.

Windows has a similar mechanism ("PciASPMOptOut"), and when the OS doesn't
have control of ASPM, it doesn't actually disable ASPM either.

This patch just adds a warning in dmesg about the fact that
pci_disable_link_state() is doing nothing.

Reported-by: Emmanuel Grumbach <egrumbach@gmail.com>
Reference: https://lkml.kernel.org/r/CANUX_P3F5YhbZX3WGU-j1AGpbXb_T9Bis2ErhvKkFMtDvzatVQ@mail.gmail.com
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=57331
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pcie/aspm.c

index d320df6375a2c807f8a45a8badc247bf16a956bf..faa83b632a847f97b5cac082e6cf9d16b66ff80b 100644 (file)
@@ -724,9 +724,6 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
        struct pci_dev *parent = pdev->bus->self;
        struct pcie_link_state *link;
 
-       if (aspm_disabled && !force)
-               return;
-
        if (!pci_is_pcie(pdev))
                return;
 
@@ -736,6 +733,19 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
        if (!parent || !parent->link_state)
                return;
 
+       /*
+        * A driver requested that ASPM be disabled on this device, but
+        * if we don't have permission to manage ASPM (e.g., on ACPI
+        * systems we have to observe the FADT ACPI_FADT_NO_ASPM bit and
+        * the _OSC method), we can't honor that request.  Windows has
+        * a similar mechanism using "PciASPMOptOut", which is also
+        * ignored in this situation.
+        */
+       if (aspm_disabled && !force) {
+               dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
+               return;
+       }
+
        if (sem)
                down_read(&pci_bus_sem);
        mutex_lock(&aspm_lock);