]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
power: regulator: Only run autoset once for each regulator
authorJonas Karlman <jonas@kwiboo.se>
Mon, 21 Aug 2023 22:30:24 +0000 (22:30 +0000)
committerKever Yang <kever.yang@rock-chips.com>
Sat, 7 Oct 2023 08:49:41 +0000 (16:49 +0800)
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>
drivers/power/regulator/regulator-uclass.c
include/power/regulator.h

index 3a6ba69f6d5ff3495431353101d046ff8d67a526..77d101f262e2708ee5a8ea9375860b099c0814f2 100644 (file)
@@ -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;
 }
 
index ff1bfc2435aef0069576986cacc463624b77833f..200652cb3d7a032b55cb2820e4af1400eb40b11a 100644 (file)
@@ -134,6 +134,7 @@ struct dm_regulator_mode {
 enum regulator_flag {
        REGULATOR_FLAG_AUTOSET_UV       = 1 << 0,
        REGULATOR_FLAG_AUTOSET_UA       = 1 << 1,
+       REGULATOR_FLAG_AUTOSET_DONE     = 1 << 2,
 };
 
 /**