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 acpi_disabled is set before pci root bus scanning. We could revert to old logic, but that will make booting path and hotplug path with different aspm_disabled again. 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 only called explicted for quirk and driver. 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 Need it for 3.8 stable. -v2: more cleanup 1. remove aspm_support_enabled, as if it compiled in, support is there so 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. 2. move pcie_no_aspm() calling for fadt disabling before scanning requested by Bjorn. -v3: remove change in pcie_aspm_sanity_check() Reported-by: Roman Yepishev Bisected-by: Roman Yepishev Signed-off-by: Yinghai Lu Cc: Taku Izumi Cc: Kenji Kaneshige --- drivers/acpi/pci_root.c | 25 +++++++++--------------- drivers/pci/pcie/aspm.c | 48 ++--------------------------------------------- include/linux/pci-aspm.h | 4 --- include/linux/pci.h | 2 - 4 files changed, 14 insertions(+), 65 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,6 @@ 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; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -494,6 +493,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 @@ -513,16 +517,17 @@ 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, @@ -554,16 +559,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 +546,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 +705,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 +740,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 +909,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 +944,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 @@ extern void pcie_aspm_pm_state_change(st extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); extern void pci_disable_link_state(struct pci_dev *pdev, int state); extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); -extern void pcie_clear_aspm(struct pci_bus *bus); extern 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 @@ -1168,7 +1168,7 @@ static inline int pcie_aspm_enabled(void static inline bool pcie_aspm_support_enabled(void) { return false; } #else extern int pcie_aspm_enabled(void); -extern bool pcie_aspm_support_enabled(void); +static inline bool pcie_aspm_support_enabled(void) { return true; } #endif #ifdef CONFIG_PCIEAER