Skip to content

Commit 1c67f9c

Browse files
kmaincentkuba-moo
authored andcommitted
net: pse-pd: pd692x0: Fix power budget leak in manager setup error path
Fix a resource leak where manager power budgets were freed on both success and error paths during manager setup. Power budgets should only be freed on error paths after regulator registration or during driver removal. Refactor cleanup logic by extracting OF node cleanup and power budget freeing into separate helper functions for better maintainability. Fixes: 3597540 ("net: pse-pd: pd692x0: Add support for PSE PI priority feature") Signed-off-by: Kory Maincent <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8c5d959 commit 1c67f9c

File tree

1 file changed

+44
-15
lines changed

1 file changed

+44
-15
lines changed

drivers/net/pse-pd/pd692x0.c

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,12 +1162,44 @@ pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
11621162
return 0;
11631163
}
11641164

1165+
static void pd692x0_of_put_managers(struct pd692x0_priv *priv,
1166+
struct pd692x0_manager *manager,
1167+
int nmanagers)
1168+
{
1169+
int i, j;
1170+
1171+
for (i = 0; i < nmanagers; i++) {
1172+
for (j = 0; j < manager[i].nports; j++)
1173+
of_node_put(manager[i].port_node[j]);
1174+
of_node_put(manager[i].node);
1175+
}
1176+
}
1177+
1178+
static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
1179+
{
1180+
int i;
1181+
1182+
for (i = 0; i < PD692X0_MAX_MANAGERS; i++) {
1183+
struct regulator *supply;
1184+
1185+
if (!priv->manager_reg[i] || !priv->manager_pw_budget[i])
1186+
continue;
1187+
1188+
supply = priv->manager_reg[i]->supply;
1189+
if (!supply)
1190+
continue;
1191+
1192+
regulator_free_power_budget(supply,
1193+
priv->manager_pw_budget[i]);
1194+
}
1195+
}
1196+
11651197
static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
11661198
{
11671199
struct pd692x0_manager *manager __free(kfree) = NULL;
11681200
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
11691201
struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
1170-
int ret, i, j, nmanagers;
1202+
int ret, nmanagers;
11711203

11721204
/* Should we flash the port matrix */
11731205
if (priv->fw_state != PD692X0_FW_OK &&
@@ -1185,31 +1217,27 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
11851217
nmanagers = ret;
11861218
ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
11871219
if (ret)
1188-
goto out;
1220+
goto err_of_managers;
11891221

11901222
ret = pd692x0_configure_managers(priv, nmanagers);
11911223
if (ret)
1192-
goto out;
1224+
goto err_of_managers;
11931225

11941226
ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
11951227
if (ret)
1196-
goto out;
1228+
goto err_managers_req_pw;
11971229

11981230
ret = pd692x0_write_ports_matrix(priv, port_matrix);
11991231
if (ret)
1200-
goto out;
1232+
goto err_managers_req_pw;
12011233

1202-
out:
1203-
for (i = 0; i < nmanagers; i++) {
1204-
struct regulator *supply = priv->manager_reg[i]->supply;
1205-
1206-
regulator_free_power_budget(supply,
1207-
priv->manager_pw_budget[i]);
1234+
pd692x0_of_put_managers(priv, manager, nmanagers);
1235+
return 0;
12081236

1209-
for (j = 0; j < manager[i].nports; j++)
1210-
of_node_put(manager[i].port_node[j]);
1211-
of_node_put(manager[i].node);
1212-
}
1237+
err_managers_req_pw:
1238+
pd692x0_managers_free_pw_budget(priv);
1239+
err_of_managers:
1240+
pd692x0_of_put_managers(priv, manager, nmanagers);
12131241
return ret;
12141242
}
12151243

@@ -1748,6 +1776,7 @@ static void pd692x0_i2c_remove(struct i2c_client *client)
17481776
{
17491777
struct pd692x0_priv *priv = i2c_get_clientdata(client);
17501778

1779+
pd692x0_managers_free_pw_budget(priv);
17511780
firmware_upload_unregister(priv->fwl);
17521781
}
17531782

0 commit comments

Comments
 (0)