aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
authorNaga Chumbalkar <nagananda.chumbalkar@hp.com>2011-03-20 23:29:20 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-03-21 12:41:08 -0400
commiteca67315e0e0d5fd91264d79c88694006dbc7d31 (patch)
tree4a68e41c0ea71cbbff8d72827d6e39f8f222c0cf /drivers/acpi/pci_root.c
parentbbfa306a1e5d9618231aa0de3d52a8eb1219d0c3 (diff)
PCI: Disable ASPM when _OSC control is not granted for PCIe services
v3 -> v2: Added text to describe the problem v2 -> v1: Split this patch from v1 v1 : Part of: http://marc.info/?l=linux-pci&m=130042212003242&w=2 Disable ASPM when no _OSC control for PCIe services is granted by the BIOS. This is to protect systems with a buggy BIOS that did not set the ACPI FADT "ASPM Controls" bit even though the underlying HW can't do ASPM. To turn "on" ASPM the minimum the BIOS needs to do: 1. Clear the ACPI FADT "ASPM Controls" bit. 2. Support _OSC appropriately There is no _OSC Control bit for ASPM. However, we expect the BIOS to support _OSC for a Root Bridge that originates a PCIe hierarchy. If this is not the case - we are better off not enabling ASPM on that server. Commit 852972acff8f10f3a15679be2059bb94916cba5d (ACPI: Disable ASPM if the Platform won't provide _OSC control for PCIe) describes the above scenario. To quote verbatim from there: [The PCI SIG documentation for the _OSC OS/firmware handshaking interface states: "If the _OSC control method is absent from the scope of a host bridge device, then the operating system must not enable or attempt to use any features defined in this section for the hierarchy originated by the host bridge." The obvious interpretation of this is that the OS should not attempt to use PCIe hotplug, PME or AER - however, the specification also notes that an _OSC method is *required* for PCIe hierarchies, and experimental validation with An Alternative OS indicates that it doesn't use any PCIe functionality if the _OSC method is missing. That arguably means we shouldn't be using MSI or extended config space, but right now our problems seem to be limited to vendors being surprised when ASPM gets enabled on machines when other OSs refuse to do so. So, for now, let's just disable ASPM if the _OSC method doesn't exist or refuses to hand over PCIe capability control.] Signed-off-by: Naga Chumbalkar <nagananda.chumbalkar@hp.com> Cc: Rafael J. Wysocki <rjw@sisk.pl> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index c7358dd68b31..f911a2f8cc34 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -32,6 +32,7 @@
32#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/pci-acpi.h> 34#include <linux/pci-acpi.h>
35#include <linux/pci-aspm.h>
35#include <linux/acpi.h> 36#include <linux/acpi.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -591,12 +592,16 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
591 592
592 status = acpi_pci_osc_control_set(device->handle, &flags, 593 status = acpi_pci_osc_control_set(device->handle, &flags,
593 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); 594 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
594 if (ACPI_SUCCESS(status)) 595 if (ACPI_SUCCESS(status)) {
595 dev_info(root->bus->bridge, 596 dev_info(root->bus->bridge,
596 "ACPI _OSC control (0x%02x) granted\n", flags); 597 "ACPI _OSC control (0x%02x) granted\n", flags);
597 else 598 } else {
598 dev_dbg(root->bus->bridge, 599 dev_dbg(root->bus->bridge,
599 "ACPI _OSC request failed (code %d)\n", status); 600 "ACPI _OSC request failed (code %d)\n", status);
601 printk(KERN_INFO "Unable to assume _OSC PCIe control. "
602 "Disabling ASPM\n");
603 pcie_no_aspm();
604 }
600 } 605 }
601 606
602 pci_acpi_add_bus_pm_notifier(device, root->bus); 607 pci_acpi_add_bus_pm_notifier(device, root->bus);