summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2023-01-31 15:15:18 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-02-02 11:27:28 +0100
commitf82060da749c611ed427523b6d1605d87338aac1 (patch)
tree427e9d3a880975e3dad0b926fea1da042ab8cab8 /drivers
parentusb: gadget: udc: do not clear gadget driver.bus (diff)
downloadlinux-f82060da749c611ed427523b6d1605d87338aac1.tar.xz
linux-f82060da749c611ed427523b6d1605d87338aac1.zip
usb: typec: ucsi: Don't attempt to resume the ports before they exist
This will fix null pointer dereference that was caused by the driver attempting to resume ports that were not yet registered. Fixes: e0dced9c7d47 ("usb: typec: ucsi: Resume in separate work") Cc: <stable@vger.kernel.org> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216697 Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20230131141518.78215-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/typec/ucsi/ucsi.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 1292241d581a..1cf8947c6d66 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1269,6 +1269,9 @@ err_unregister:
con->port = NULL;
}
+ kfree(ucsi->connector);
+ ucsi->connector = NULL;
+
err_reset:
memset(&ucsi->cap, 0, sizeof(ucsi->cap));
ucsi_reset_ppm(ucsi);
@@ -1300,7 +1303,8 @@ static void ucsi_resume_work(struct work_struct *work)
int ucsi_resume(struct ucsi *ucsi)
{
- queue_work(system_long_wq, &ucsi->resume_work);
+ if (ucsi->connector)
+ queue_work(system_long_wq, &ucsi->resume_work);
return 0;
}
EXPORT_SYMBOL_GPL(ucsi_resume);
@@ -1420,6 +1424,9 @@ void ucsi_unregister(struct ucsi *ucsi)
/* Disable notifications */
ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+ if (!ucsi->connector)
+ return;
+
for (i = 0; i < ucsi->cap.num_connectors; i++) {
cancel_work_sync(&ucsi->connector[i].work);
ucsi_unregister_partner(&ucsi->connector[i]);