Subject: [PATCH] PCI, ACPI: Delay pcie_no_aspm() calling Roman reported ath5k does not work anymore on 3.8. Bisected to | commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6 | Author: Taku Izumi | Date: Tue Oct 30 15:27:13 2012 +0900 | | PCI/ACPI: Request _OSC control before scanning PCI root bus | | This patch moves up the code block to request _OSC control in order to | separate ACPI work and PCI work in acpi_pci_root_add(). It make pci_disable_link_state does not work anymore as acpi_disabled is set before pci root bus scanning. It will skip that in quirks and pcie_aspm_sanity_check. Retore old logic just delay calling pcie_no_aspm() later. https://bugzilla.kernel.org/show_bug.cgi?id=55211 http://article.gmane.org/gmane.linux.kernel.pci/20640 Need it for 3.8 stable. Reported-by: Roman Yepishev Bisected-by: Roman Yepishev Tested-by: Roman Yepishev Signed-off-by: Yinghai Lu Cc: stable@kernel.org --- drivers/acpi/pci_root.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) Index: linux-2.6/drivers/acpi/pci_root.c =================================================================== --- linux-2.6.orig/drivers/acpi/pci_root.c +++ linux-2.6/drivers/acpi/pci_root.c @@ -415,7 +415,9 @@ static int acpi_pci_root_add(struct acpi struct acpi_pci_root *root; struct acpi_pci_driver *driver; u32 flags, base_flags; - bool is_osc_granted = false; + /* -1: not even tried, 0: tried but failed, 1: tried and succesful */ + int osc_support_query_state = -1; + int osc_control_set_state = -1; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -488,11 +490,12 @@ static int acpi_pci_root_add(struct acpi if (flags != base_flags) { status = acpi_pci_osc_support(root, flags); if (ACPI_FAILURE(status)) { + osc_support_query_state = 0; dev_info(&device->dev, "ACPI _OSC support " - "notification failed, disabling PCIe ASPM\n"); - pcie_no_aspm(); + "notification failed, PCIe ASPM will be disabled\n"); flags = base_flags; - } + } else + osc_support_query_state = 1; } if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { @@ -514,11 +517,11 @@ static int acpi_pci_root_add(struct acpi status = acpi_pci_osc_control_set(device->handle, &flags, OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); if (ACPI_SUCCESS(status)) { - is_osc_granted = true; + osc_control_set_state = 1; dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); } else { - is_osc_granted = false; + osc_control_set_state = 0; dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", @@ -555,13 +558,16 @@ static int acpi_pci_root_add(struct acpi } /* ASPM setting */ - if (is_osc_granted) { + if (osc_support_query_state == 0) { + dev_info(&device->dev, "ACPI _OSC support notification failed, PCIe ASPM disabled\n"); + pcie_no_aspm(); + } + if (osc_control_set_state == 1) { 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(); + } else if (osc_control_set_state == 0) { + dev_info(&device->dev, "ACPI _OSC control not granted, PCIe ASPM disabled\n"); + pcie_no_aspm(); } pci_acpi_add_bus_pm_notifier(device, root->bus);