In Windows, systems that support Modern Standby specify hardware pre-conditions for the SoC to be able to achieve the lowest power state by using 'device constraints' in a SOC specific "Power Engine Plugin" (PEP) [1] [2]. For each device, the constraint is the minimum (shallowest) power state in which the device can be for the platform to be still able to achieve significant energy conservation in a system-wide low-power idle configuration. Device constraints are specified in the return value for a _DSM of a PNP0D80 device, and Linux enumerates the constraints during probing. For PCI bridges (including PCIe ports), the constraints may be regarded as an additional source of information regarding the power state to put the device into when it is suspended. In particular, if the constraint for a given PCI bridge is D3hot, the platform regards D3hot as a valid power state for the bridge and it is reasonable to expect that there won't be any side effects caused by putting the bridge into that power state. Accordingly, take the low-power S0 idle (LPS0) constraints into account when deciding whether or not to allow a given PCI bridge to be put into D3. Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/platform-design-for-modern-standby#low-power-core-silicon-cpu-soc-dram [1] Link: https://uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf [2] Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- v13->v14: * Move code as another way to satisfy acpi_pci_bridge_d3() instead * Update commit with Rafael's suggestions v12->v13: * Move back to PCI code * Trim commit message v11->v12: * Adjust for dropped patch 8/9 from v11. * Update comment v10->v11: * Fix kernel kernel build robot errors and various sparse warnings related to new handling of pci_power_t. * Use the new helpers introduced in previous patches --- drivers/pci/pci-acpi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 64e6ada024235..8331aea22d327 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -1022,6 +1022,15 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev) adev = ACPI_COMPANION(&dev->dev); if (adev) { + int acpi_state; + + /* Check if the platform specifies an LPS0 constraint of D3. */ + acpi_state = acpi_get_lps0_constraint(adev); + pci_dbg(dev, "LPS0 constraint: %d\n", acpi_state); + if (acpi_state != ACPI_STATE_UNKNOWN && + acpi_state >= ACPI_STATE_D3_HOT) + return true; + /* * If the bridge has _S0W, whether or not it can go into D3 * depends on what is returned by that object. In particular, -- 2.34.1