PCI: Configure ASPM when enabling device
We can't do ASPM configuration at enumeration-time because enabling it makes some defective hardware unresponsive, even if ASPM is disabled later (see41cd766b06
("PCI: Don't enable aspm before drivers have had a chance to veto it"). Therefore, we have to do it after a driver claims the device. We previously configured ASPM in pci_set_power_state(), but that's not a very good place because it's not really related to setting the PCI device power state, and doing it there means: - We incorrectly skipped ASPM config when setting a device that's already in D0 to D0. - We unnecessarily configured ASPM when setting a device to a low-power state (the ASPM feature only applies when the device is in D0). - We unnecessarily configured ASPM when called from a .resume() method (ASPM configuration needs to be restored during resume, but pci_restore_pcie_state() should already do this). Move ASPM configuration from pci_set_power_state() to do_pci_enable_device() so we do it when a driver enables a device. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=79621 Fixes:db288c9c5f
("PCI / PM: restore the original behavior of pci_set_power_state()") Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Vidya Sagar <sagar.tv@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: stable@vger.kernel.org # v3.6+
This commit is contained in:
parent
cbace46a97
commit
1f6ae47ecf
|
@ -839,12 +839,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
|
|||
|
||||
if (!__pci_complete_power_transition(dev, state))
|
||||
error = 0;
|
||||
/*
|
||||
* When aspm_policy is "powersave" this call ensures
|
||||
* that ASPM is configured.
|
||||
*/
|
||||
if (!error && dev->bus->self)
|
||||
pcie_aspm_powersave_config_link(dev->bus->self);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -1195,12 +1189,18 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
|
|||
static int do_pci_enable_device(struct pci_dev *dev, int bars)
|
||||
{
|
||||
int err;
|
||||
struct pci_dev *bridge;
|
||||
u16 cmd;
|
||||
u8 pin;
|
||||
|
||||
err = pci_set_power_state(dev, PCI_D0);
|
||||
if (err < 0 && err != -EIO)
|
||||
return err;
|
||||
|
||||
bridge = pci_upstream_bridge(dev);
|
||||
if (bridge)
|
||||
pcie_aspm_powersave_config_link(bridge);
|
||||
|
||||
err = pcibios_enable_device(dev, bars);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
Loading…
Reference in New Issue