diff options
author | Christian Kohlschütter <christian@kohlschutter.com> | 2022-08-29 16:55:43 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-08-29 21:16:23 +0100 |
commit | 520fb178212d1dd545ed0ed231df09111b30ab7e (patch) | |
tree | 86fdb5db6b082e8f310671df217505e4a5402548 /drivers | |
parent | b662748ff2e8ff99daabdfbd928270f25f29a9fd (diff) | |
download | linux-stable-520fb178212d1dd545ed0ed231df09111b30ab7e.tar.gz linux-stable-520fb178212d1dd545ed0ed231df09111b30ab7e.tar.bz2 linux-stable-520fb178212d1dd545ed0ed231df09111b30ab7e.zip |
regulator: core: Fix regulator supply registration with sysfs
In "regulator: core: Resolve supply name earlier to prevent
double-init", we introduced a bug that prevented the regulator names
from registering properly with sysfs.
Reorder regulator_register such that supply names are properly resolved
and registered.
Fixes: 8a866d527ac0 ("regulator: core: Resolve supply name earlier to prevent double-init")
Link: https://lore.kernel.org/all/58b92e75-f373-dae7-7031-8abd465bb874@samsung.com/
Signed-off-by: Christian Kohlschütter <christian@kohlschutter.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20220829165543.24856-1-christian@kohlschutter.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/core.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c17d3418d7bf..a8dab5a93607 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5409,6 +5409,7 @@ regulator_register(const struct regulator_desc *regulator_desc, bool dangling_of_gpiod = false; struct device *dev; int ret, i; + bool resolved_early = false; if (cfg == NULL) return ERR_PTR(-EINVAL); @@ -5512,6 +5513,18 @@ regulator_register(const struct regulator_desc *regulator_desc, BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work); + if (init_data && init_data->supply_regulator) + rdev->supply_name = init_data->supply_regulator; + else if (regulator_desc->supply_name) + rdev->supply_name = regulator_desc->supply_name; + + /* register with sysfs */ + rdev->dev.class = ®ulator_class; + rdev->dev.parent = dev; + dev_set_name(&rdev->dev, "regulator.%lu", + (unsigned long) atomic_inc_return(®ulator_no)); + dev_set_drvdata(&rdev->dev, rdev); + /* set regulator constraints */ if (init_data) rdev->constraints = kmemdup(&init_data->constraints, @@ -5522,33 +5535,25 @@ regulator_register(const struct regulator_desc *regulator_desc, GFP_KERNEL); if (!rdev->constraints) { ret = -ENOMEM; - goto clean; + goto wash; } - if (init_data && init_data->supply_regulator) - rdev->supply_name = init_data->supply_regulator; - else if (regulator_desc->supply_name) - rdev->supply_name = regulator_desc->supply_name; - if ((rdev->supply_name && !rdev->supply) && - (rdev->constraints->always_on || - rdev->constraints->boot_on)) { - /* Try to resolve the name of the supplying regulator here first - * so we prevent double-initializing the regulator, which may - * cause timing-specific voltage brownouts/glitches that are - * hard to debug. - */ + (rdev->constraints->always_on || + rdev->constraints->boot_on)) { ret = regulator_resolve_supply(rdev); if (ret) rdev_dbg(rdev, "unable to resolve supply early: %pe\n", ERR_PTR(ret)); + + resolved_early = true; } /* perform any regulator specific init */ if (init_data && init_data->regulator_init) { ret = init_data->regulator_init(rdev->reg_data); if (ret < 0) - goto clean; + goto wash; } if (config->ena_gpiod) { @@ -5556,22 +5561,15 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO: %pe\n", ERR_PTR(ret)); - goto clean; + goto wash; } /* The regulator core took over the GPIO descriptor */ dangling_cfg_gpiod = false; dangling_of_gpiod = false; } - /* register with sysfs */ - rdev->dev.class = ®ulator_class; - rdev->dev.parent = dev; - dev_set_name(&rdev->dev, "regulator.%lu", - (unsigned long) atomic_inc_return(®ulator_no)); - dev_set_drvdata(&rdev->dev, rdev); - ret = set_machine_constraints(rdev); - if (ret == -EPROBE_DEFER) { + if (ret == -EPROBE_DEFER && !resolved_early) { /* Regulator might be in bypass mode and so needs its supply * to set the constraints */ |