@@ -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+
8893struct 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-
817819static int
818820pd692x0_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
908911out :
909912 for (i = 0 ; i < nmanagers ; i ++ ) {
@@ -963,8 +966,7 @@ pd692x0_register_manager_regulator(struct device *dev, char *reg_name,
963966
964967static int
965968pd692x0_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
10101012static 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
10341040static 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
11021119static int
11031120pd692x0_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
11411157static 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+
11691205static 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)
12011236static 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
12421279err_managers_req_pw :
12431280 pd692x0_managers_free_pw_budget (priv );
12441281err_of_managers :
1245- pd692x0_of_put_managers (priv , manager , nmanagers );
1282+ pd692x0_of_put_managers (priv , manager );
12461283err_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