diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-12-06 20:41:18 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-12-11 08:32:56 -0500 |
commit | 3487972d7fa6c5143951436ada5933dcf0ec659d (patch) | |
tree | e44e9769fce8d3499bf53beae6029232dd1a5d5b /drivers | |
parent | 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36 (diff) |
PM / sleep: Avoid excess pm_runtime_enable() calls in device_resume()
Middle-layer code doing suspend-time optimizations for devices with
the DPM_FLAG_SMART_SUSPEND flag set (currently, the PCI bus type and
the ACPI PM domain) needs to make the core skip ->thaw_early and
->thaw callbacks for those devices in some cases and it sets the
power.direct_complete flag for them for this purpose.
However, it turns out that setting power.direct_complete outside of
the PM core is a bad idea as it triggers an excess invocation of
pm_runtime_enable() in device_resume().
For this reason, provide a helper to clear power.is_late_suspended
and power.is_suspended to be invoked by the middle-layer code in
question instead of setting power.direct_complete and make that code
call the new helper.
Fixes: c4b65157aeef (PCI / PM: Take SMART_SUSPEND driver flag into account)
Fixes: 05087360fd7a (ACPI / PM: Take SMART_SUSPEND driver flag into account)
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/device_pm.c | 2 | ||||
-rw-r--r-- | drivers/base/power/main.c | 15 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 2 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index e4ffaeec9ec2..a4c8ad98560d 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -1138,7 +1138,7 @@ int acpi_subsys_thaw_noirq(struct device *dev) | |||
1138 | * skip all of the subsequent "thaw" callbacks for the device. | 1138 | * skip all of the subsequent "thaw" callbacks for the device. |
1139 | */ | 1139 | */ |
1140 | if (dev_pm_smart_suspend_and_suspended(dev)) { | 1140 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
1141 | dev->power.direct_complete = true; | 1141 | dev_pm_skip_next_resume_phases(dev); |
1142 | return 0; | 1142 | return 0; |
1143 | } | 1143 | } |
1144 | 1144 | ||
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index db2f04415927..08744b572af6 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -526,6 +526,21 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) | |||
526 | /*------------------------- Resume routines -------------------------*/ | 526 | /*------------------------- Resume routines -------------------------*/ |
527 | 527 | ||
528 | /** | 528 | /** |
529 | * dev_pm_skip_next_resume_phases - Skip next system resume phases for device. | ||
530 | * @dev: Target device. | ||
531 | * | ||
532 | * Make the core skip the "early resume" and "resume" phases for @dev. | ||
533 | * | ||
534 | * This function can be called by middle-layer code during the "noirq" phase of | ||
535 | * system resume if necessary, but not by device drivers. | ||
536 | */ | ||
537 | void dev_pm_skip_next_resume_phases(struct device *dev) | ||
538 | { | ||
539 | dev->power.is_late_suspended = false; | ||
540 | dev->power.is_suspended = false; | ||
541 | } | ||
542 | |||
543 | /** | ||
529 | * device_resume_noirq - Execute a "noirq resume" callback for given device. | 544 | * device_resume_noirq - Execute a "noirq resume" callback for given device. |
530 | * @dev: Device to handle. | 545 | * @dev: Device to handle. |
531 | * @state: PM transition of the system being carried out. | 546 | * @state: PM transition of the system being carried out. |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 7f47bb72bf30..945099d49f8f 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -999,7 +999,7 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
999 | * the subsequent "thaw" callbacks for the device. | 999 | * the subsequent "thaw" callbacks for the device. |
1000 | */ | 1000 | */ |
1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { | 1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { |
1002 | dev->power.direct_complete = true; | 1002 | dev_pm_skip_next_resume_phases(dev); |
1003 | return 0; | 1003 | return 0; |
1004 | } | 1004 | } |
1005 | 1005 | ||