On Sun, 17 May 2009 20:17:06 +0200 "Rafael J. Wysocki" <rjw@xxxxxxx> wrote: > From: Rafael J. Wysocki <rjw@xxxxxxx> > > Recent PCI PM changes introduced a bug that causes some devices to be > mishandled after kexec and during early initialization. The failure > scenario in the kexec case is the following: > > * Assume a PCI device is not power-manageable by the platform and has > PCI_PM_CTRL_NO_SOFT_RESET set in PMCSR. > * The device is put into D3 before kexec (using the native PCI PM). > * After kexec, pci_setup_device() sets the device's power state to > PCI_UNKNOWN. > * pci_set_power_state(dev, PCI_D0) is called by the device's driver. > * __pci_start_power_transition(dev, PCI_D0) is called and since the > device is not power-manageable by the platform, it causes > pci_update_current_state(dev, PCI_D0) to be called. As a result > the device's current_state field is updated to PCI_D3, in > accordance with the contents of its PCI PM registers. > * pci_raw_set_power_state() is called and it changes the device power > state to D0. *However*, it should also call pci_restore_bars() to > reinitialize the device, but it doesn't, because the device's > current_state field has been modified earlier. > > To prevent this from happening, modify > pci_platform_power_transition() so that it doesn't use > pci_update_current_state() to update the current_state field for > devices that aren't power-manageable by the platform. Instead, this > field should be updated directly for devices that don't support the > native PCI PM. > > Signed-off-by: Rafael J. Wysocki <rjw@xxxxxxx> > --- > drivers/pci/pci.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > Index: linux-2.6/drivers/pci/pci.c > =================================================================== > --- linux-2.6.orig/drivers/pci/pci.c > +++ linux-2.6/drivers/pci/pci.c > @@ -557,7 +557,8 @@ static int pci_platform_power_transition > } else { > error = -ENODEV; > /* Fall back to PCI_D0 if native PM is not supported > */ > - pci_update_current_state(dev, PCI_D0); > + if (!dev->pm_cap) > + dev->current_state = PCI_D0; > } > > return error; > Applied to my for-linus branch, thanks Rafael. -- Jesse Barnes, Intel Open Source Technology Center _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm