diff options
author | Naga Chumbalkar <nagananda.chumbalkar@hp.com> | 2011-03-20 23:29:08 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-03-21 12:40:43 -0400 |
commit | 1a680b7c325882188865f05b9a88d32f75f26495 (patch) | |
tree | eb3844655f9ff01630157e4b2c039759970b1a94 /drivers/pci | |
parent | 8b8bae901ce23addbdcdb54fa1696fb2d049feb5 (diff) |
PCI: PCIe links may not get configured for ASPM under POWERSAVE mode
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 commit 41cd766b065970ff6f6c89dd1cf55fa706c84a3d
(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 commit
97c145f7c87453cec90e91238fba5fe2c1561b32 (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>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.c | 6 | ||||
-rw-r--r-- | drivers/pci/pcie/aspm.c | 22 |
2 files changed, 28 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b714d787bddd..2472e7177b4b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -740,6 +740,12 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
740 | 740 | ||
741 | if (!__pci_complete_power_transition(dev, state)) | 741 | if (!__pci_complete_power_transition(dev, state)) |
742 | error = 0; | 742 | error = 0; |
743 | /* | ||
744 | * When aspm_policy is "powersave" this call ensures | ||
745 | * that ASPM is configured. | ||
746 | */ | ||
747 | if (!error && dev->bus->self) | ||
748 | pcie_aspm_powersave_config_link(dev->bus->self); | ||
743 | 749 | ||
744 | return error; | 750 | return error; |
745 | } | 751 | } |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index bbdb4fd85b9c..e61b82e611c2 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -708,6 +708,28 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) | |||
708 | up_read(&pci_bus_sem); | 708 | up_read(&pci_bus_sem); |
709 | } | 709 | } |
710 | 710 | ||
711 | void pcie_aspm_powersave_config_link(struct pci_dev *pdev) | ||
712 | { | ||
713 | struct pcie_link_state *link = pdev->link_state; | ||
714 | |||
715 | if (aspm_disabled || !pci_is_pcie(pdev) || !link) | ||
716 | return; | ||
717 | |||
718 | if (aspm_policy != POLICY_POWERSAVE) | ||
719 | return; | ||
720 | |||
721 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | ||
722 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | ||
723 | return; | ||
724 | |||
725 | down_read(&pci_bus_sem); | ||
726 | mutex_lock(&aspm_lock); | ||
727 | pcie_config_aspm_path(link); | ||
728 | pcie_set_clkpm(link, policy_to_clkpm_state(link)); | ||
729 | mutex_unlock(&aspm_lock); | ||
730 | up_read(&pci_bus_sem); | ||
731 | } | ||
732 | |||
711 | /* | 733 | /* |
712 | * pci_disable_link_state - disable pci device's link state, so the link will | 734 | * pci_disable_link_state - disable pci device's link state, so the link will |
713 | * never enter specific states | 735 | * never enter specific states |