Skip to content

Commit

Permalink
drivers: regulator: do not cache voltage level value
Browse files Browse the repository at this point in the history
Always read current voltage level from the device instead of
caching the level in struct regulator. This fixes issues for
when the regulator level value depends on the parent regulator
(supply). It is up the regulator driver to cache or not this
value in their private data if applicable.

Fixes: 1a3d327 ("drivers: regulator framework")
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
  • Loading branch information
patrickdelaunay committed Feb 22, 2024
1 parent 64a52f9 commit 423c992
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 18 deletions.
32 changes: 21 additions & 11 deletions core/drivers/regulator/regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,36 @@ bool regulator_is_enabled(struct regulator *regulator)
return !res && enabled;
}

int regulator_get_voltage(struct regulator *regulator)
{
TEE_Result res = TEE_SUCCESS;
int level_uv = regulator->min_uv;

if (regulator->ops->get_voltage) {
res = regulator->ops->get_voltage(regulator, &level_uv);
if (res) {
EMSG("%s get_voltage failed with %#"PRIx32,
regulator_name(regulator), res);
level_uv = 0;
}
}

return level_uv;
}

TEE_Result regulator_set_voltage(struct regulator *regulator, int level_uv)
{
TEE_Result res = TEE_ERROR_GENERIC;
int cur_uv = 0;

assert(regulator);
FMSG("%s %duV", regulator_name(regulator), level_uv);

if (level_uv < regulator->min_uv || level_uv > regulator->max_uv)
return TEE_ERROR_BAD_PARAMETERS;

if (level_uv == regulator->cur_uv)
cur_uv = regulator_get_voltage(regulator);
if (level_uv == cur_uv)
return TEE_SUCCESS;

if (!regulator->ops->set_voltage)
Expand All @@ -207,8 +226,6 @@ TEE_Result regulator_set_voltage(struct regulator *regulator, int level_uv)
return res;
}

regulator->cur_uv = level_uv;

return TEE_SUCCESS;
}

Expand Down Expand Up @@ -256,14 +273,7 @@ TEE_Result regulator_register(struct regulator *regulator)
return TEE_ERROR_BAD_PARAMETERS;

/* Sanitize regulator effective level */
if (regulator->ops->get_voltage) {
res = regulator->ops->get_voltage(regulator, &uv);
if (res)
return res;
} else {
uv = min_uv;
}
regulator->cur_uv = uv;
uv = regulator_get_voltage(regulator);

if (uv < min_uv || uv > max_uv) {
res = regulator_set_voltage(regulator, min_uv);
Expand Down
9 changes: 2 additions & 7 deletions core/include/drivers/regulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ struct regulator_voltages_desc {
* @name: Regulator string name for debug purpose or NULL
* @min_uv: Min possible voltage level in microvolt (uV)
* @max_uv: Max possible voltage level in microvolt (uV)
* @cur_uv: Current voltage level in microvolt (uV)
* @flags: REGULATOR_* property flags
* @refcount: Regulator enable request reference counter
* @lock: Mutex for concurrent access protection
Expand All @@ -101,7 +100,6 @@ struct regulator {
int min_uv;
int max_uv;
/* Fields internal to regulator framework */
int cur_uv;
unsigned int flags;
unsigned int refcount;
struct mutex lock; /* Concurrent access protection */
Expand Down Expand Up @@ -283,13 +281,10 @@ static inline TEE_Result regulator_set_min_voltage(struct regulator *regulator)
}

/*
* regulator_get_voltage() - Get regulator current level in microvolt
* regulator_get_voltage() - Get regulator effective voltage level in microvolt
* @regulator: Regulator reference
*/
static inline int regulator_get_voltage(struct regulator *regulator)
{
return regulator->cur_uv;
}
int regulator_get_voltage(struct regulator *regulator);

/*
* regulator_get_range() - Get regulator min and/or max support levels
Expand Down

0 comments on commit 423c992

Please sign in to comment.