mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 12:34:02 +02:00
usb: typec: hd3ss3220: track VBUS enable state per consumer
regulator_is_enabled() reports the aggregate regulator state, not
whether this consumer holds an enable reference. If another consumer
enables VBUS first, the driver can skip its own regulator_enable() call
and later attempt to drop a reference it never acquired, triggering an
unbalanced regulator disable warning.
Track successful enable and disable calls locally. Keep the state
unchanged when an operation fails so a later role or ID notification
retries the operation while this consumer keeps balanced references.
Fixes: b3f9d6e491 ("usb: typec: hd3ss3220: Check if regulator needs to be switched")
Cc: stable <stable@kernel.org>
Link: https://github.com/qualcomm-linux/kernel/issues/472
Signed-off-by: Chang Wu <kunjinkao.jp@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Tested-by: Jan Remmet <j.remmet@phytec.de>
Reviewed-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Link: https://patch.msgid.link/20260819152027.90994-1-kunjinkao.jp@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b58e620045
commit
c9a48db776
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user