Commit 5694ba1
PCI/PM: Only read PCI_PM_CTRL register when available
For a device with no Power Management Capability, pci_power_up() previously
returned 0 (success) if the platform was able to put the device in D0,
which led to pci_set_full_power_state() trying to read PCI_PM_CTRL, even
though it doesn't exist.
Since dev->pm_cap == 0 in this case, pci_set_full_power_state() actually
read the wrong register, interpreted it as PCI_PM_CTRL, and corrupted
dev->current_state. This led to messages like this in some cases:
pci 0000:01:00.0: Refused to change power state from D3hot to D0
To prevent this, make pci_power_up() always return a negative failure code
if the device lacks a Power Management Capability, even if non-PCI platform
power management has been able to put the device in D0. The failure will
prevent pci_set_full_power_state() from trying to access PCI_PM_CTRL.
Fixes: e200904 ("PCI/PM: Split pci_power_up()")
Link: https://lore.kernel.org/r/20230824013738.1894965-1-chenfeiyang@loongson.cn
Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: stable@vger.kernel.org # v5.19+1 parent 06c2afb commit 5694ba1
1 file changed
Lines changed: 9 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1226 | 1226 | | |
1227 | 1227 | | |
1228 | 1228 | | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
1229 | 1233 | | |
1230 | 1234 | | |
1231 | 1235 | | |
| |||
1242 | 1246 | | |
1243 | 1247 | | |
1244 | 1248 | | |
1245 | | - | |
1246 | | - | |
1247 | | - | |
1248 | 1249 | | |
1249 | 1250 | | |
1250 | 1251 | | |
| |||
1302 | 1303 | | |
1303 | 1304 | | |
1304 | 1305 | | |
1305 | | - | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
1306 | 1310 | | |
| 1311 | + | |
1307 | 1312 | | |
1308 | 1313 | | |
1309 | 1314 | | |
| |||
0 commit comments