• R
    PCI / PM: restore the original behavior of pci_set_power_state() · db288c9c
    Rafael J. Wysocki 提交于
    Commit cc2893b6 (PCI: Ensure we re-enable devices on resume)
    addressed the problem with USB not being powered after resume on
    recent Lenovo machines, but it did that in a suboptimal way.
    Namely, it should have changed the relevant code paths only,
    which are pci_pm_resume_noirq() and pci_pm_restore_noirq() supposed
    to restore the device's power and standard configuration registers
    after system resume from suspend or hibernation.  Instead, however,
    it modified pci_set_power_state() which is executed in several
    other situations too.  That resulted in some undesirable effects,
    like attempting to change a device's power state in the same way
    multiple times in a row (up to as many as 4 times in a row in the
    snd_hda_intel driver).
    
    Fix the bug addressed by commit cc2893b6 in an alternative way,
    by forcibly powering up all devices in pci_pm_default_resume_early(),
    which is called by pci_pm_resume_noirq() and pci_pm_restore_noirq()
    to restore the device's power and standard configuration registers,
    and modifying pci_pm_runtime_resume() to avoid the forcible power-up
    if not necessary.  Then, revert the changes made by commit cc2893b6
    to make the confusion introduced by it go away.
    Acked-by: NMatthew Garrett <mjg@redhat.com>
    Signed-off-by: NRafael J. Wysocki <rjw@sisk.pl>
    Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
    db288c9c
pci-driver.c 31.0 KB