[PATCH v3] usb: typec: ucsi: gaokun: unwind notifier on UCSI register failure
From: Pengpeng Hou
Date: Thu Jul 09 2026 - 08:38:07 EST
gaokun_ucsi_register_worker() registers the EC notifier before calling
ucsi_register(). If ucsi_register() fails, the worker currently only logs
the error and leaves the notifier registered. Later EC events can then
call into an unpublished UCSI instance.
The remove path also unconditionally unregisters both the EC notifier and
the UCSI device even if the delayed worker failed before both publication
steps completed.
Unregister the notifier immediately when ucsi_register() fails, and track
only the fully published state. The remove path then tears down the pair
only if both publication steps completed.
Fixes: 00327d7f2c8c ("usb: typec: ucsi: add Huawei Matebook E Go ucsi driver")
Reviewed-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
Reviewed-by: Pengyu Luo <mitltlatltl@xxxxxxxxx>
Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
Changes since v2:
- rebase onto v7.2-rc2, which now releases per-port typec_mux handles in
the remove path
- add the collected Reviewed-by tags
- add the Fixes tag after checking the introducing commit
- no hardware test was performed
drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
index ad669d2..24e859a 100644
--- a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
+++ b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
@@ -103,6 +103,7 @@ struct gaokun_ucsi {
struct notifier_block nb;
u16 version;
u8 num_ports;
+ bool registered;
};
/* -------------------------------------------------------------------------- */
@@ -482,8 +483,13 @@ static void gaokun_ucsi_register_worker(struct work_struct *work)
}
ret = ucsi_register(ucsi);
- if (ret)
+ if (ret) {
dev_err_probe(ucsi->dev, ret, "ucsi register failed\n");
+ gaokun_ec_unregister_notify(uec->ec, &uec->nb);
+ return;
+ }
+
+ uec->registered = true;
}
static int gaokun_ucsi_probe(struct auxiliary_device *adev,
@@ -528,8 +534,11 @@ static void gaokun_ucsi_remove(struct auxiliary_device *adev)
int i;
disable_delayed_work_sync(&uec->work);
- gaokun_ec_unregister_notify(uec->ec, &uec->nb);
- ucsi_unregister(uec->ucsi);
+ if (uec->registered) {
+ gaokun_ec_unregister_notify(uec->ec, &uec->nb);
+ ucsi_unregister(uec->ucsi);
+ }
+
for (i = 0; i < uec->num_ports; ++i)
typec_mux_put(uec->ports[i].typec_mux);
--
2.50.1 (Apple Git-155)