diff options
author | Jonas Karlman <jonas@kwiboo.se> | 2024-07-24 22:47:10 +0000 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-09-25 08:54:03 -0600 |
commit | f417c14d88fec5757dbf3cd6af6f7f2ddb99595f (patch) | |
tree | fe66d51625382c951b3ba1ea03cd2a260ad8ef56 | |
parent | 49e3b574ed4f6dc26b65a5d6e9cd14b97e03b861 (diff) |
power: regulator: Do not call set_suspend_value with -ENODATA
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@kwiboo.se>
-rw-r--r-- | drivers/power/regulator/regulator-uclass.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 88a8525b3c4..03d39587b31 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; |