]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
regulator: core: disable supply if enabling main regulator fails
authorGabor Juhos <j4g8y7@gmail.com>
Fri, 7 Nov 2025 17:10:08 +0000 (18:10 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 7 Nov 2025 17:37:47 +0000 (17:37 +0000)
For 'always-on' and 'boot-on' regulators, the set_machine_constraints()
may enable supply before enabling the main regulator, however if the
latter fails, the function returns with an error but the supply remains
enabled.

When this happens, the regulator_register() function continues on the
error path where it puts the supply regulator. Since enabling the supply
is not balanced with a disable call, a warning similar to the following
gets issued from _regulator_put():

    [    1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0
    [    1.603908] Modules linked in:
    [    1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE
    [    1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT)
    [    1.603945] Workqueue: async async_run_entry_fn
    [    1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
    [    1.603967] pc : _regulator_put+0x8c/0xa0
    [    1.603976] lr : _regulator_put+0x7c/0xa0
    ...
    [    1.604140] Call trace:
    [    1.604145]  _regulator_put+0x8c/0xa0 (P)
    [    1.604156]  regulator_register+0x2ec/0xbf0
    [    1.604166]  devm_regulator_register+0x60/0xb0
    [    1.604178]  rpm_reg_probe+0x120/0x208
    [    1.604187]  platform_probe+0x64/0xa8
    ...

In order to avoid this, change the set_machine_constraints() function to
disable the supply if enabling the main regulator fails.

Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies")
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/regulator/core.c

index 84bc38911dba308539a25dd3af30a5c24802b890..2eab56df042e6b05abf0989f425dc161c7b0e66d 100644 (file)
@@ -1631,6 +1631,8 @@ static int set_machine_constraints(struct regulator_dev *rdev)
         * and we have control then make sure it is enabled.
         */
        if (rdev->constraints->always_on || rdev->constraints->boot_on) {
+               bool supply_enabled = false;
+
                /* If we want to enable this regulator, make sure that we know
                 * the supplying regulator.
                 */
@@ -1650,11 +1652,14 @@ static int set_machine_constraints(struct regulator_dev *rdev)
                                rdev->supply = NULL;
                                return ret;
                        }
+                       supply_enabled = true;
                }
 
                ret = _regulator_do_enable(rdev);
                if (ret < 0 && ret != -EINVAL) {
                        rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret));
+                       if (supply_enabled)
+                               regulator_disable(rdev->supply);
                        return ret;
                }