[PATCH v4 1/2] regulator: qcom-rpmh-regulator: fix regulator mode mismatch

Federico Amedeo Izzo via B4 Relay devnull+federico.izzo.pro at kernel.org
Sat May 23 15:04:24 CEST 2026


From: Federico Amedeo Izzo <federico at izzo.pro>

Initial regulator mode was read from dts but never applied.
This caused a mismatch between saved mode and actual regulator mode.

Apply the current mode from priv->mode during enable() and move
rpmh_regulator_vrm_set_mode function before rpmh_regulator_set_enable_state().

Signed-off-by: Federico Amedeo Izzo <federico at izzo.pro>
---
 drivers/power/regulator/qcom-rpmh-regulator.c | 106 ++++++++++++++------------
 1 file changed, 56 insertions(+), 50 deletions(-)

diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c
index 4d65aae1690..f789b5b6f86 100644
--- a/drivers/power/regulator/qcom-rpmh-regulator.c
+++ b/drivers/power/regulator/qcom-rpmh-regulator.c
@@ -295,6 +295,56 @@ static int rpmh_regulator_vrm_get_value(struct udevice *rdev)
 	return vreg->uv;
 }
 
+static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
+					      unsigned int mode, bool bypassed)
+{
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+	};
+	struct dm_regulator_mode *pmic_mode;
+	int i;
+
+	if (mode > REGULATOR_MODE_HPM)
+		return -EINVAL;
+
+	for (i = 0; i < vreg->hw_data->n_modes; i++) {
+		pmic_mode = &vreg->hw_data->pmic_mode_map[i];
+		if (pmic_mode->id == mode)
+			break;
+	}
+	if (pmic_mode->id != mode) {
+		printf("Invalid mode %d\n", mode);
+		return -EINVAL;
+	}
+
+	if (bypassed)
+		// XXX: should have a version check for PMIC4 but we don't have any yet
+		// and we don't use bypass mode
+		cmd.data = PMIC5_BOB_MODE_PASS;
+	else
+		cmd.data = pmic_mode->register_value;
+
+	return rpmh_regulator_send_request(vreg, &cmd, true);
+}
+
+static int rpmh_regulator_vrm_set_mode(struct udevice *rdev,
+				       int mode)
+{
+	struct rpmh_vreg *vreg = dev_get_priv(rdev);
+	int ret;
+
+	debug("%s: set_mode %d (current %d)\n", rdev->name, mode, vreg->mode);
+
+	if (mode == vreg->mode)
+		return 0;
+
+	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
+	if (!ret)
+		vreg->mode = mode;
+
+	return ret;
+}
+
 static int rpmh_regulator_is_enabled(struct udevice *rdev)
 {
 	struct rpmh_vreg *vreg = dev_get_priv(rdev);
@@ -331,6 +381,12 @@ static int rpmh_regulator_set_enable_state(struct udevice *rdev,
 	debug("%s: set_enable %d (current %d)\n", rdev->name, enable,
 	      vreg->enabled);
 
+	if (vreg->mode != -EINVAL) {
+		ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, vreg->bypassed);
+		if (ret < 0)
+			return ret;
+	}
+
 	if (vreg->enabled == -EINVAL &&
 	    vreg->uv != -ENOTRECOVERABLE) {
 		ret = _rpmh_regulator_vrm_set_value(rdev,
@@ -346,56 +402,6 @@ static int rpmh_regulator_set_enable_state(struct udevice *rdev,
 	return ret;
 }
 
-static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
-					      unsigned int mode, bool bypassed)
-{
-	struct tcs_cmd cmd = {
-		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
-	};
-	struct dm_regulator_mode *pmic_mode;
-	int i;
-
-	if (mode > REGULATOR_MODE_HPM)
-		return -EINVAL;
-
-	for (i = 0; i < vreg->hw_data->n_modes; i++) {
-		pmic_mode = &vreg->hw_data->pmic_mode_map[i];
-		if (pmic_mode->id == mode)
-			break;
-	}
-	if (pmic_mode->id != mode) {
-		printf("Invalid mode %d\n", mode);
-		return -EINVAL;
-	}
-
-	if (bypassed)
-		// XXX: should have a version check for PMIC4 but we don't have any yet
-		// and we don't use bypass mode
-		cmd.data = PMIC5_BOB_MODE_PASS;
-	else
-		cmd.data = pmic_mode->register_value;
-
-	return rpmh_regulator_send_request(vreg, &cmd, true);
-}
-
-static int rpmh_regulator_vrm_set_mode(struct udevice *rdev,
-				       int mode)
-{
-	struct rpmh_vreg *vreg = dev_get_priv(rdev);
-	int ret;
-
-	debug("%s: set_mode %d (current %d)\n", rdev->name, mode, vreg->mode);
-
-	if (mode == vreg->mode)
-		return 0;
-
-	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
-	if (!ret)
-		vreg->mode = mode;
-
-	return ret;
-}
-
 static int rpmh_regulator_vrm_get_pmic_mode(struct rpmh_vreg *vreg, int *pmic_mode)
 {
 	struct tcs_cmd cmd = {

-- 
2.54.0




More information about the U-Boot mailing list