Skip to content

Commit 6fa1f8b

Browse files
kmaincentkuba-moo
authored andcommitted
net: pse-pd: pd692x0: Separate configuration parsing from hardware setup
Cache the port matrix configuration in driver private data to enable PSE controller reconfiguration. This refactoring separates device tree parsing from hardware configuration application, allowing settings to be reapplied without reparsing the device tree. This refactoring is a prerequisite for preserving PSE configuration across reboots to prevent power disruption to connected devices. Signed-off-by: Kory Maincent <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://patch.msgid.link/20251013-feature_pd692x0_reboot_keep_conf-v2-2-68ab082a93dd@bootlin.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f197902 commit 6fa1f8b

File tree

1 file changed

+76
-39
lines changed

1 file changed

+76
-39
lines changed

drivers/net/pse-pd/pd692x0.c

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ enum {
8585
PD692X0_MSG_CNT
8686
};
8787

88+
struct pd692x0_matrix {
89+
u8 hw_port_a;
90+
u8 hw_port_b;
91+
};
92+
8893
struct pd692x0_priv {
8994
struct i2c_client *client;
9095
struct pse_controller_dev pcdev;
@@ -101,6 +106,8 @@ struct pd692x0_priv {
101106
enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
102107
struct regulator_dev *manager_reg[PD692X0_MAX_MANAGERS];
103108
int manager_pw_budget[PD692X0_MAX_MANAGERS];
109+
int nmanagers;
110+
struct pd692x0_matrix *port_matrix;
104111
};
105112

106113
/* Template list of communication messages. The non-null bytes defined here
@@ -809,11 +816,6 @@ struct pd692x0_manager {
809816
int nports;
810817
};
811818

812-
struct pd692x0_matrix {
813-
u8 hw_port_a;
814-
u8 hw_port_b;
815-
};
816-
817819
static int
818820
pd692x0_of_get_ports_manager(struct pd692x0_priv *priv,
819821
struct pd692x0_manager *manager,
@@ -903,7 +905,8 @@ pd692x0_of_get_managers(struct pd692x0_priv *priv,
903905
}
904906

905907
of_node_put(managers_node);
906-
return nmanagers;
908+
priv->nmanagers = nmanagers;
909+
return 0;
907910

908911
out:
909912
for (i = 0; i < nmanagers; i++) {
@@ -963,8 +966,7 @@ pd692x0_register_manager_regulator(struct device *dev, char *reg_name,
963966

964967
static int
965968
pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
966-
const struct pd692x0_manager *manager,
967-
int nmanagers)
969+
const struct pd692x0_manager *manager)
968970
{
969971
struct device *dev = &priv->client->dev;
970972
size_t reg_name_len;
@@ -975,7 +977,7 @@ pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
975977
*/
976978
reg_name_len = strlen(dev_name(dev)) + 23;
977979

978-
for (i = 0; i < nmanagers; i++) {
980+
for (i = 0; i < priv->nmanagers; i++) {
979981
static const char * const regulators[] = { "vaux5", "vaux3p3" };
980982
struct regulator_dev *rdev;
981983
char *reg_name;
@@ -1008,10 +1010,14 @@ pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
10081010
}
10091011

10101012
static int
1011-
pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id, int pw)
1013+
pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id)
10121014
{
10131015
struct pd692x0_msg msg, buf;
1014-
int ret, pw_mW = pw / 1000;
1016+
int ret, pw_mW;
1017+
1018+
pw_mW = priv->manager_pw_budget[id] / 1000;
1019+
if (!pw_mW)
1020+
return 0;
10151021

10161022
msg = pd692x0_msg_template_list[PD692X0_MSG_GET_POWER_BANK];
10171023
msg.data[0] = id;
@@ -1032,11 +1038,11 @@ pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id, int pw)
10321038
}
10331039

10341040
static int
1035-
pd692x0_configure_managers(struct pd692x0_priv *priv, int nmanagers)
1041+
pd692x0_req_managers_pw_budget(struct pd692x0_priv *priv)
10361042
{
10371043
int i, ret;
10381044

1039-
for (i = 0; i < nmanagers; i++) {
1045+
for (i = 0; i < priv->nmanagers; i++) {
10401046
struct regulator *supply = priv->manager_reg[i]->supply;
10411047
int pw_budget;
10421048

@@ -1053,7 +1059,18 @@ pd692x0_configure_managers(struct pd692x0_priv *priv, int nmanagers)
10531059
return ret;
10541060

10551061
priv->manager_pw_budget[i] = pw_budget;
1056-
ret = pd692x0_conf_manager_power_budget(priv, i, pw_budget);
1062+
}
1063+
1064+
return 0;
1065+
}
1066+
1067+
static int
1068+
pd692x0_configure_managers(struct pd692x0_priv *priv)
1069+
{
1070+
int i, ret;
1071+
1072+
for (i = 0; i < priv->nmanagers; i++) {
1073+
ret = pd692x0_conf_manager_power_budget(priv, i);
10571074
if (ret < 0)
10581075
return ret;
10591076
}
@@ -1101,10 +1118,9 @@ pd692x0_set_port_matrix(const struct pse_pi_pairset *pairset,
11011118

11021119
static int
11031120
pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
1104-
const struct pd692x0_manager *manager,
1105-
int nmanagers,
1106-
struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
1121+
const struct pd692x0_manager *manager)
11071122
{
1123+
struct pd692x0_matrix *port_matrix = priv->port_matrix;
11081124
struct pse_controller_dev *pcdev = &priv->pcdev;
11091125
int i, ret;
11101126

@@ -1117,7 +1133,7 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
11171133
/* Update with values for every PSE PIs */
11181134
for (i = 0; i < pcdev->nr_lines; i++) {
11191135
ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0],
1120-
manager, nmanagers,
1136+
manager, priv->nmanagers,
11211137
&port_matrix[i]);
11221138
if (ret) {
11231139
dev_err(&priv->client->dev,
@@ -1126,7 +1142,7 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
11261142
}
11271143

11281144
ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1],
1129-
manager, nmanagers,
1145+
manager, priv->nmanagers,
11301146
&port_matrix[i]);
11311147
if (ret) {
11321148
dev_err(&priv->client->dev,
@@ -1139,9 +1155,9 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
11391155
}
11401156

11411157
static int
1142-
pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
1143-
const struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
1158+
pd692x0_write_ports_matrix(struct pd692x0_priv *priv)
11441159
{
1160+
struct pd692x0_matrix *port_matrix = priv->port_matrix;
11451161
struct pd692x0_msg msg, buf;
11461162
int ret, i;
11471163

@@ -1166,13 +1182,32 @@ pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
11661182
return 0;
11671183
}
11681184

1185+
static int pd692x0_hw_conf_init(struct pd692x0_priv *priv)
1186+
{
1187+
int ret;
1188+
1189+
/* Is PD692x0 ready to be configured? */
1190+
if (priv->fw_state != PD692X0_FW_OK &&
1191+
priv->fw_state != PD692X0_FW_COMPLETE)
1192+
return 0;
1193+
1194+
ret = pd692x0_configure_managers(priv);
1195+
if (ret)
1196+
return ret;
1197+
1198+
ret = pd692x0_write_ports_matrix(priv);
1199+
if (ret)
1200+
return ret;
1201+
1202+
return 0;
1203+
}
1204+
11691205
static void pd692x0_of_put_managers(struct pd692x0_priv *priv,
1170-
struct pd692x0_manager *manager,
1171-
int nmanagers)
1206+
struct pd692x0_manager *manager)
11721207
{
11731208
int i, j;
11741209

1175-
for (i = 0; i < nmanagers; i++) {
1210+
for (i = 0; i < priv->nmanagers; i++) {
11761211
for (j = 0; j < manager[i].nports; j++)
11771212
of_node_put(manager[i].port_node[j]);
11781213
of_node_put(manager[i].node);
@@ -1201,48 +1236,50 @@ static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
12011236
static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
12021237
{
12031238
struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1204-
struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
1239+
struct pd692x0_matrix *port_matrix;
12051240
struct pd692x0_manager *manager;
1206-
int ret, nmanagers;
1207-
1208-
/* Should we flash the port matrix */
1209-
if (priv->fw_state != PD692X0_FW_OK &&
1210-
priv->fw_state != PD692X0_FW_COMPLETE)
1211-
return 0;
1241+
int ret;
12121242

12131243
manager = kcalloc(PD692X0_MAX_MANAGERS, sizeof(*manager), GFP_KERNEL);
12141244
if (!manager)
12151245
return -ENOMEM;
12161246

1247+
port_matrix = devm_kcalloc(&priv->client->dev, PD692X0_MAX_PIS,
1248+
sizeof(*port_matrix), GFP_KERNEL);
1249+
if (!port_matrix) {
1250+
ret = -ENOMEM;
1251+
goto err_free_manager;
1252+
}
1253+
priv->port_matrix = port_matrix;
1254+
12171255
ret = pd692x0_of_get_managers(priv, manager);
12181256
if (ret < 0)
12191257
goto err_free_manager;
12201258

1221-
nmanagers = ret;
1222-
ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
1259+
ret = pd692x0_register_managers_regulator(priv, manager);
12231260
if (ret)
12241261
goto err_of_managers;
12251262

1226-
ret = pd692x0_configure_managers(priv, nmanagers);
1263+
ret = pd692x0_req_managers_pw_budget(priv);
12271264
if (ret)
12281265
goto err_of_managers;
12291266

1230-
ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
1267+
ret = pd692x0_set_ports_matrix(priv, manager);
12311268
if (ret)
12321269
goto err_managers_req_pw;
12331270

1234-
ret = pd692x0_write_ports_matrix(priv, port_matrix);
1271+
ret = pd692x0_hw_conf_init(priv);
12351272
if (ret)
12361273
goto err_managers_req_pw;
12371274

1238-
pd692x0_of_put_managers(priv, manager, nmanagers);
1275+
pd692x0_of_put_managers(priv, manager);
12391276
kfree(manager);
12401277
return 0;
12411278

12421279
err_managers_req_pw:
12431280
pd692x0_managers_free_pw_budget(priv);
12441281
err_of_managers:
1245-
pd692x0_of_put_managers(priv, manager, nmanagers);
1282+
pd692x0_of_put_managers(priv, manager);
12461283
err_free_manager:
12471284
kfree(manager);
12481285
return ret;
@@ -1647,7 +1684,7 @@ static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)
16471684
return FW_UPLOAD_ERR_FW_INVALID;
16481685
}
16491686

1650-
ret = pd692x0_setup_pi_matrix(&priv->pcdev);
1687+
ret = pd692x0_hw_conf_init(priv);
16511688
if (ret < 0) {
16521689
dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",
16531690
ERR_PTR(ret));

0 commit comments

Comments
 (0)