diff options
| author | Lukas Wunner <lukas@wunner.de> | 2016-10-28 04:52:06 -0400 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-11-17 19:46:06 -0500 |
| commit | c6a6330706148e7d5265c3dd658d25843c83390f (patch) | |
| tree | 3a6084b514e490879976faa75fb9efc9f8b7638a /drivers | |
| parent | e8559b7100324494acbde6e26bcdc6a5a5b4a4ed (diff) | |
PCI: Activate runtime PM on a PCIe port only if it can suspend
Currently pcie_portdrv_probe() activates runtime PM on a PCIe port even
if it will never actually suspend because the BIOS is too old or the
"pcie_port_pm=off" option was specified on the kernel command line.
A few CPU cycles can be saved by not activating runtime PM at all in these
cases, because rpm_idle() and rpm_suspend() will bail out right at the
beginning when calling rpm_check_suspend_allowed(), instead of carrying out
various locking and assignments, invoking rpm_callback(), getting back
-EBUSY and rolling everything back.
The conditions checked in pci_bridge_d3_possible() are all static, they
never change during uptime of the system, hence it's safe to call this to
determine if runtime PM should be activated.
No functional change intended.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/pci/pci.c | 2 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 1 | ||||
| -rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 5 |
3 files changed, 5 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4a7f6f54d669..720f7e27c3a8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -2230,7 +2230,7 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) | |||
| 2230 | * This function checks if it is possible to move the bridge to D3. | 2230 | * This function checks if it is possible to move the bridge to D3. |
| 2231 | * Currently we only allow D3 for recent enough PCIe ports. | 2231 | * Currently we only allow D3 for recent enough PCIe ports. |
| 2232 | */ | 2232 | */ |
| 2233 | static bool pci_bridge_d3_possible(struct pci_dev *bridge) | 2233 | bool pci_bridge_d3_possible(struct pci_dev *bridge) |
| 2234 | { | 2234 | { |
| 2235 | unsigned int year; | 2235 | unsigned int year; |
| 2236 | 2236 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 27048bb88783..ffffef37ab61 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -85,6 +85,7 @@ void pci_pm_init(struct pci_dev *dev); | |||
| 85 | void pci_ea_init(struct pci_dev *dev); | 85 | void pci_ea_init(struct pci_dev *dev); |
| 86 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 86 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
| 87 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 87 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
| 88 | bool pci_bridge_d3_possible(struct pci_dev *dev); | ||
| 88 | void pci_bridge_d3_update(struct pci_dev *dev); | 89 | void pci_bridge_d3_update(struct pci_dev *dev); |
| 89 | 90 | ||
| 90 | static inline void pci_wakeup_event(struct pci_dev *dev) | 91 | static inline void pci_wakeup_event(struct pci_dev *dev) |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 79327cc14e7d..1ae712cb22ec 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/dmi.h> | 19 | #include <linux/dmi.h> |
| 20 | #include <linux/pci-aspm.h> | 20 | #include <linux/pci-aspm.h> |
| 21 | 21 | ||
| 22 | #include "../pci.h" | ||
| 22 | #include "portdrv.h" | 23 | #include "portdrv.h" |
| 23 | #include "aer/aerdrv.h" | 24 | #include "aer/aerdrv.h" |
| 24 | 25 | ||
| @@ -157,7 +158,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
| 157 | * subordinate devices). We can't be sure for native PCIe hotplug | 158 | * subordinate devices). We can't be sure for native PCIe hotplug |
| 158 | * either so prevent that as well. | 159 | * either so prevent that as well. |
| 159 | */ | 160 | */ |
| 160 | if (!dev->is_hotplug_bridge) { | 161 | if (pci_bridge_d3_possible(dev) && !dev->is_hotplug_bridge) { |
| 161 | /* | 162 | /* |
| 162 | * Keep the port resumed 100ms to make sure things like | 163 | * Keep the port resumed 100ms to make sure things like |
| 163 | * config space accesses from userspace (lspci) will not | 164 | * config space accesses from userspace (lspci) will not |
| @@ -175,7 +176,7 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
| 175 | 176 | ||
| 176 | static void pcie_portdrv_remove(struct pci_dev *dev) | 177 | static void pcie_portdrv_remove(struct pci_dev *dev) |
| 177 | { | 178 | { |
| 178 | if (!dev->is_hotplug_bridge) { | 179 | if (pci_bridge_d3_possible(dev) && !dev->is_hotplug_bridge) { |
| 179 | pm_runtime_forbid(&dev->dev); | 180 | pm_runtime_forbid(&dev->dev); |
| 180 | pm_runtime_get_noresume(&dev->dev); | 181 | pm_runtime_get_noresume(&dev->dev); |
| 181 | pm_runtime_dont_use_autosuspend(&dev->dev); | 182 | pm_runtime_dont_use_autosuspend(&dev->dev); |
