From c89d802385dc4f6dd5008e5a38cd21f5c8277509 Mon Sep 17 00:00:00 2001 From: Chang Wu Date: Mon, 17 Aug 2026 19:27:26 +0800 Subject: [PATCH 1/2] usb: typec: hd3ss3220: Fix VBUS regulator error message The error message currently reports the inverse operation because the enable/disable names are selected backwards. Report the operation that was actually attempted. Signed-off-by: Chang Wu --- drivers/usb/typec/hd3ss3220.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index 3e39b800e6b5f..d0de5a2488f95 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -218,7 +218,7 @@ static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on) if (ret) dev_err(hd3ss3220->dev, - "vbus regulator %s failed: %d\n", on ? "disable" : "enable", ret); + "vbus regulator %s failed: %d\n", on ? "enable" : "disable", ret); } static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220) From 7f0394ca81e235b79f28e7c1cef0cde38f38879b Mon Sep 17 00:00:00 2001 From: Chang Wu Date: Mon, 17 Aug 2026 19:28:18 +0800 Subject: [PATCH 2/2] usb: typec: hd3ss3220: Track VBUS enable state per consumer regulator_is_enabled() may report enabled when another consumer holds the enable reference, so it cannot be used to determine whether this consumer called regulator_enable(). If another consumer enables VBUS first, hd3ss3220 can skip its own enable. A later disable then attempts to drop a reference it never acquired, causing an unbalanced regulator disable. Track successful enable and disable calls locally. Do not update the state when a regulator operation fails, so repeated role and ID notifications remain balanced. Fixes: b3f9d6e491fd ("usb: typec: hd3ss3220: Check if regulator needs to be switched") Signed-off-by: Chang Wu --- drivers/usb/typec/hd3ss3220.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index d0de5a2488f95..4eec90c82bae4 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -62,6 +62,7 @@ struct hd3ss3220 { int id_irq; struct regulator *vbus; + bool vbus_enabled; }; static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode) @@ -208,7 +209,7 @@ static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on) { int ret; - if (regulator_is_enabled(hd3ss3220->vbus) == on) + if (hd3ss3220->vbus_enabled == on) return; if (on) @@ -216,9 +217,13 @@ static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on) else ret = regulator_disable(hd3ss3220->vbus); - if (ret) + if (ret) { dev_err(hd3ss3220->dev, "vbus regulator %s failed: %d\n", on ? "enable" : "disable", ret); + return; + } + + hd3ss3220->vbus_enabled = on; } static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220)