diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-23 18:40:55 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-23 18:40:55 +0200 |
commit | 7266f2030eb0e17c442aa6cf527263828eed79bd (patch) | |
tree | 48dc945416c7b76c9085e720920c10798d3617f4 | |
parent | Merge branch 'stable/for-linus-5.14' of git://git.kernel.org/pub/scm/linux/ke... (diff) | |
parent | Revert "PCI: PM: Do not read power state in pci_enable_device_flags()" (diff) | |
download | linux-7266f2030eb0e17c442aa6cf527263828eed79bd.tar.xz linux-7266f2030eb0e17c442aa6cf527263828eed79bd.zip |
Merge tag 'pm-5.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fix from Rafael Wysocki:
"Revert a recent PCI power management commit that causes initialization
issues to appear on some systems"
* tag 'pm-5.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Revert "PCI: PM: Do not read power state in pci_enable_device_flags()"
-rw-r--r-- | drivers/pci/pci.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b717680377a9..8d4ebe095d0c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1900,11 +1900,21 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) int err; int i, bars = 0; - if (atomic_inc_return(&dev->enable_cnt) > 1) { - pci_update_current_state(dev, dev->current_state); - return 0; /* already enabled */ + /* + * Power state could be unknown at this point, either due to a fresh + * boot or a device removal call. So get the current power state + * so that things like MSI message writing will behave as expected + * (e.g. if the device really is in D0 at enable time). + */ + if (dev->pm_cap) { + u16 pmcsr; + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); + dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } + if (atomic_inc_return(&dev->enable_cnt) > 1) + return 0; /* already enabled */ + bridge = pci_upstream_bridge(dev); if (bridge) pci_enable_bridge(bridge); |