mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Naga Chumbalkar](/assets/img/avatar_default.png)
v3 -> v2: Moved ASPM enabling logic to pci_set_power_state() v2 -> v1: Preserved the logic in pci_raw_set_power_state() : Added ASPM enabling logic after scanning Root Bridge : http://marc.info/?l=linux-pci&m=130046996216391&w=2 v1 : http://marc.info/?l=linux-pci&m=130013164703283&w=2 The assumption made in commit41cd766b06
(PCI: Don't enable aspm before drivers have had a chance to veto it) that pci_enable_device() will result in re-configuring ASPM when aspm_policy is POWERSAVE is no longer valid. This is due to commit97c145f7c8
(PCI: read current power state at enable time) which resets dev->current_state to D0. Due to this the call to pcie_aspm_pm_state_change() is never made. Note the equality check (below) that returns early: ./drivers/pci/pci.c: pci_raw_set_pci_power_state() 546 /* Check if we're already there */ 547 if (dev->current_state == state) 548 return 0; Therefore OSPM never configures the PCIe links for ASPM to turn them "on". Fix it by configuring ASPM from the pci_enable_device() code path. This also allows a driver such as the e1000e networking driver a chance to disable ASPM (L0s, L1), if need be, prior to enabling the device. A driver may perform this action if the device is known to mis-behave wrt ASPM. Signed-off-by: Naga Chumbalkar <nagananda.chumbalkar@hp.com> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
68 lines
1.7 KiB
C
68 lines
1.7 KiB
C
/*
|
|
* aspm.h
|
|
*
|
|
* PCI Express ASPM defines and function prototypes
|
|
*
|
|
* Copyright (C) 2007 Intel Corp.
|
|
* Zhang Yanmin (yanmin.zhang@intel.com)
|
|
* Shaohua Li (shaohua.li@intel.com)
|
|
*
|
|
* For more information, please consult the following manuals (look at
|
|
* http://www.pcisig.com/ for how to get them):
|
|
*
|
|
* PCI Express Specification
|
|
*/
|
|
|
|
#ifndef LINUX_ASPM_H
|
|
#define LINUX_ASPM_H
|
|
|
|
#include <linux/pci.h>
|
|
|
|
#define PCIE_LINK_STATE_L0S 1
|
|
#define PCIE_LINK_STATE_L1 2
|
|
#define PCIE_LINK_STATE_CLKPM 4
|
|
|
|
#ifdef CONFIG_PCIEASPM
|
|
extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
|
|
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
|
|
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
|
|
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 pcie_clear_aspm(void);
|
|
extern void pcie_no_aspm(void);
|
|
#else
|
|
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
|
|
{
|
|
}
|
|
static inline void pcie_clear_aspm(void)
|
|
{
|
|
}
|
|
static inline void pcie_no_aspm(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */
|
|
extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
|
|
extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
|
|
#else
|
|
static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
|
|
{
|
|
}
|
|
#endif
|
|
#endif /* LINUX_ASPM_H */
|