Thread (35 messages) 35 messages, 5 authors, 6h ago

Re: [PATCH net 07/10] net: pse-pd: pd692x0: release the manager power budget through devres

flat view

From: Kory Maincent <kory.maincent@bootlin.com>
Date: 2026-10-19 12:46:04
Also in: lkml


On 10/18/26 10:23, Carlo Szelinsky wrote:
pd692x0 reserves a power budget on each manager's supply in
setup_pi_matrix(), but gives it back only on that function's own errors
and in remove(). If probe fails later, or the request fails for one
manager after others succeeded, the budget stays reserved on vmain. Each
probe retry, e.g. after -EPROBE_DEFER, reserves it again until nothing
is left.

Release the budget from a devm action instead, and drop the explicit
release calls.
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>

Thank you!
quoted hunk ↗ jump to hunk
Fixes: 1c67f9c54cdc ("net: pse-pd: pd692x0: Fix power budget leak in manager setup error path")
Signed-off-by: Carlo Szelinsky <redacted>
---
  drivers/net/pse-pd/pd692x0.c | 22 +++++++++++++++-------
  1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 209de9cec849..34f0dfbccd06 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -1224,8 +1224,9 @@ static void pd692x0_of_put_managers(struct pd692x0_priv *priv,
  	}
  }
  
-static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
+static void pd692x0_managers_free_pw_budget(void *data)
  {
+	struct pd692x0_priv *priv = data;
  	int i;
  
  	for (i = 0; i < PD692X0_MAX_MANAGERS; i++) {
@@ -1279,31 +1280,39 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
  	if (ret)
  		goto err_of_managers;
  
+	/* Frees whatever pd692x0_req_managers_pw_budget() manages to
+	 * request, on any later probe failure and on unbind. Added after
+	 * the manager regulators so that it runs before devres unregisters
+	 * them and their supply goes away.
+	 */
+	ret = devm_add_action_or_reset(&priv->client->dev,
+				       pd692x0_managers_free_pw_budget, priv);
+	if (ret)
+		goto err_of_managers;
+
  	ret = pd692x0_req_managers_pw_budget(priv);
  	if (ret)
  		goto err_of_managers;
  
  	ret = pd692x0_set_ports_matrix(priv, manager);
  	if (ret)
-		goto err_managers_req_pw;
+		goto err_of_managers;
  
  	/* Do not init the conf if it is already saved */
  	if (!priv->cfg_saved) {
  		ret = pd692x0_hw_conf_init(priv);
  		if (ret)
-			goto err_managers_req_pw;
+			goto err_of_managers;
  
  		ret = pd692x0_save_user_byte(priv);
  		if (ret)
-			goto err_managers_req_pw;
+			goto err_of_managers;
  	}
  
  	pd692x0_of_put_managers(priv, manager);
  	kfree(manager);
  	return 0;
  
-err_managers_req_pw:
-	pd692x0_managers_free_pw_budget(priv);
  err_of_managers:
  	pd692x0_of_put_managers(priv, manager);
  err_free_manager:
@@ -1855,7 +1864,6 @@ static void pd692x0_i2c_remove(struct i2c_client *client)
  {
  	struct pd692x0_priv *priv = i2c_get_clientdata(client);
  
-	pd692x0_managers_free_pw_budget(priv);
  	firmware_upload_unregister(priv->fwl);
  }
  
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help