From 4511db2505322c2fbbcd082399bd65f98a4d187e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Oct 2023 09:39:04 +0200 Subject: [PATCH] drivers: regulator: always on property Implements always-on regulator property for regulators that once enabled shall never be disabled. This is archived using a regulator_enable() call to increment its refcount. Signed-off-by: Etienne Carriere --- core/drivers/regulator/regulator.c | 22 ++++++++++++++++++---- core/include/drivers/regulator.h | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/core/drivers/regulator/regulator.c b/core/drivers/regulator/regulator.c index 1ece3b51f06..334d804be76 100644 --- a/core/drivers/regulator/regulator.c +++ b/core/drivers/regulator/regulator.c @@ -108,6 +108,9 @@ TEE_Result regulator_enable(struct regulator *regulator) assert(regulator); FMSG("%s", regulator_name(regulator)); + if (regulator_is_always_on(regulator)) + return TEE_SUCCESS; + return regulator_refcnt_enable(regulator); } @@ -153,6 +156,9 @@ TEE_Result regulator_disable(struct regulator *regulator) assert(regulator); FMSG("%s", regulator_name(regulator)); + if (regulator_is_always_on(regulator)) + return TEE_SUCCESS; + return regulator_refcnt_disable(regulator); } @@ -213,7 +219,8 @@ TEE_Result regulator_register(struct regulator *regulator) int max_uv = 0; int uv = 0; - if (!regulator || !regulator->ops) + if (!regulator || !regulator->ops || + regulator->flags & ~REGULATOR_FLAGS_MASK) return TEE_ERROR_BAD_PARAMETERS; regulator_get_range(regulator, &min_uv, &max_uv); @@ -236,6 +243,13 @@ TEE_Result regulator_register(struct regulator *regulator) return res; } + /* Unbalanced enable refcount to keep always-on regulators enabled */ + if (regulator_is_always_on(regulator)) { + res = regulator_refcnt_enable(regulator); + if (res) + return res; + } + SLIST_INSERT_HEAD(®ulator_device_list, regulator, link); return TEE_SUCCESS; @@ -249,14 +263,14 @@ void regulator_print_state(const char *message __maybe_unused) struct regulator *regulator = NULL; DMSG("Regulator state: %s", message); - DMSG("name use\ten\tuV\tmin\tmax\tsupply"); + DMSG("name use\ten\tuV\tmin\tmax\tflags\tsupply"); SLIST_FOREACH(regulator, ®ulator_device_list, link) - DMSG("%8s %u\t%d\t%d\t%d\t%d\t%s\n", + DMSG("%8s %u\t%d\t%d\t%d\t%d\t%#x\t%s\n", regulator->name, regulator->refcount, regulator_is_enabled(regulator), regulator_get_voltage(regulator), - regulator->min_uv, regulator->max_uv, + regulator->min_uv, regulator->max_uv, regulator->flags, regulator->supply ? regulator_name(regulator->supply) : ""); } diff --git a/core/include/drivers/regulator.h b/core/include/drivers/regulator.h index ed1570d4d6b..feb1fe3fe7b 100644 --- a/core/include/drivers/regulator.h +++ b/core/include/drivers/regulator.h @@ -12,6 +12,18 @@ #include #include #include +#include + +/* + * Regulator property flags: related to device tree binding properties + * + * REGUL_ALWAYS_ON + * Regulator should never be disabled. Relates to device tree binding + * property regulator-always-on. + */ +#define REGULATOR_ALWAYS_ON BIT(0) + +#define REGULATOR_FLAGS_MASK REGULATOR_ALWAYS_ON struct regulator_ops; @@ -24,6 +36,7 @@ struct regulator_ops; * @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 * @link: Link in initialized regulator list @@ -38,6 +51,7 @@ struct regulator { int max_uv; /* Fields internal to regulator framework */ int cur_uv; + unsigned int flags; unsigned int refcount; struct mutex lock; /* Concurrent access protection */ SLIST_ENTRY(regulator) link; @@ -134,6 +148,15 @@ static inline const char *regulator_name(struct regulator *regulator) return regulator->name; } +/* + * regulator_is_always_on() - Return the state of REGULATOR_ALWAYS_ON flag + * @regulator: Regulator reference + */ +static inline bool regulator_is_always_on(struct regulator *regulator) +{ + return regulator->flags & REGULATOR_ALWAYS_ON; +} + /* * regulator_set_min_voltage() - Set regulator to its min level * @regulator: Regulator reference