From: sashiko-bot@kernel.org
To: "Paul Louvel" <paul.louvel@bootlin.com>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH 3/5] regulator: core: Add mechanism to force disable a regulator at boot
Date: Wed, 21 Oct 2026 10:46:52 +0000 [thread overview]
Message-ID: <sashiko-outbox-180119@kernel.org> (raw)
In-Reply-To: <20261021-paul-lm51772-v1-3-25f0ffbffa8d@bootlin.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] regulator: core: missing mutual exclusion for boot_force_off in set_machine_constraints()
- [High] regulator: core: boot_force_off is a no-op for GPIO-controlled regulators
- [Medium] regulator: core: boot_force_off works around consumer API misuse
- [Low] regulator: missing kernel-doc for boot_force_off in struct regulation_constraints
--
commit 934802b5e041e184ae3df8fc8a423b7e086bf66c
Author: Paul Louvel <paul.louvel@bootlin.com>
regulator: core: Add mechanism to force disable a regulator at boot
This commit adds the regulator-boot-force-off device tree property and the
corresponding boot_force_off constraint flag to disable a regulator in
set_machine_constraints() during registration.
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 14422cfe80e2d..b45048ec084a1 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -1450,6 +1450,81 @@ static int handle_notify_limits(struct regulator_dev *rdev,
>
> return ret;
> }
> +
[ ... ]
> +static int _regulator_do_disable(struct regulator_dev *rdev)
> +{
> + int ret;
> +
> + trace_regulator_disable(rdev_get_name(rdev));
> +
> + if (rdev->ena_pin) {
> + if (rdev->ena_gpio_state) {
> + ret = regulator_ena_gpio_ctrl(rdev, false);
> + if (ret < 0)
> + return ret;
> + rdev->ena_gpio_state = 0;
> + }
> +
> + } else if (rdev->desc->ops->disable) {
> + ret = rdev->desc->ops->disable(rdev);
> + if (ret != 0)
> + return ret;
> + }
> +
> + if (rdev->desc->off_on_delay)
> + rdev->last_off = ktime_get_boottime();
> +
> + trace_regulator_disable_complete(rdev_get_name(rdev));
> +
> + return 0;
> +}
[Severity: High]
Does boot_force_off work for regulators that use an enable gpio
(rdev->ena_pin)?
During regulator_register(), rdev is zero-allocated and
regulator_ena_gpio_request() attaches rdev->ena_pin without setting
rdev->ena_gpio_state. When regulator_register() -> set_machine_constraints()
calls _regulator_do_disable(rdev) for boot_force_off (with always_on and
boot_on unset), rdev->ena_gpio_state is still 0.
In _regulator_do_disable(), when rdev->ena_pin is present and
rdev->ena_gpio_state is 0, the code skips regulator_ena_gpio_ctrl(rdev, false)
and also skips the else-if branch for rdev->desc->ops->disable(rdev).
Won't this leave gpio-controlled regulators enabled in hardware at boot?
> +
> /**
> * set_machine_constraints - sets regulator constraints
> * @rdev: regulator source
> @@ -1701,6 +1776,12 @@ static int set_machine_constraints(struct regulator_dev *rdev,
> rdev->last_off = ktime_get();
> }
>
> + if (rdev->constraints->boot_force_off) {
> + ret = _regulator_do_disable(rdev);
> + if (ret < 0)
> + return ret;
> + }
> +
> if (!rdev->constraints->pw_budget_mW)
> rdev->constraints->pw_budget_mW = INT_MAX;
>
[Severity: High]
What happens in set_machine_constraints() if boot_force_off is set together
with always_on or boot_on?
Neither of_get_regulation_constraints() nor set_machine_constraints() prevents
boot_force_off from being active at the same time as always_on or boot_on
(including when set_machine_constraints() implicitly sets
rdev->constraints->always_on = true when !rdev->ena_pin && !ops->enable).
Right before this boot_force_off check, set_machine_constraints() handles
always_on and boot_on:
drivers/regulator/core.c:set_machine_constraints() {
if (rdev->constraints->always_on || rdev->constraints->boot_on) {
...
if (rdev->supply &&
(rdev->constraints->always_on ||
!regulator_is_enabled(rdev->supply))) {
ret = (is_locked
? _regulator_enable(rdev->supply)
: regulator_enable(rdev->supply));
...
supply_enabled = true;
}
ret = _regulator_do_enable(rdev);
...
if (rdev->constraints->always_on)
rdev->use_count++;
}
}
Because boot_force_off is checked in a separate conditional afterwards,
set_machine_constraints() will enable rdev->supply and rdev, and then
immediately call _regulator_do_disable(rdev).
If _regulator_do_disable(rdev) fails after rdev->supply was enabled,
set_machine_constraints() returns the error without disabling rdev->supply,
and regulator_register() jumps to the wash cleanup path:
drivers/regulator/core.c:regulator_register() {
wash:
regulator_put(rdev->supply);
}
which triggers the warning in _regulator_put() and leaks the supply enable
count:
drivers/regulator/core.c:_regulator_put() {
/* Docs say you must disable before calling regulator_put() */
WARN_ON(regulator->enable_count);
}
And if _regulator_do_disable(rdev) succeeds when always_on or boot_on is set,
the hardware output is disabled while rdev->use_count remains 1 (for
always_on, preventing subsequent regulator_enable() calls from re-enabling the
hardware) and rdev->supply remains enabled with an unbalanced enable_count.
Should boot_force_off be mutually exclusive with always_on and boot_on?
[ ... ]
> diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
> index 09e26febfc834..337629be58ca7 100644
> --- a/drivers/regulator/of_regulator.c
> +++ b/drivers/regulator/of_regulator.c
> @@ -132,6 +132,7 @@ static int of_get_regulation_constraints(struct device *dev,
> constraints->always_on = of_property_read_bool(np, "regulator-always-on");
> if (!constraints->always_on) /* status change should be possible. */
> constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
> + constraints->boot_force_off = of_property_read_bool(np, "regulator-boot-force-off");
>
> constraints->pull_down = of_property_read_bool(np, "regulator-pull-down");
> constraints->system_critical = of_property_read_bool(np,
[Severity: Medium]
Is a new device tree property the right way to handle consumers that want to
disable a boot-enabled regulator during probe?
In the regulator framework, regulator_enable() and regulator_disable() calls
on a standard consumer handle must be balanced because regulator_get()
initializes regulator->enable_count to 0 regardless of hardware state.
For consumers that have exclusive control of a supply and need to turn off a
regulator that was left enabled at boot without a prior regulator_enable(),
regulator_get_exclusive() already syncs use_count and enable_count with the
hardware state in _regulator_get_common():
drivers/regulator/core.c:_regulator_get_common() {
if (get_type == EXCLUSIVE_GET) {
rdev->exclusive = 1;
ret = _regulator_is_enabled(rdev);
if (ret > 0) {
rdev->use_count = 1;
regulator->enable_count = 1;
}
Could the affected consumer driver use regulator_get_exclusive() (or
devm_regulator_get_exclusive()) instead of adding regulator-boot-force-off to
device tree?
> diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
> index 1fc440c5c4c7e..35ab9de96e5c7 100644
> --- a/include/linux/regulator/machine.h
> +++ b/include/linux/regulator/machine.h
> @@ -227,7 +227,8 @@ struct regulation_constraints {
> unsigned int active_discharge;
>
> /* constraint flags */
> - unsigned always_on:1; /* regulator never off when system is on */
> + unsigned always_on:1; /* regulator never off when system is on */
> + unsigned boot_force_off:1; /* force regulator off at boot */
> unsigned boot_on:1; /* bootloader/firmware enabled regulator */
> unsigned apply_uV:1; /* apply uV constraint if min == max */
> unsigned ramp_disable:1; /* disable ramp delay */
[Severity: Low]
Struct regulation_constraints in include/linux/regulator/machine.h has a
kernel-doc comment block above the definition describing its fields. Should an
@boot_force_off entry be added there as well to avoid a kernel-doc warning?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021-paul-lm51772-v1-0-25f0ffbffa8d@bootlin.com?part=3
next prev parent reply other threads:[~2026-10-21 10:46 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 10:27 [PATCH 0/5] Add TI LM51772 buck-boost voltage regulator Paul Louvel
2026-10-21 10:27 ` [PATCH 1/5] regulator: dt-bindings: Add regulator-boot-force-off property Paul Louvel
2026-10-21 17:01 ` Conor Dooley
2026-10-21 17:11 ` Paul Louvel
2026-10-22 7:08 ` Krzysztof Kozlowski
2026-10-21 10:27 ` [PATCH 2/5] regulator: dt-bindings: Add TI LM51772 support Paul Louvel
2026-10-21 10:44 ` sashiko-bot
2026-10-21 10:27 ` [PATCH 3/5] regulator: core: Add mechanism to force disable a regulator at boot Paul Louvel
2026-10-21 10:46 ` sashiko-bot [this message]
2026-10-21 15:17 ` Paul Louvel
2026-10-21 10:27 ` [PATCH 4/5] regulator: Support regulators where the voltage selector spans two registers Paul Louvel
2026-10-21 10:45 ` sashiko-bot
2026-10-21 15:10 ` Paul Louvel
2026-10-21 10:27 ` [PATCH 5/5] regulator: Add TI LM51772 support Paul Louvel
2026-10-21 10:56 ` sashiko-bot
2026-10-21 15:14 ` Paul Louvel
2026-10-21 15:10 ` Uwe Kleine-König
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-180119@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=paul.louvel@bootlin.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox