forked from mirrors/linux
		
	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: c4b65157ae (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>
			
			
This commit is contained in:
		
							parent
							
								
									6d08b06e67
								
							
						
					
					
						commit
						ae860a19f3
					
				
					 1 changed files with 3 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -958,10 +958,11 @@ static int pci_pm_freeze(struct device *dev)
 | 
			
		|||
	 * devices should not be touched during freeze/thaw transitions,
 | 
			
		||||
	 * however.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND))
 | 
			
		||||
	if (!dev_pm_smart_suspend_and_suspended(dev)) {
 | 
			
		||||
		pm_runtime_resume(dev);
 | 
			
		||||
		pci_dev->state_saved = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pci_dev->state_saved = false;
 | 
			
		||||
	if (pm->freeze) {
 | 
			
		||||
		int error;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue