]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
PCI: Configure ASPM when enabling device
authorVidya Sagar <sagar.tv@gmail.com>
Wed, 16 Jul 2014 10:03:42 +0000 (15:33 +0530)
committerSachin Nikam <snikam@nvidia.com>
Fri, 25 Jul 2014 11:01:24 +0000 (04:01 -0700)
We can't do ASPM configuration at enumeration-time because enabling it
makes some defective hardware unresponsive, even if ASPM is disabled later
(see 41cd766b0659 ("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.

Fixes: db288c9c5f9d ("PCI / PM: restore the original behavior of pci_set_power_state()")
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Bug 200011678

(cherry picked from commit 1f6ae47ecff7f23da73417e068018b311f3b5583)
repo : git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git

Change-Id: I0f8eebcd472c1ec1d5099bc560742af55d7d5aba

Link: https://bugzilla.kernel.org/show_bug.cgi?id=79621
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Vidya Sagar <sagar.tv@gmail.com>
Change-Id: I0f8eebcd472c1ec1d5099bc560742af55d7d5aba
Reviewed-on: http://git-master/r/440348
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Tested-by: Sachin Nikam <snikam@nvidia.com>
drivers/pci/pci.c

index 0bb7bfd49bf6555141393d55837fd584d4e3c99f..29f9e6bc5c79f4be9722a8269cbebe7a2a94f22e 100644 (file)
@@ -781,12 +781,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;
 }
@@ -1119,12 +1113,18 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
 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;