eb2c8b7489
Changes:
- Rebase onto v5.14.5
Links:
- kernel: 9c1bdc17bb
51 lines
2 KiB
Diff
51 lines
2 KiB
Diff
From 18ee50b7f5cb1d1a89bf3de78965c4123c0e051a Mon Sep 17 00:00:00 2001
|
|
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
|
|
Date: Thu, 8 Jul 2021 15:25:06 +0200
|
|
Subject: [PATCH] PCI: Use pci_update_current_state() in
|
|
pci_enable_device_flags()
|
|
|
|
Updating the current_state field of struct pci_dev the way it is done
|
|
in pci_enable_device_flags() before calling do_pci_enable_device() may
|
|
not work. For example, if the given PCI device depends on an ACPI
|
|
power resource whose _STA method initially returns 0 ("off"), but the
|
|
config space of the PCI device is accessible and the power state
|
|
retrieved from the PCI_PM_CTRL register is D0, the current_state
|
|
field in the struct pci_dev representing that device will get out of
|
|
sync with the power.state of its ACPI companion object and that will
|
|
lead to power management issues going forward.
|
|
|
|
To avoid such issues, make pci_enable_device_flags() call
|
|
pci_update_current_state() which takes ACPI device power management
|
|
into account, if present, to retrieve the current power state of the
|
|
device.
|
|
|
|
Link: https://lore.kernel.org/lkml/20210314000439.3138941-1-luzmaximilian@gmail.com/
|
|
Reported-by: Maximilian Luz <luzmaximilian@gmail.com>
|
|
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
|
Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
|
|
Patchset: surface-hotplug
|
|
---
|
|
drivers/pci/pci.c | 6 +-----
|
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
|
|
index 3f353572588d..a5e6759c407b 100644
|
|
--- a/drivers/pci/pci.c
|
|
+++ b/drivers/pci/pci.c
|
|
@@ -1906,11 +1906,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
|
|
* 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);
|
|
- }
|
|
+ pci_update_current_state(dev, dev->current_state);
|
|
|
|
if (atomic_inc_return(&dev->enable_cnt) > 1)
|
|
return 0; /* already enabled */
|
|
--
|
|
2.33.0
|
|
|