PCI: Make pci_wakeup_bus() & pci_bus_set_current_state() public
authorLukas Wunner <lukas@wunner.de>
Sat, 3 Mar 2018 09:53:24 +0000 (10:53 +0100)
committerLukas Wunner <lukas@wunner.de>
Tue, 13 Mar 2018 21:57:36 +0000 (22:57 +0100)
commit2a4d2c4240c00e7db8fb64e377bd2180cc30b146
treec80c6defabd47e9bd4894a8c753f0179314b03ba
parent5775b843a619b3c93f946e2b55a208d9f0f48b59
PCI: Make pci_wakeup_bus() & pci_bus_set_current_state() public

There are PCI devices which are power-manageable by a nonstandard means,
such as a custom ACPI method.  One example are discrete GPUs in hybrid
graphics laptops, another are Thunderbolt controllers in Macs.

Such devices can't be put into D3cold with pci_set_power_state() because
pci_platform_power_transition() fails with -ENODEV.  Instead they're put
into D3hot by pci_set_power_state() and subsequently into D3cold by
invoking the nonstandard means.  However as a consequence the cached
current_state is incorrectly left at D3hot.

What we need to do is walk the hierarchy below such a PCI device on
powerdown and update the current_state to D3cold.  On powerup the PCI
device itself and the hierarchy below it is in D0uninitialized, so we
need to walk the hierarchy again and wake all devices, causing them to
be put into D0active and then letting them autosuspend as they see fit.

To this end make pci_wakeup_bus() & pci_bus_set_current_state() public
so PCI drivers don't have to reinvent the wheel.

Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://patchwork.freedesktop.org/patch/msgid/2962443259e7faec577274b4ef8c54aad66f9a94.1520068884.git.lukas@wunner.de
drivers/pci/pci.c
include/linux/pci.h