Commit b8178f13 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus"

This reverts commit 8c33f51d.

Conflicts:
	drivers/acpi/pci_root.c

This commit broke some pre-1.1 PCIe devices by leaving them with
ASPM enabled.  Previously, we had disabled ASPM on these devices
because many of them don't implement it correctly (per 149e1637).

Requesting _OSC control early means that aspm_disabled may be set
before we scan the PCI bus and configure link ASPM state.  But the
ASPM configuration currently skips the check for pre-PCIe 1.1 devices
when aspm_disabled is set, like this:

    acpi_pci_root_add
      acpi_pci_osc_support
        if (flags != base_flags)
          pcie_no_aspm
            aspm_disabled = 1
      pci_acpi_scan_root
        ...
          pcie_aspm_init_link_state
            pcie_aspm_sanity_check
              if (!aspm_disabled)
                /* check for pre-PCIe 1.1 device */

Therefore, setting aspm_disabled early means that we leave ASPM enabled
on these pre-PCIe 1.1 devices, which is a regression for some devices.

The best fix would be to clean up the ASPM init so we can evaluate
_OSC before scanning the bug (that way boot-time and hot-add discovery
will work the same), but that requires significant rework.

For now, we'll just revert the _OSC change as the lowest-risk fix.

Reference: https://bugzilla.kernel.org/show_bug.cgi?id=55211Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: default avatarYinghai Lu <yinghai@kernel.org>
CC: stable@vger.kernel.org	# v3.8+
parent be7f088b
...@@ -415,7 +415,6 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -415,7 +415,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
struct acpi_pci_root *root; struct acpi_pci_root *root;
struct acpi_pci_driver *driver; struct acpi_pci_driver *driver;
u32 flags, base_flags; u32 flags, base_flags;
bool is_osc_granted = false;
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root) if (!root)
...@@ -476,6 +475,30 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -476,6 +475,30 @@ static int acpi_pci_root_add(struct acpi_device *device,
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
acpi_pci_osc_support(root, flags); acpi_pci_osc_support(root, flags);
/*
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
mutex_lock(&acpi_pci_root_lock);
list_add_tail(&root->node, &acpi_pci_roots);
mutex_unlock(&acpi_pci_root_lock);
/*
* Scan the Root Bridge
* --------------------
* Must do this prior to any attempt to bind the root device, as the
* PCI namespace does not get created until this call is made (and
* thus the root bridge's pci_dev does not exist).
*/
root->bus = pci_acpi_scan_root(root);
if (!root->bus) {
printk(KERN_ERR PREFIX
"Bus %04x:%02x not present in PCI namespace\n",
root->segment, (unsigned int)root->secondary.start);
result = -ENODEV;
goto out_del_root;
}
/* Indicate support for various _OSC capabilities. */ /* Indicate support for various _OSC capabilities. */
if (pci_ext_cfg_avail()) if (pci_ext_cfg_avail())
flags |= OSC_EXT_PCI_CONFIG_SUPPORT; flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
...@@ -494,6 +517,7 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -494,6 +517,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
flags = base_flags; flags = base_flags;
} }
} }
if (!pcie_ports_disabled if (!pcie_ports_disabled
&& (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
...@@ -514,54 +538,28 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -514,54 +538,28 @@ static int acpi_pci_root_add(struct acpi_device *device,
status = acpi_pci_osc_control_set(device->handle, &flags, status = acpi_pci_osc_control_set(device->handle, &flags,
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
is_osc_granted = true;
dev_info(&device->dev, dev_info(&device->dev,
"ACPI _OSC control (0x%02x) granted\n", flags); "ACPI _OSC control (0x%02x) granted\n", flags);
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
/*
* We have ASPM control, but the FADT indicates
* that it's unsupported. Clear it.
*/
pcie_clear_aspm(root->bus);
}
} else { } else {
is_osc_granted = false;
dev_info(&device->dev, dev_info(&device->dev,
"ACPI _OSC request failed (%s), " "ACPI _OSC request failed (%s), "
"returned control mask: 0x%02x\n", "returned control mask: 0x%02x\n",
acpi_format_exception(status), flags); acpi_format_exception(status), flags);
pr_info("ACPI _OSC control for PCIe not granted, "
"disabling ASPM\n");
pcie_no_aspm();
} }
} else { } else {
dev_info(&device->dev, dev_info(&device->dev,
"Unable to request _OSC control " "Unable to request _OSC control "
"(_OSC support mask: 0x%02x)\n", flags); "(_OSC support mask: 0x%02x)\n", flags);
}
/*
* TBD: Need PCI interface for enumeration/configuration of roots.
*/
mutex_lock(&acpi_pci_root_lock);
list_add_tail(&root->node, &acpi_pci_roots);
mutex_unlock(&acpi_pci_root_lock);
/*
* Scan the Root Bridge
* --------------------
* Must do this prior to any attempt to bind the root device, as the
* PCI namespace does not get created until this call is made (and
* thus the root bridge's pci_dev does not exist).
*/
root->bus = pci_acpi_scan_root(root);
if (!root->bus) {
printk(KERN_ERR PREFIX
"Bus %04x:%02x not present in PCI namespace\n",
root->segment, (unsigned int)root->secondary.start);
result = -ENODEV;
goto out_del_root;
}
/* ASPM setting */
if (is_osc_granted) {
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
pcie_clear_aspm(root->bus);
} else {
pr_info("ACPI _OSC control for PCIe not granted, "
"disabling ASPM\n");
pcie_no_aspm();
} }
pci_acpi_add_bus_pm_notifier(device, root->bus); pci_acpi_add_bus_pm_notifier(device, root->bus);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment