diff options
author | Jonas Karlman | 2023-08-21 22:30:24 +0000 |
---|---|---|
committer | Kever Yang | 2023-10-07 16:49:41 +0800 |
commit | d99fb64a98af3bebf6b0c134291c4fb89e177aa2 (patch) | |
tree | ca0af2bac0df1e72fb3d2ead9152aa7d5ee47223 /drivers/power/regulator | |
parent | a9e9445ea2bb010444621e563a79bc33fe064f9c (diff) |
power: regulator: Only run autoset once for each regulator
With the commit 4fcba5d556b4 ("regulator: implement basic reference
counter"), keeping regulator enablement in balance become more important.
Calling regulator_autoset multiple times on a fixed regulator increase
the enable count for each call, resulting in an unbalanced enable count.
Introduce a AUTOSET_DONE flag and use it to mark that autoset has run
for the regulator. Return -EALREADY on any subsequent call to autoset.
This fixes so that the enable count is only ever increased by one per
regulator for autoset.
Fixes: 4fcba5d556b4 ("regulator: implement basic reference counter")
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Diffstat (limited to 'drivers/power/regulator')
-rw-r--r-- | drivers/power/regulator/regulator-uclass.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 3a6ba69f6d5..77d101f262e 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -293,6 +293,9 @@ int regulator_autoset(struct udevice *dev) uc_pdata = dev_get_uclass_plat(dev); + if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_DONE) + return -EALREADY; + ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on); if (ret == -ENOSYS) ret = 0; @@ -306,11 +309,15 @@ int regulator_autoset(struct udevice *dev) return ret; } - if (!uc_pdata->always_on && !uc_pdata->boot_on) - return -EMEDIUMTYPE; + if (!uc_pdata->always_on && !uc_pdata->boot_on) { + ret = -EMEDIUMTYPE; + goto out; + } - if (uc_pdata->type == REGULATOR_TYPE_FIXED) - return regulator_set_enable(dev, true); + if (uc_pdata->type == REGULATOR_TYPE_FIXED) { + ret = regulator_set_enable(dev, true); + goto out; + } if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) ret = regulator_set_value(dev, uc_pdata->min_uV); @@ -322,6 +329,9 @@ int regulator_autoset(struct udevice *dev) if (!ret) ret = regulator_set_enable(dev, true); +out: + uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_DONE; + return ret; } |