Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH] PCI/pwrctrl: Power off child devices on power-on failure
@ 2026-09-09 15:28 Lorenzo Bianconi
  2026-09-09 15:32 ` sashiko-bot
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lorenzo Bianconi @ 2026-09-09 15:28 UTC (permalink / raw)
  To: Bartosz Golaszewski, Manivannan Sadhasivam, Bjorn Helgaas,
	Krishna Chaitanya Chundru
  Cc: Manivannan Sadhasivam, linux-pci, Lorenzo Bianconi

pci_pwrctrl_power_on_device() recursively powers on the child nodes
of a device before powering on the device itself. If powering on a
child fails (e.g. returning -EPROBE_DEFER), the function returned
immediately, leaving the sibling children that were already powered
on in the same loop iteration enabled.

Since probe deferral is a standard boot path, this leads to unbounded
regulator and clock enable increments across retries. The error path
in pci_pwrctrl_power_on_devices() only powers off the top-level
children processed before the failing one and explicitly stops at it,
so it can never clean up the siblings leaked deeper in the failed
subtree.

Power off the sibling children that were successfully powered on
before a child fails, and power off all children if the device's own
power_on() fails after its children were already enabled. Switch to a
manual child iterator so the failing node can be tracked and its
reference released in the error path.

Fixes: b35cf3b6aa1e ("PCI/pwrctrl: Add APIs to power on/off pwrctrl devices")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 drivers/pci/pwrctrl/core.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
index 10d817aefb09..d29cd506972d 100644
--- a/drivers/pci/pwrctrl/core.c
+++ b/drivers/pci/pwrctrl/core.c
@@ -252,14 +252,16 @@ static int __pci_pwrctrl_power_on_device(struct device *dev)
 static int pci_pwrctrl_power_on_device(struct device_node *np)
 {
 	struct platform_device *pdev;
+	struct device_node *child;
 	int ret = 0;
 
-	for_each_available_child_of_node_scoped(np, child) {
+	for_each_available_child_of_node(np, child) {
 		ret = pci_pwrctrl_power_on_device(child);
 		if (ret)
-			return ret;
+			goto err_power_off;
 	}
 
+	child = NULL;
 	if (!pci_pwrctrl_is_required(np))
 		return 0;
 
@@ -279,6 +281,19 @@ static int pci_pwrctrl_power_on_device(struct device_node *np)
 
 	platform_device_put(pdev);
 
+	if (ret)
+		goto err_power_off;
+
+	return 0;
+
+err_power_off:
+	for_each_available_child_of_node_scoped(np, tmp) {
+		if (tmp == child)
+			break;
+		pci_pwrctrl_power_off_device(tmp);
+	}
+	of_node_put(child);
+
 	return ret;
 }
 

---
base-commit: 028f86457e822ab9de5b0d6d23efddc1b8b54ae1
change-id: 20260908-pwrtctl-power-on-rallback-5c6364b080ce

Best regards,
-- 
Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>


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

end of thread, other threads:[~2026-09-10  7:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 15:28 [PATCH] PCI/pwrctrl: Power off child devices on power-on failure Lorenzo Bianconi
2026-09-09 15:32 ` sashiko-bot
2026-09-10  7:06 ` Manivannan Sadhasivam
2026-09-10  7:22 ` Bartosz Golaszewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox