linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PCI/PM: Target PM state is D3cold if the upstream bridge is power manageable
@ 2021-05-10 10:26 Mika Westerberg
  2021-05-17 22:33 ` Rajat Jain
  2021-05-25 23:36 ` Bjorn Helgaas
  0 siblings, 2 replies; 6+ messages in thread
From: Mika Westerberg @ 2021-05-10 10:26 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki
  Cc: Utkarsh H Patel, Koba Ko, Mika Westerberg, linux-pci

ASMedia xHCI controller only supports PME from D3cold:

11:00.0 USB controller: ASMedia Technology Inc. ASM1042A USB 3.0 Host Controller (prog-if 30 [XHCI])
  ...
  Capabilities: [78] Power Management version 3
  	  Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0-,D1-,D2-,D3hot-,D3cold+)
	  Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-

Now, if the controller is part of a Thunderbolt device for instance, it
is connected to a PCIe switch downstream port. When the hierarchy then
enters D3cold as a result of s2idle cycle pci_target_state() returns D0
because the device does not support PME from the default target_state
(D3hot). So what happens is that the whole hierarchy is left into D0
breaking power management.

For this reason choose target_state to be D3cold if there is a upstream
bridge that is power manageable. The reasoning here is that the upstream
bridge will be also placed into D3 making the effective power state of
the device in question to be D3cold.

Reported-by: Utkarsh H Patel <utkarsh.h.patel@intel.com>
Reported-by: Koba Ko <koba.ko@canonical.com>
Tested-by: Koba Ko <koba.ko@canonical.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/pci/pci.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b717680377a9..e3f3b9010762 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2578,8 +2578,19 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)
 		return target_state;
 	}
 
-	if (!dev->pm_cap)
+	if (!dev->pm_cap) {
 		target_state = PCI_D0;
+	} else {
+		struct pci_dev *bridge;
+
+		/*
+		 * If the upstream bridge can be put to D3 then it means
+		 * that our target state is D3cold instead of D3hot.
+		 */
+		bridge = pci_upstream_bridge(dev);
+		if (bridge && pci_bridge_d3_possible(bridge))
+			target_state = PCI_D3cold;
+	}
 
 	/*
 	 * If the device is in D3cold even though it's not power-manageable by
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-05-26 10:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-10 10:26 [PATCH] PCI/PM: Target PM state is D3cold if the upstream bridge is power manageable Mika Westerberg
2021-05-17 22:33 ` Rajat Jain
2021-05-18 10:44   ` Mika Westerberg
2021-05-18 11:00     ` Kai-Heng Feng
2021-05-25 23:36 ` Bjorn Helgaas
2021-05-26 10:42   ` Mika Westerberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).