[PATCH 3/3] power: regulator: qcom-rpmh: propagate votes to parent supplies

Casey Connolly casey.connolly at linaro.org
Mon Apr 13 13:06:16 CEST 2026


Parse the parent supply data, fetch parent supplies and propagate
set_enable() calls to the parent regulator.

Not sure if necessary but it doesn't hurt

Signed-off-by: Casey Connolly <casey.connolly at linaro.org>
---
 drivers/power/regulator/qcom-rpmh-regulator.c | 35 +++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c
index 3f0f18454698..de71af9b0f0d 100644
--- a/drivers/power/regulator/qcom-rpmh-regulator.c
+++ b/drivers/power/regulator/qcom-rpmh-regulator.c
@@ -159,8 +159,9 @@ struct rpmh_vreg {
 	struct udevice			*dev;
 	u32				addr;
 	const struct rpmh_vreg_hw_data	*hw_data;
 	bool				always_wait_for_ack;
+	struct udevice			*supply;
 
 	int				enabled;
 	bool				bypassed;
 	int				uv;
@@ -330,8 +331,26 @@ 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->enabled <= 0 && !enable)
+		return 0;
+	if (vreg->enabled >= 1 && enable) {
+		vreg->enabled++;
+		return 0;
+	}
+
+	if (vreg->supply) {
+		debug("%s: set supply %s enable state %d\n",
+		      rdev->name, vreg->supply->name, enable);
+		ret = regulator_set_enable(vreg->supply, enable);
+		if (ret < 0) {
+			debug("%s: failed to set supply %s enable state %d: %d\n",
+			      rdev->name, vreg->supply->name, enable, ret);
+			return ret;
+		}
+	}
+
 	if (vreg->enabled == -EINVAL &&
 	    vreg->uv != -ENOTRECOVERABLE) {
 		ret = _rpmh_regulator_vrm_set_value(rdev,
 						    vreg->uv, true);
@@ -339,10 +358,13 @@ static int rpmh_regulator_set_enable_state(struct udevice *rdev,
 			return ret;
 	}
 
 	ret = rpmh_regulator_send_request(vreg, &cmd, enable);
-	if (!ret)
-		vreg->enabled = enable;
+	if (!ret) {
+		if (vreg->enabled < 0)
+			vreg->enabled = 0;
+		vreg->enabled += enable ? 1 : -1;
+	}
 
 	return ret;
 }
 
@@ -837,8 +859,10 @@ static int rpmh_regulator_probe(struct udevice *dev)
 {
 	const struct rpmh_vreg_init_data *init_data;
 	struct rpmh_vreg *priv;
 	struct dm_regulator_uclass_plat *plat_data;
+	int ret;
+	char name[32] = { 0 };
 
 	init_data = (const struct rpmh_vreg_init_data *)dev_get_driver_data(dev);
 	priv = dev_get_priv(dev);
 	plat_data = dev_get_uclass_plat(dev);
@@ -849,8 +873,15 @@ static int rpmh_regulator_probe(struct udevice *dev)
 		dev_err(dev, "Failed to read RPMh address for %s\n", dev->name);
 		return -ENODEV;
 	}
 
+	strlcpy(name, init_data->supply_name, sizeof(name));
+	strlcat(name, "-supply", sizeof(name));
+	ret = device_get_supply_regulator(dev->parent, name, &priv->supply);
+	if (ret)
+		printf("Failed to get supply regulator %s for %s: %d\n",
+		       init_data->supply_name, dev->name, ret);
+
 	priv->hw_data = init_data->hw_data;
 	priv->enabled = -EINVAL;
 	priv->uv = -ENOTRECOVERABLE;
 	if (ofnode_read_u32(dev_ofnode(dev), "regulator-initial-mode", &priv->mode))

-- 
2.51.0



More information about the U-Boot mailing list