aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-01-20 20:17:42 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-01-23 16:13:54 -0500
commitbac2a909a096c9110525c18cbb8ce73c660d5f71 (patch)
tree59bd2a6efea9c9cb4cca404f35ae94c67f0dd988 /drivers/pci/pci.c
parentec6f34e5b552fb0a52e6aae1a5afbbb1605cc6cc (diff)
PCI / PM: Avoid resuming PCI devices during system suspend
Commit f25c0ae2b4c4 (ACPI / PM: Avoid resuming devices in ACPI PM domain during system suspend) modified the ACPI PM domain's system suspend callbacks to allow devices attached to it to be left in the runtime-suspended state during system suspend so as to optimize the suspend process. This was based on the general mechanism introduced by commit aae4518b3124 (PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily). Extend that approach to PCI devices by modifying the PCI bus type's ->prepare callback to return 1 for devices that are runtime-suspended when it is being executed and that are in a suitable power state and need not be resumed going forward. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index cab05f31223f..7a671abceccc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -521,6 +521,11 @@ static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
521 pci_platform_pm->run_wake(dev, enable) : -ENODEV; 521 pci_platform_pm->run_wake(dev, enable) : -ENODEV;
522} 522}
523 523
524static inline bool platform_pci_need_resume(struct pci_dev *dev)
525{
526 return pci_platform_pm ? pci_platform_pm->need_resume(dev) : false;
527}
528
524/** 529/**
525 * pci_raw_set_power_state - Use PCI PM registers to set the power state of 530 * pci_raw_set_power_state - Use PCI PM registers to set the power state of
526 * given PCI device 531 * given PCI device
@@ -1999,6 +2004,27 @@ bool pci_dev_run_wake(struct pci_dev *dev)
1999} 2004}
2000EXPORT_SYMBOL_GPL(pci_dev_run_wake); 2005EXPORT_SYMBOL_GPL(pci_dev_run_wake);
2001 2006
2007/**
2008 * pci_dev_keep_suspended - Check if the device can stay in the suspended state.
2009 * @pci_dev: Device to check.
2010 *
2011 * Return 'true' if the device is runtime-suspended, it doesn't have to be
2012 * reconfigured due to wakeup settings difference between system and runtime
2013 * suspend and the current power state of it is suitable for the upcoming
2014 * (system) transition.
2015 */
2016bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
2017{
2018 struct device *dev = &pci_dev->dev;
2019
2020 if (!pm_runtime_suspended(dev)
2021 || (device_can_wakeup(dev) && !device_may_wakeup(dev))
2022 || platform_pci_need_resume(pci_dev))
2023 return false;
2024
2025 return pci_target_state(pci_dev) == pci_dev->current_state;
2026}
2027
2002void pci_config_pm_runtime_get(struct pci_dev *pdev) 2028void pci_config_pm_runtime_get(struct pci_dev *pdev)
2003{ 2029{
2004 struct device *dev = &pdev->dev; 2030 struct device *dev = &pdev->dev;