diff options
| author | Pengpeng Hou <pengpeng@iscas.ac.cn> | 2026-07-09 20:32:39 +0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-10 15:56:54 +0200 |
| commit | 2c5659a7064e7c4c0c51eb9356bcf6726a85773b (patch) | |
| tree | 6958a9cd936f273a3530e50d649d28c898cf4ffc | |
| parent | e2467aabbfe14a4d6d4d40b58153ca3354606d9f (diff) | |
| download | linux-next-2c5659a7064e7c4c0c51eb9356bcf6726a85773b.tar.gz linux-next-2c5659a7064e7c4c0c51eb9356bcf6726a85773b.zip | |
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 <heikki.krogerus@linux.intel.com>
Reviewed-by: Pengyu Luo <mitltlatltl@gmail.com>
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260709123239.62930-1-pengpeng@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 15 |
1 files 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); |
