From 2c5659a7064e7c4c0c51eb9356bcf6726a85773b Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Thu, 9 Jul 2026 20:32:39 +0800 Subject: [PATCH] usb: typec: ucsi: gaokun: unwind notifier on UCSI register failure 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 Reviewed-by: Pengyu Luo Signed-off-by: Pengpeng Hou Link: https://patch.msgid.link/20260709123239.62930-1-pengpeng@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman --- 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 ad669d2f8b9c..24e859ab2174 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);