PCI: reset pci device state to unknown state for resume
Considering below scenario: 1.Unload a PCI device's driver, the device ->current remains in PCI_D0. 2.Do suspend/resume circle. After that, BIOS puts the device to D3. 3.Reload the device driver. The calling pci_set_power_state in the driver can't change the state to D0, as set_power_state thinks the device is already in D0. A bug is reported at http://bugzilla.kernel.org/show_bug.cgi?id=6024 Pat attached a patch at http://marc.theaimsgroup.com/?l=linux-pci&m=114049761428561&w=2 for this issue, but it's lost. As pci_set_power_state can handle D3 -> D0 correctly (restore config space), I simplified Patrick's patch. Signed-off-by: Shaohua Li <shaohua.li@intel.com> Cc: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
3095fc0c97
commit
2449e06a56
1 changed files with 13 additions and 0 deletions
|
@ -264,6 +264,13 @@ static int pci_device_remove(struct device * dev)
|
|||
pci_dev->driver = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is still on, set the power state as "unknown",
|
||||
* since it might change by the next time we load the driver.
|
||||
*/
|
||||
if (pci_dev->current_state == PCI_D0)
|
||||
pci_dev->current_state = PCI_UNKNOWN;
|
||||
|
||||
/*
|
||||
* We would love to complain here if pci_dev->is_enabled is set, that
|
||||
* the driver should have called pci_disable_device(), but the
|
||||
|
@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
|
|||
suspend_report_result(drv->suspend, i);
|
||||
} else {
|
||||
pci_save_state(pci_dev);
|
||||
/*
|
||||
* mark its power state as "unknown", since we don't know if
|
||||
* e.g. the BIOS will change its device state when we suspend.
|
||||
*/
|
||||
if (pci_dev->current_state == PCI_D0)
|
||||
pci_dev->current_state = PCI_UNKNOWN;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue