Jesse Keating 2f82dda
From: Matthew Garrett <mjg@redhat.com>
Jesse Keating 2f82dda
Subject: ACPI: Disable ASPM if the platform won't provide _OSC control for PCIe
Jesse Keating 2f82dda
Jesse Keating 2f82dda
ACPI: Disable ASPM if the platform won't provide _OSC control for PCIe
Jesse Keating 2f82dda
Jesse Keating 2f82dda
[ backport to 2.6.32 ]
Jesse Keating 2f82dda
Jesse Keating 2f82dda
The PCI SIG documentation for the _OSC OS/firmware handshaking interface
Jesse Keating 2f82dda
states:
Jesse Keating 2f82dda
Jesse Keating 2f82dda
"If the _OSC control method is absent from the scope of a host bridge
Jesse Keating 2f82dda
device, then the operating system must not enable or attempt to use any
Jesse Keating 2f82dda
features defined in this section for the hierarchy originated by the host
Jesse Keating 2f82dda
bridge."
Jesse Keating 2f82dda
Jesse Keating 2f82dda
The obvious interpretation of this is that the OS should not attempt to use
Jesse Keating 2f82dda
PCIe hotplug, PME or AER - however, the specification also notes that an
Jesse Keating 2f82dda
_OSC method is *required* for PCIe hierarchies, and experimental validation
Jesse Keating 2f82dda
with An Alternative OS indicates that it doesn't use any PCIe functionality
Jesse Keating 2f82dda
if the _OSC method is missing. That arguably means we shouldn't be using
Jesse Keating 2f82dda
MSI or extended config space, but right now our problems seem to be limited
Jesse Keating 2f82dda
to vendors being surprised when ASPM gets enabled on machines when other
Jesse Keating 2f82dda
OSs refuse to do so. So, for now, let's just disable ASPM if the _OSC
Jesse Keating 2f82dda
method doesn't exist or refuses to hand over PCIe capability control.
Jesse Keating 2f82dda
Jesse Keating 2f82dda
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Jesse Keating 2f82dda
---
Jesse Keating 2f82dda
Jesse Keating 2f82dda
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
Jesse Keating 2f82dda
index 4eac593..1f67057 100644
Jesse Keating 2f82dda
--- a/drivers/acpi/pci_root.c
Jesse Keating 2f82dda
+++ b/drivers/acpi/pci_root.c
Jesse Keating 2f82dda
@@ -33,6 +33,7 @@
Jesse Keating 2f82dda
 #include <linux/pm.h>
Jesse Keating 2f82dda
 #include <linux/pci.h>
Jesse Keating 2f82dda
 #include <linux/pci-acpi.h>
Jesse Keating 2f82dda
+#include <linux/pci-aspm.h>
Jesse Keating 2f82dda
 #include <linux/acpi.h>
Jesse Keating 2f82dda
 #include <acpi/acpi_bus.h>
Jesse Keating 2f82dda
 #include <acpi/acpi_drivers.h>
Jesse Keating 2f82dda
@@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
Jesse Keating 2f82dda
 	if (flags != base_flags)
Jesse Keating 2f82dda
 		acpi_pci_osc_support(root, flags);
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+	status = acpi_pci_osc_control_set(root->device->handle,
Jesse Keating 2f82dda
+					  0);
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+	if (status == AE_NOT_EXIST) {
Jesse Keating 2f82dda
+		printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
Jesse Keating 2f82dda
+		pcie_no_aspm();
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 	return 0;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 end: