[PATCH v3 06/10] regulator: ab8500: Propagate mode enable read errors

From: Linus Walleij

Date: Mon Sep 14 2026 - 03:54:58 EST


For regulators whose enable and mode share a state field, set_mode()
first reads that field so changing the requested mode does not enable a
disabled rail. A register read error is currently treated as true and
the driver proceeds to write the new mode, potentially enabling a rail
whose state is unknown.

Return the read error without changing the register or cached mode.

References: AB8500 User Manual, UM0836 Rev 3, p. 227;
AB8505 User Manual, DM00046744 Rev 3, p. 237

Fixes: 438e695b87e0 ("regulator: ab8500: Get rid of is_enabled from struct ab8500_regulator_info")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@xxxxxxxxxx>
---
drivers/regulator/ab8500.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 05c6b9c7af0c..e4c3502c8dbc 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -433,7 +433,7 @@ static unsigned int ab8500_regulator_get_optimum_mode(
static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
- int ret = 0;
+ int enabled, ret = 0;
u8 bank, reg, mask, val;
bool lp_mode_req = false;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
@@ -490,7 +490,17 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
goto out_unlock;
}

- if (info->mode_mask || ab8500_regulator_is_enabled(rdev)) {
+ if (info->mode_mask) {
+ enabled = 1;
+ } else {
+ enabled = ab8500_regulator_is_enabled(rdev);
+ if (enabled < 0) {
+ ret = enabled;
+ goto out_unlock;
+ }
+ }
+
+ if (enabled) {
ret = abx500_mask_and_set_register_interruptible(info->dev,
bank, reg, mask, val);
if (ret < 0) {

--
2.55.0