diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-05-18 22:51:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-07-02 16:32:00 -0700 |
commit | 6b188e72edf2e40a1ba972e31694d5d10b91dbb0 (patch) | |
tree | dc7495b9010097309c0c6d04e15fb0c8d2b1dfe8 | |
parent | fe9238fb7cac760494e50c0a7d52a91cf4d865b7 (diff) |
PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
commit f62795f1e892ca9269849fa83de97621da7e02c0 upstream.
According to the PCI PM specification (PCI Bus Power Management
Interface Specification, Rev. 1.2, Section 5.4.1) we are supposed to
reinitialize devices that have PCI_PM_CTRL_NO_SOFT_RESET clear during
all transitions from PCI_D3hot to PCI_D0, but we only do it if the
device's current_state field is equal to PCI_UNKNOWN.
This may lead to problems if a device with PCI_PM_CTRL_NO_SOFT_RESET
unset is put into PCI_D3hot at run time by its driver and
pci_set_power_state() is used to put it back into PCI_D0, because in
that case the device will remain uninitialized after
pci_set_power_state() has returned. Prevent that from happening by
modifying pci_raw_set_power_state() to reinitialize devices with
PCI_PM_CTRL_NO_SOFT_RESET unset during all transitions from D3 to D0.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/pci/pci.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 482fee46d3d1..33cc1487b1e7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -473,6 +473,8 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= state; break; + case PCI_D3hot: + case PCI_D3cold: case PCI_UNKNOWN: /* Boot-up */ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) |