commit 885c252ffb059dc493200bdb981bdd21cabe4442 Author: Matthew Garrett Date: Thu Dec 9 18:31:59 2010 -0500 PCI: _OSC "supported" field should contain supported features, not enabled ones From testing with Windows, the call to the PCI root _OSC method includes the full set of features supported by the operating system even if the hardware has already indicated that it doesn't support ASPM or MSI. https://bugzilla.redhat.com/show_bug.cgi?id=638912 is a case where making the _OSC call will incorrectly configure the chipset unless the supported field has bits 1, 2 and 4 set. Rework the functionality to ensure that we match this behaviour. Signed-off-by: Matthew Garrett diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 96668ad..afb5d08 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -450,7 +450,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) struct acpi_pci_root *root; acpi_handle handle; struct acpi_device *child; - u32 flags, base_flags; + u32 flags; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -498,10 +498,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) device->driver_data = root; /* - * All supported architectures that use ACPI have support for - * PCI domains, so we indicate this in _OSC support capabilities. + * Indicate support for various _OSC capabilities. These match + * what the operating system supports, not what the hardware supports, + * so they shouldn't be conditional on functionality that's been + * blacklisted */ - flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; + flags = OSC_EXT_PCI_CONFIG_SUPPORT | OSC_ACTIVE_STATE_PWR_SUPPORT | + OSC_CLOCK_PWR_CAPABILITY_SUPPORT | + OSC_PCI_SEGMENT_GROUPS_SUPPORT | OSC_MSI_SUPPORT; + acpi_pci_osc_support(root, flags); /* @@ -555,17 +560,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) list_for_each_entry(child, &device->children, node) acpi_pci_bridge_scan(child); - /* Indicate support for various _OSC capabilities. */ - if (pci_ext_cfg_avail(root->bus->self)) - flags |= OSC_EXT_PCI_CONFIG_SUPPORT; - if (pcie_aspm_enabled()) - flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | - OSC_CLOCK_PWR_CAPABILITY_SUPPORT; - if (pci_msi_enabled()) - flags |= OSC_MSI_SUPPORT; - if (flags != base_flags) - acpi_pci_osc_support(root, flags); - pci_acpi_add_bus_pm_notifier(device, root->bus); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true);