[PATCH v5 2/4] regulator: core: Parse regulator-off-on-delay-us generically
From: Jishnu Prakash
Date: Tue Oct 27 2026 - 08:44:24 EST
off_on_delay is normally fixed per regulator type in regulator_desc,
e.g. hardcoded for every LDO a driver supports. But the delay a rail
needs before it's safe to re-enable can depend on board-specific
factors like attached bulk capacitance, not just the regulator type,
so some individual regulators need a different value than their
type's default.
Add an off_on_delay field to struct regulation_constraints, parse
'regulator-off-on-delay-us' into it in of_get_regulation_constraints(),
and add a _regulator_get_off_on_delay() helper, so a
devicetree/board-constraint value takes precedence over the driver's
static regulator_desc value. This lets drivers rely on the core to
set this delay rather than parsing it themselves.
Suggested-by: Saikiran <bjsaikiran@xxxxxxxxx>
Signed-off-by: Jishnu Prakash <jishnu.prakash@xxxxxxxxxxxxxxxx>
---
drivers/regulator/core.c | 18 ++++++++++++++----
drivers/regulator/of_regulator.c | 4 ++++
include/linux/regulator/machine.h | 4 ++++
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6a4008f387b5..537384c55d6f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1401,6 +1401,7 @@ static int machine_constraints_current(struct regulator_dev *rdev,
}
static int _regulator_do_enable(struct regulator_dev *rdev);
+static unsigned int _regulator_get_off_on_delay(struct regulator_dev *rdev);
static int notif_set_limit(struct regulator_dev *rdev,
int (*set)(struct regulator_dev *, int, int, bool),
@@ -1695,7 +1696,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (rdev->constraints->always_on)
rdev->use_count++;
- } else if (rdev->desc->off_on_delay) {
+ } else if (_regulator_get_off_on_delay(rdev)) {
rdev->last_off = ktime_get();
}
@@ -2071,6 +2072,13 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
return rdev->desc->enable_time;
}
+static unsigned int _regulator_get_off_on_delay(struct regulator_dev *rdev)
+{
+ if (rdev->constraints && rdev->constraints->off_on_delay)
+ return rdev->constraints->off_on_delay;
+ return rdev->desc->off_on_delay;
+}
+
static struct regulator_supply_alias *regulator_find_supply_alias(
struct device *dev, const char *supply)
{
@@ -2985,6 +2993,7 @@ static inline int _regulator_check_status_enabled(struct regulator_dev *rdev)
static int _regulator_do_enable(struct regulator_dev *rdev)
{
int ret, delay;
+ unsigned int off_on_delay;
/* Query before enabling in case configuration dependent. */
ret = _regulator_get_enable_time(rdev);
@@ -2997,11 +3006,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
trace_regulator_enable(rdev_get_name(rdev));
- if (rdev->desc->off_on_delay) {
+ off_on_delay = _regulator_get_off_on_delay(rdev);
+ if (off_on_delay) {
/* if needed, keep a distance of off_on_delay from last time
* this regulator was disabled.
*/
- ktime_t end = ktime_add_us(rdev->last_off, rdev->desc->off_on_delay);
+ ktime_t end = ktime_add_us(rdev->last_off, off_on_delay);
s64 remaining = ktime_us_delta(end, ktime_get_boottime());
if (remaining > 0)
@@ -3243,7 +3253,7 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
return ret;
}
- if (rdev->desc->off_on_delay)
+ if (_regulator_get_off_on_delay(rdev))
rdev->last_off = ktime_get_boottime();
trace_regulator_disable_complete(rdev_get_name(rdev));
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 09e26febfc83..990946b27a7a 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -178,6 +178,10 @@ static int of_get_regulation_constraints(struct device *dev,
if (!ret)
constraints->enable_time = pval;
+ ret = of_property_read_u32(np, "regulator-off-on-delay-us", &pval);
+ if (!ret)
+ constraints->off_on_delay = pval;
+
ret = of_property_read_u32(np, "regulator-uv-less-critical-window-ms", &pval);
if (!ret)
constraints->uv_less_critical_window_ms = pval;
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 1fc440c5c4c7..79b2d7cab934 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -163,6 +163,9 @@ struct notification_limit {
* regulator_active_discharge values are used for
* initialisation.
* @enable_time: Turn-on time of the rails (unit: microseconds)
+ * @off_on_delay: Guard time (in uS), before re-enabling a regulator. Takes
+ * precedence over the regulator_desc field of the same name
+ * when non-zero.
* @uv_less_critical_window_ms: Specifies the time window (in milliseconds)
* following a critical under-voltage (UV) event
* during which less critical actions can be
@@ -222,6 +225,7 @@ struct regulation_constraints {
unsigned int settling_time_up;
unsigned int settling_time_down;
unsigned int enable_time;
+ unsigned int off_on_delay;
unsigned int uv_less_critical_window_ms;
unsigned int active_discharge;
--
2.43.0