History

Merge tag 'pm-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki: "These fix three issues in the system-wide suspend and hibernation area related to PCI device PM handling by suspend-to-idle, device wakeup optimizations and arbitrary differences between suspend and hiberantion. Specifics: - Modify the PCI bus type's PM code to avoid putting devices left by their drivers in D0 on purpose during suspend to idle into low-power states as doing that may confuse the system resume callbacks of the drivers in question (Rafael Wysocki). - Avoid checking ACPI wakeup configuration during system-wide suspend for suspended devices that do not use ACPI-based wakeup to allow them to stay in suspend more often (Rafael Wysocki). - The last phase of hibernation is analogous to system-wide suspend also because on platforms with ACPI it passes control to the platform firmware to complete the transision, so make it indicate that by calling pm_set_suspend_via_firmware() to allow the drivers that care about this to do the right thing (Rafael Wysocki)" * tag 'pm-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: PCI: PM: Avoid possible suspend-to-idle issue ACPI: PM: Call pm_set_suspend_via_firmware() during hibernation ACPI/PCI: PM: Add missing wakeup.flags.valid checks

Linus Torvalds committed 7 years ago

Commit 702c31e2 parents 72cea7a d491f2b7 files · +48 −22Browse files

Unified · Split

7 files
  1. drivers/acpi/device_pm.c +2 −2
  2. drivers/acpi/sleep.c +24 −15
  3. drivers/pci/pci-acpi.c +2 −1
  4. drivers/pci/pci-driver.c +16 −1
  5. include/linux/pci.h +1 −0
  6. include/linux/suspend.h +1 −1
  7. kernel/power/hibernate.c +2 −2
drivers/acpi/device_pm.c+2−2
@@ -944,8 +944,8 @@ static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev) · 943 unmodified lines
944 u32 sys_target = acpi_target_system_state();944 u32 sys_target = acpi_target_system_state();
945 int ret, state;945 int ret, state;
946 946
947 if (!pm_runtime_suspended(dev) || !adev ||947 if (!pm_runtime_suspended(dev) || !adev || (adev->wakeup.flags.valid &&
948 device_may_wakeup(dev) != !!adev->wakeup.prepare_count)948 device_may_wakeup(dev) != !!adev->wakeup.prepare_count))
949 return true;949 return true;
950 950
951 if (sys_target == ACPI_STATE_S0)951 if (sys_target == ACPI_STATE_S0)
drivers/acpi/sleep.c+24−15
@@ -1132,15 +1132,19 @@ void __init acpi_no_s4_hw_signature(void) · 1131 unmodified lines
1132 nosigcheck = true;1132 nosigcheck = true;
1133}1133}
1134 1134
1135static int acpi_hibernation_begin(void)1135static int acpi_hibernation_begin(pm_message_t stage)
1136{1136{
1137 int error;1137 if (!nvs_nosave) {
1138 int error = suspend_nvs_alloc();
1139 if (error)
1140 return error;
1141 }
1138 1142
1139 error = nvs_nosave ? 0 : suspend_nvs_alloc();1143 if (stage.event == PM_EVENT_HIBERNATE)
1140 if (!error)1144 pm_set_suspend_via_firmware();
1141 acpi_pm_start(ACPI_STATE_S4);
1142 1145
1143 return error;1146 acpi_pm_start(ACPI_STATE_S4);
1147 return 0;
1144}1148}
1145 1149
1146static int acpi_hibernation_enter(void)1150static int acpi_hibernation_enter(void)
@@ -1200,7 +1204,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops = { · 53 unmodified lines
1200 * function is used if the pre-ACPI 2.0 suspend ordering has been1204 * function is used if the pre-ACPI 2.0 suspend ordering has been
1201 * requested.1205 * requested.
1202 */1206 */
1203static int acpi_hibernation_begin_old(void)1207static int acpi_hibernation_begin_old(pm_message_t stage)
1204{1208{
1205 int error;1209 int error;
1206 /*1210 /*
@@ -1211,16 +1215,21 @@ static int acpi_hibernation_begin_old(void) · 4 unmodified lines
1211 acpi_sleep_tts_switch(ACPI_STATE_S4);1215 acpi_sleep_tts_switch(ACPI_STATE_S4);
1212 1216
1213 error = acpi_sleep_prepare(ACPI_STATE_S4);1217 error = acpi_sleep_prepare(ACPI_STATE_S4);
1218 if (error)
1219 return error;
1214 1220
1215 if (!error) {1221 if (!nvs_nosave) {
1216 if (!nvs_nosave)1222 error = suspend_nvs_alloc();
1217 error = suspend_nvs_alloc();1223 if (error)
1218 if (!error) {1224 return error;
1219 acpi_target_sleep_state = ACPI_STATE_S4;
1220 acpi_scan_lock_acquire();
1221 }
1222 }1225 }
1223 return error;1226
1227 if (stage.event == PM_EVENT_HIBERNATE)
1228 pm_set_suspend_via_firmware();
1229
1230 acpi_target_sleep_state = ACPI_STATE_S4;
1231 acpi_scan_lock_acquire();
1232 return 0;
1224}1233}
1225 1234
1226/*1235/*
drivers/pci/pci-acpi.c+2−1
@@ -733,7 +733,8 @@ static bool acpi_pci_need_resume(struct pci_dev *dev) · 732 unmodified lines
733 if (!adev || !acpi_device_power_manageable(adev))733 if (!adev || !acpi_device_power_manageable(adev))
734 return false;734 return false;
735 735
736 if (device_may_wakeup(&dev->dev) != !!adev->wakeup.prepare_count)736 if (adev->wakeup.flags.valid &&
737 device_may_wakeup(&dev->dev) != !!adev->wakeup.prepare_count)
737 return true;738 return true;
738 739
739 if (acpi_target_system_state() == ACPI_STATE_S0)740 if (acpi_target_system_state() == ACPI_STATE_S0)
drivers/pci/pci-driver.c+16−1
@@ -734,6 +734,8 @@ static int pci_pm_suspend(struct device *dev) · 733 unmodified lines
734 struct pci_dev *pci_dev = to_pci_dev(dev);734 struct pci_dev *pci_dev = to_pci_dev(dev);
735 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;735 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
736 736
737 pci_dev->skip_bus_pm = false;
738
737 if (pci_has_legacy_pm_support(pci_dev))739 if (pci_has_legacy_pm_support(pci_dev))
738 return pci_legacy_suspend(dev, PMSG_SUSPEND);740 return pci_legacy_suspend(dev, PMSG_SUSPEND);
739 741
@@ -827,7 +829,20 @@ static int pci_pm_suspend_noirq(struct device *dev) · 87 unmodified lines
827 }829 }
828 }830 }
829 831
830 if (!pci_dev->state_saved) {832 if (pci_dev->skip_bus_pm) {
833 /*
834 * The function is running for the second time in a row without
835 * going through full resume, which is possible only during
836 * suspend-to-idle in a spurious wakeup case. Moreover, the
837 * device was originally left in D0, so its power state should
838 * not be changed here and the device register values saved
839 * originally should be restored on resume again.
840 */
841 pci_dev->state_saved = true;
842 } else if (pci_dev->state_saved) {
843 if (pci_dev->current_state == PCI_D0)
844 pci_dev->skip_bus_pm = true;
845 } else {
831 pci_save_state(pci_dev);846 pci_save_state(pci_dev);
832 if (pci_power_manageable(pci_dev))847 if (pci_power_manageable(pci_dev))
833 pci_prepare_to_sleep(pci_dev);848 pci_prepare_to_sleep(pci_dev);
include/linux/pci.h+1−0
@@ -344,6 +344,7 @@ struct pci_dev { · 343 unmodified lines
344 D3cold, not set for devices344 D3cold, not set for devices
345 powered on/off by the345 powered on/off by the
346 corresponding bridge */346 corresponding bridge */
347 unsigned int skip_bus_pm:1; /* Internal: Skip bus-level PM */
347 unsigned int ignore_hotplug:1; /* Ignore hotplug events */348 unsigned int ignore_hotplug:1; /* Ignore hotplug events */
348 unsigned int hotplug_user_indicators:1; /* SlotCtl indicators349 unsigned int hotplug_user_indicators:1; /* SlotCtl indicators
349 controlled exclusively by350 controlled exclusively by
include/linux/suspend.h+1−1
@@ -359,7 +359,7 @@ extern void mark_free_pages(struct zone *zone); · 358 unmodified lines
359 * platforms which require special recovery actions in that situation.359 * platforms which require special recovery actions in that situation.
360 */360 */
361struct platform_hibernation_ops {361struct platform_hibernation_ops {
362 int (*begin)(void);362 int (*begin)(pm_message_t stage);
363 void (*end)(void);363 void (*end)(void);
364 int (*pre_snapshot)(void);364 int (*pre_snapshot)(void);
365 void (*finish)(void);365 void (*finish)(void);
kernel/power/hibernate.c+2−2
@@ -129,7 +129,7 @@ static int hibernation_test(int level) { return 0; } · 128 unmodified lines
129static int platform_begin(int platform_mode)129static int platform_begin(int platform_mode)
130{130{
131 return (platform_mode && hibernation_ops) ?131 return (platform_mode && hibernation_ops) ?
132 hibernation_ops->begin() : 0;132 hibernation_ops->begin(PMSG_FREEZE) : 0;
133}133}
134 134
135/**135/**
@@ -542,7 +542,7 @@ int hibernation_platform_enter(void) · 406 unmodified lines
542 * hibernation_ops->finish() before saving the image, so we should let542 * hibernation_ops->finish() before saving the image, so we should let
543 * the firmware know that we're going to enter the sleep state after all543 * the firmware know that we're going to enter the sleep state after all
544 */544 */
545 error = hibernation_ops->begin();545 error = hibernation_ops->begin(PMSG_HIBERNATE);
546 if (error)546 if (error)
547 goto Close;547 goto Close;
548 548