Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: typec: ucsi: add a common function ucsi_unregister_connectors()

In error path of ucsi_init(), it will unregister all valid ucsi connectors,
and similar operation also happen in ucsi_unregister(),
add a common function ucsi_unregister_connectors() for two places,
inside this function, if con->wq is NULL, it will break the loop,
if other kind of error happen after con->wq allocated,
ucsi/typec related API is safe to unregister.

Also in ucsi_init(), it allocate number of (ucsi->cap.num_connectors + 1)
connectors, there is one extra as the ending,
ucsi_unregister_connectors() is safe to unregister all ucsi connectors
according ucsi->cap.num_connectors,
remove the extra one connector to save memory.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Linyu Yuan <quic_linyyuan@quicinc.com>
Link: https://lore.kernel.org/r/1650881886-25530-2-git-send-email-quic_linyyuan@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Linyu Yuan and committed by
Greg Kroah-Hartman
87d0e2f4 7a60fa06

+29 -24
+29 -24
drivers/usb/typec/ucsi/ucsi.c
··· 1186 1186 return ret; 1187 1187 } 1188 1188 1189 + static void ucsi_unregister_connectors(struct ucsi *ucsi) 1190 + { 1191 + struct ucsi_connector *con; 1192 + int i; 1193 + 1194 + if (!ucsi->connector) 1195 + return; 1196 + 1197 + for (i = 0; i < ucsi->cap.num_connectors; i++) { 1198 + con = &ucsi->connector[i]; 1199 + 1200 + if (!con->wq) 1201 + break; 1202 + 1203 + cancel_work_sync(&con->work); 1204 + ucsi_unregister_partner(con); 1205 + ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); 1206 + ucsi_unregister_port_psy(con); 1207 + destroy_workqueue(con->wq); 1208 + typec_unregister_port(con->port); 1209 + } 1210 + 1211 + kfree(ucsi->connector); 1212 + ucsi->connector = NULL; 1213 + } 1214 + 1189 1215 /** 1190 1216 * ucsi_init - Initialize UCSI interface 1191 1217 * @ucsi: UCSI to be initialized ··· 1220 1194 */ 1221 1195 static int ucsi_init(struct ucsi *ucsi) 1222 1196 { 1223 - struct ucsi_connector *con; 1224 1197 u64 command; 1225 1198 int ret; 1226 1199 int i; ··· 1250 1225 } 1251 1226 1252 1227 /* Allocate the connectors. Released in ucsi_unregister() */ 1253 - ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1, 1228 + ucsi->connector = kcalloc(ucsi->cap.num_connectors, 1254 1229 sizeof(*ucsi->connector), GFP_KERNEL); 1255 1230 if (!ucsi->connector) { 1256 1231 ret = -ENOMEM; ··· 1274 1249 return 0; 1275 1250 1276 1251 err_unregister: 1277 - for (con = ucsi->connector; con->port; con++) { 1278 - ucsi_unregister_partner(con); 1279 - ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); 1280 - ucsi_unregister_port_psy(con); 1281 - if (con->wq) 1282 - destroy_workqueue(con->wq); 1283 - typec_unregister_port(con->port); 1284 - con->port = NULL; 1285 - } 1252 + ucsi_unregister_connectors(ucsi); 1286 1253 1287 1254 err_reset: 1288 1255 memset(&ucsi->cap, 0, sizeof(ucsi->cap)); ··· 1380 1363 void ucsi_unregister(struct ucsi *ucsi) 1381 1364 { 1382 1365 u64 cmd = UCSI_SET_NOTIFICATION_ENABLE; 1383 - int i; 1384 1366 1385 1367 /* Make sure that we are not in the middle of driver initialization */ 1386 1368 cancel_work_sync(&ucsi->work); ··· 1387 1371 /* Disable notifications */ 1388 1372 ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); 1389 1373 1390 - for (i = 0; i < ucsi->cap.num_connectors; i++) { 1391 - cancel_work_sync(&ucsi->connector[i].work); 1392 - ucsi_unregister_partner(&ucsi->connector[i]); 1393 - ucsi_unregister_altmodes(&ucsi->connector[i], 1394 - UCSI_RECIPIENT_CON); 1395 - ucsi_unregister_port_psy(&ucsi->connector[i]); 1396 - if (ucsi->connector[i].wq) 1397 - destroy_workqueue(ucsi->connector[i].wq); 1398 - typec_unregister_port(ucsi->connector[i].port); 1399 - } 1400 - 1401 - kfree(ucsi->connector); 1374 + ucsi_unregister_connectors(ucsi); 1402 1375 } 1403 1376 EXPORT_SYMBOL_GPL(ucsi_unregister); 1404 1377