Skip to content

Commit ae860a1

Browse files
westerirafaeljw
authored andcommitted
PCI / PM: Do not clear state_saved in pci_pm_freeze() when smart suspend is set
If a driver uses DPM_FLAG_SMART_SUSPEND and the device is already runtime suspended when hibernate is started PCI core skips runtime resuming the device but still clears pci_dev->state_saved. After the hibernation image is written pci_pm_thaw_noirq() makes sure subsequent thaw phases for the device are also skipped leaving it runtime suspended with pci_dev->state_saved == false. When the device is eventually runtime resumed pci_pm_runtime_resume() restores config space by calling pci_restore_standard_config(), however because pci_dev->state_saved == false pci_restore_state() never actually restores the config space leaving the device in a state that is not what the driver might expect. For example here is what happens for intel-lpss I2C devices once the hibernation snapshot is taken: intel-lpss 0000:00:15.0: power state changed by ACPI to D0 intel-lpss 0000:00:1e.0: power state changed by ACPI to D3cold video LNXVIDEO:00: Restoring backlight state PM: hibernation exit i2c_designware i2c_designware.1: Unknown Synopsys component type: 0xffffffff i2c_designware i2c_designware.0: Unknown Synopsys component type: 0xffffffff i2c_designware i2c_designware.1: timeout in disabling adapter i2c_designware i2c_designware.0: timeout in disabling adapter Since PCI config space is not restored the device is still in D3hot making MMIO register reads return 0xffffffff. Fix this by clearing pci_dev->state_saved only if we actually end up runtime resuming the device. Fixes: c4b6515 (PCI / PM: Take SMART_SUSPEND driver flag into account) Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Cc: 4.15+ <stable@vger.kernel.org> # 4.15+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 6d08b06 commit ae860a1

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/pci/pci-driver.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -958,10 +958,11 @@ static int pci_pm_freeze(struct device *dev)
958958
* devices should not be touched during freeze/thaw transitions,
959959
* however.
960960
*/
961-
if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND))
961+
if (!dev_pm_smart_suspend_and_suspended(dev)) {
962962
pm_runtime_resume(dev);
963+
pci_dev->state_saved = false;
964+
}
963965

964-
pci_dev->state_saved = false;
965966
if (pm->freeze) {
966967
int error;
967968

0 commit comments

Comments
 (0)