[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