Subject: [PATCH] PCI: Remove not needed check in disable aspm link 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 pcie_aspm_sanity_check does not work anymore as aspm_disabled is set before pci root bus scanning. Bjorn revert that for v3.9, and that will make booting path and hotplug path with different aspm_disabled again. For fixing acpiphp and pciehp loading, we need put that "osc set early" again. For regression that Roman had, acctually we don't need to check aspm_disabled in pci_disable_link_state, as we already have protection about link state checking. And pci_disable_link_state will be called only for quirk and driver directly. That will keep the logic in pcie_aspm_sanity_check() in commits: 0ae5eaf10 PCI: ignore pre-1.1 ASPM quirking when ASPM is disabled cdb0f9a1a ASPM: Fix pcie devices with non-pcie children still working, AKA still not touch pre-1.1 ASPM device. https://bugzilla.kernel.org/show_bug.cgi?id=55211 http://article.gmane.org/gmane.linux.kernel.pci/20640 Also remove aspm_support_enabled. if aspm is compiled in, even user pass aspm=off, link_state still get allocated, then we will have chance to disable aspm on devices from buggy setting of BIOS. According Bjorn, move the FADT disabling handling early. -v4: update changelog accordingly for v3.10 Reported-by: Roman Yepishev Bisected-by: Roman Yepishev Signed-off-by: Yinghai Lu Cc: Taku Izumi Cc: Kenji Kaneshige --- drivers/acpi/pci_root.c | 24 +++++++++--------------- drivers/pci/pcie/aspm.c | 39 +++------------------------------------ include/linux/pci-aspm.h | 4 ---- include/linux/pci.h | 2 +- 4 files changed, 13 insertions(+), 56 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 @@ -382,7 +382,6 @@ static int acpi_pci_root_add(struct acpi int result; struct acpi_pci_root *root; u32 flags, base_flags; - bool is_osc_granted = false; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -461,6 +460,11 @@ static int acpi_pci_root_add(struct acpi flags = base_flags; } } + + /* ASPM setting */ + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) + pcie_no_aspm(); + if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL @@ -480,16 +484,16 @@ 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; + if (ACPI_SUCCESS(status)) dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); - } else { - is_osc_granted = false; + else { dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", acpi_format_exception(status), flags); + pr_info("ACPI _OSC control for PCIe not granted disabling ASPM\n"); + pcie_no_aspm(); } } else { dev_info(&device->dev, @@ -521,16 +525,6 @@ static int acpi_pci_root_add(struct acpi 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); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); Index: linux-2.6/drivers/pci/pcie/aspm.c =================================================================== --- linux-2.6.orig/drivers/pci/pcie/aspm.c +++ linux-2.6/drivers/pci/pcie/aspm.c @@ -69,7 +69,6 @@ struct pcie_link_state { }; static int aspm_disabled, aspm_force; -static bool aspm_support_enabled = true; static DEFINE_MUTEX(aspm_lock); static LIST_HEAD(link_list); @@ -556,9 +555,6 @@ void pcie_aspm_init_link_state(struct pc struct pcie_link_state *link; int blacklist = !!pcie_aspm_sanity_check(pdev); - if (!aspm_support_enabled) - return; - if (!pci_is_pcie(pdev) || pdev->link_state) return; if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && @@ -718,15 +714,11 @@ void pcie_aspm_powersave_config_link(str * pci_disable_link_state - disable pci device's link state, so the link will * never enter specific states */ -static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, - bool force) +static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) { struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link; - if (aspm_disabled && !force) - return; - if (!pci_is_pcie(pdev)) return; @@ -757,34 +749,16 @@ static void __pci_disable_link_state(str void pci_disable_link_state_locked(struct pci_dev *pdev, int state) { - __pci_disable_link_state(pdev, state, false, false); + __pci_disable_link_state(pdev, state, false); } EXPORT_SYMBOL(pci_disable_link_state_locked); void pci_disable_link_state(struct pci_dev *pdev, int state) { - __pci_disable_link_state(pdev, state, true, false); + __pci_disable_link_state(pdev, state, true); } EXPORT_SYMBOL(pci_disable_link_state); -void pcie_clear_aspm(struct pci_bus *bus) -{ - struct pci_dev *child; - - if (aspm_force) - return; - - /* - * Clear any ASPM setup that the firmware has carried out on this bus - */ - list_for_each_entry(child, &bus->devices, bus_list) { - __pci_disable_link_state(child, PCIE_LINK_STATE_L0S | - PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM, - false, true); - } -} - static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) { int i; @@ -944,7 +918,6 @@ static int __init pcie_aspm_disable(char if (!strcmp(str, "off")) { aspm_policy = POLICY_DEFAULT; aspm_disabled = 1; - aspm_support_enabled = false; printk(KERN_INFO "PCIe ASPM is disabled\n"); } else if (!strcmp(str, "force")) { aspm_force = 1; @@ -980,9 +953,3 @@ int pcie_aspm_enabled(void) return !aspm_disabled; } EXPORT_SYMBOL(pcie_aspm_enabled); - -bool pcie_aspm_support_enabled(void) -{ - return aspm_support_enabled; -} -EXPORT_SYMBOL(pcie_aspm_support_enabled); Index: linux-2.6/include/linux/pci-aspm.h =================================================================== --- linux-2.6.orig/include/linux/pci-aspm.h +++ linux-2.6/include/linux/pci-aspm.h @@ -29,7 +29,6 @@ void pcie_aspm_pm_state_change(struct pc void pcie_aspm_powersave_config_link(struct pci_dev *pdev); void pci_disable_link_state(struct pci_dev *pdev, int state); void pci_disable_link_state_locked(struct pci_dev *pdev, int state); -void pcie_clear_aspm(struct pci_bus *bus); void pcie_no_aspm(void); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) @@ -47,9 +46,6 @@ static inline void pcie_aspm_powersave_c static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { } -static inline void pcie_clear_aspm(struct pci_bus *bus) -{ -} static inline void pcie_no_aspm(void) { } Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -1186,7 +1186,7 @@ static inline int pcie_aspm_enabled(void static inline bool pcie_aspm_support_enabled(void) { return false; } #else int pcie_aspm_enabled(void); -bool pcie_aspm_support_enabled(void); +static inline bool pcie_aspm_support_enabled(void) { return true; } #endif #ifdef CONFIG_PCIEAER