提交 2449e06a 编写于 作者: S Shaohua Li 提交者: Greg Kroah-Hartman

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: NShaohua Li <shaohua.li@intel.com>
Cc: Patrick Mochel <mochel@digitalimplant.org>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 3095fc0c
...@@ -264,6 +264,13 @@ static int pci_device_remove(struct device * dev) ...@@ -264,6 +264,13 @@ static int pci_device_remove(struct device * dev)
pci_dev->driver = NULL; 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 * We would love to complain here if pci_dev->is_enabled is set, that
* the driver should have called pci_disable_device(), but the * 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) ...@@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
suspend_report_result(drv->suspend, i); suspend_report_result(drv->suspend, i);
} else { } else {
pci_save_state(pci_dev); 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; return i;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册