[PATCH 1/2] power: regulator: Do not call set_suspend_value with -ENODATA

Jonas Karlman jonas at kwiboo.se
Thu Jul 25 00:47:10 CEST 2024


On some boards a PMIC regulator is flagged with regulator-on-in-suspend
and does not define any suspend or max microvolt, e.g. on Radxa ROCK 3A:

  vcc_ddr: DCDC_REG3 {
	regulator-name = "vcc_ddr";
	regulator-always-on;
	regulator-boot-on;
	regulator-initial-mode = <0x2>;

	regulator-state-mem {
		regulator-on-in-suspend;
	};
  };

This result in suspend_uV having the value -ENODATA after probe.

This negative voltage, -ENODATA, gets missinterpreted and result in an
unexpected voltage being set by autoset.

E.g. on Radxa ROCK 3A the vcc_ddr regulator by default have a normal and
suspend voltage value of 0.5v. However, due to this missinterpretation
the suspend voltage end up beind set to 0.5625v instead.

Fix this by skip calling regulator_set_suspend_value() in autoset and
also protect calling set value ops when input value is -ENODATA.

Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
---
 drivers/power/regulator/regulator-uclass.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 88a8525b3c47..03d39587b315 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -60,6 +60,8 @@ int regulator_set_value(struct udevice *dev, int uV)
 		return -EINVAL;
 	if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
 		return -EINVAL;
+	if (uV == -ENODATA)
+		return -EINVAL;
 
 	if (!ops || !ops->set_value)
 		return -ENOSYS;
@@ -90,6 +92,8 @@ int regulator_set_suspend_value(struct udevice *dev, int uV)
 		return -EINVAL;
 	if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
 		return -EINVAL;
+	if (uV == -ENODATA)
+		return -EINVAL;
 
 	if (!ops->set_suspend_value)
 		return -ENOSYS;
@@ -141,6 +145,8 @@ int regulator_set_current(struct udevice *dev, int uA)
 		return -EINVAL;
 	if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
 		return -EINVAL;
+	if (uA == -ENODATA)
+		return -EINVAL;
 
 	if (!ops || !ops->set_current)
 		return -ENOSYS;
@@ -299,7 +305,7 @@ int regulator_autoset(struct udevice *dev)
 	if (ret == -ENOSYS)
 		ret = 0;
 
-	if (!ret && uc_pdata->suspend_on) {
+	if (!ret && uc_pdata->suspend_on && uc_pdata->suspend_uV != -ENODATA) {
 		ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
 		if (ret == -ENOSYS)
 			ret = 0;
-- 
2.45.2



More information about the U-Boot mailing list