From: Rafael J. Wysocki <rjw@xxxxxxx> The story in http://bugzilla.kernel.org/show_bug.cgi?id=12846 shows that setting the power state of a PCI device by pci_raw_set_power_state() may sometimes fail. For this reason, pci_raw_set_power_state() should not assume that the power state of the device has actually changed after writing into its PMCSR. Instead, it should read the value from there and use it to update dev->current_state. It also is useful to print a warning if the device's power state hasn't changed as expected. Signed-off-by: Rafael J. Wysocki <rjw@xxxxxxx> --- drivers/pci/pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) Index: linux-2.6/drivers/pci/pci.c =================================================================== --- linux-2.6.orig/drivers/pci/pci.c +++ linux-2.6/drivers/pci/pci.c @@ -436,7 +436,7 @@ static inline int platform_pci_sleep_wak */ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) { - u16 pmcsr; + u16 pmcsr, new_pmcsr; bool need_restore = false; /* Check if we're already there */ @@ -498,7 +498,15 @@ static int pci_raw_set_power_state(struc else if (state == PCI_D2 || dev->current_state == PCI_D2) udelay(PCI_PM_D2_DELAY); - dev->current_state = state; + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &new_pmcsr); + if (new_pmcsr == pmcsr) { + dev->current_state = state; + } else { + dev->current_state = (new_pmcsr & PCI_PM_CTRL_STATE_MASK); + dev_warn(&dev->dev, + "failed to set power state to D%d, is D%d\n", state, + dev->current_state); + } /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm