diff options
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r-- | drivers/pci/pcie/Kconfig | 20 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 17 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 16 |
3 files changed, 37 insertions, 16 deletions
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index b8b494b3e0d..dda70981b7a 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -31,14 +31,22 @@ source "drivers/pci/pcie/aer/Kconfig" # PCI Express ASPM # config PCIEASPM - bool "PCI Express ASPM support(Experimental)" - depends on PCI && EXPERIMENTAL && PCIEPORTBUS - default n + bool "PCI Express ASPM control" if EMBEDDED + depends on PCI && PCIEPORTBUS + default y help - This enables PCI Express ASPM (Active State Power Management) and - Clock Power Management. ASPM supports state L0/L0s/L1. + This enables OS control over PCI Express ASPM (Active State + Power Management) and Clock Power Management. ASPM supports + state L0/L0s/L1. - When in doubt, say N. + ASPM is initially set up the the firmware. With this option enabled, + Linux can modify this state in order to disable ASPM on known-bad + hardware or configurations and enable it when known-safe. + + ASPM can be disabled or enabled at runtime via + /sys/module/pcie_aspm/parameters/policy + + When in doubt, say Y. config PCIEASPM_DEBUG bool "Debug PCI Express ASPM" depends on PCIEASPM diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8af4f619bba..fc0b5a93e1d 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -727,20 +727,21 @@ static void aer_isr_one_error(struct pcie_device *p_device, static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src) { unsigned long flags; - int ret = 0; /* Lock access to Root error producer/consumer index */ spin_lock_irqsave(&rpc->e_lock, flags); - if (rpc->prod_idx != rpc->cons_idx) { - *e_src = rpc->e_sources[rpc->cons_idx]; - rpc->cons_idx++; - if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) - rpc->cons_idx = 0; - ret = 1; + if (rpc->prod_idx == rpc->cons_idx) { + spin_unlock_irqrestore(&rpc->e_lock, flags); + return 0; } + + *e_src = rpc->e_sources[rpc->cons_idx]; + rpc->cons_idx++; + if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) + rpc->cons_idx = 0; spin_unlock_irqrestore(&rpc->e_lock, flags); - return ret; + return 1; } /** diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index be53d98fa38..71222814c1e 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -588,11 +588,23 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) * update through pcie_aspm_cap_init(). */ pcie_aspm_cap_init(link, blacklist); - pcie_config_aspm_path(link); /* Setup initial Clock PM state */ pcie_clkpm_cap_init(link, blacklist); - pcie_set_clkpm(link, policy_to_clkpm_state(link)); + + /* + * At this stage drivers haven't had an opportunity to change the + * link policy setting. Enabling ASPM on broken hardware can cripple + * it even before the driver has had a chance to disable ASPM, so + * default to a safe level right now. If we're enabling ASPM beyond + * the BIOS's expectation, we'll do so once pci_enable_device() is + * called. + */ + if (aspm_policy != POLICY_POWERSAVE) { + pcie_config_aspm_path(link); + pcie_set_clkpm(link, policy_to_clkpm_state(link)); + } + unlock: mutex_unlock(&aspm_lock); out: |