diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-05 05:27:45 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-05 05:27:45 +0300 |
commit | d40c874573145b4af3b3b6205f3741b498697623 (patch) | |
tree | 65a81c9df4e489cc661038c6c2771141174be25d /drivers/regulator/core.c | |
parent | 521d04e3c8a7dda4ed1ee1630e92d370688f6b33 (diff) | |
parent | 392cc0a4a0c4b25534f3148b192f18be468f67bd (diff) | |
download | linux-d40c874573145b4af3b3b6205f3741b498697623.tar.xz |
Merge tag 'regulator-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown:
"The core work this time around has mostly been around the code to
manage regulator modes, simplifying the interface for configuring
modes to not take account of the voltage and as a side effect
resolving a bootstrapping issue on systems where we can't read the
voltage from the regulator.
Otherwise it's been quite a quiet release with some new drivers and a
devm helper:
- Make the load handling in the Qualcomm RPMH regulators much more
idiomatic and general cleanups to the handling of load
configuration
- devm helper for a combined get and enable operation
- Support for MediaTek MT6331, Qualcomm PM660, 660L and PM6125, Texas
Instruments TPS65219"
* tag 'regulator-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (45 commits)
dt-bindings: gpio-regulator: add vin-supply property support
regulator: gpio: Add input_supply support in gpio_regulator_config
regulator: tps65219: Fix is_enabled checking in tps65219_set_bypass
regulator: qcom,rpmh: add pm660 and pm660l pmics
regulator: qcom-rpmh: add pm660 and pm660l pmics
regulator: of: Fix kernel-doc
regulator: of: Fix kernel-doc
regulator: Add driver for MT6332 PMIC regulators
regulator: Add bindings for MT6332 regulator
regulator: Add driver for MT6331 PMIC regulators
regulator: Add bindings for MT6331 regulator
regulator: tps65219: Fix .bypass_val_on setting
regulator: qcom_rpm: Fix circular deferral regression
regulator: core: Prevent integer underflow
regulator: dt-bindings: qcom,rpmh: Indicate regulator-allow-set-load dependencies
regulator: bd9576: switch to using devm_fwnode_gpiod_get()
regulator: bd71815: switch to using devm_fwnode_gpiod_get()
regulator: core: Fix regulator supply registration with sysfs
regulator: tps65219: change tps65219_regulator_irq_types to static
regulator: core: Don't err if allow-set-load but no allowed-modes
...
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r-- | drivers/regulator/core.c | 98 |
1 files changed, 63 insertions, 35 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d3e8dc32832d..bcccad8f7516 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -977,12 +977,27 @@ static int drms_uA_update(struct regulator_dev *rdev) rdev_err(rdev, "failed to set load %d: %pe\n", current_uA, ERR_PTR(err)); } else { + /* + * Unfortunately in some cases the constraints->valid_ops has + * REGULATOR_CHANGE_DRMS but there are no valid modes listed. + * That's not really legit but we won't consider it a fatal + * error here. We'll treat it as if REGULATOR_CHANGE_DRMS + * wasn't set. + */ + if (!rdev->constraints->valid_modes_mask) { + rdev_dbg(rdev, "Can change modes; but no valid mode\n"); + return 0; + } + /* get output voltage */ output_uV = regulator_get_voltage_rdev(rdev); - if (output_uV <= 0) { - rdev_err(rdev, "invalid output voltage found\n"); - return -EINVAL; - } + + /* + * Don't return an error; if regulator driver cares about + * output_uV then it's up to the driver to validate. + */ + if (output_uV <= 0) + rdev_dbg(rdev, "invalid output voltage found\n"); /* get input voltage */ input_uV = 0; @@ -990,10 +1005,13 @@ static int drms_uA_update(struct regulator_dev *rdev) input_uV = regulator_get_voltage(rdev->supply); if (input_uV <= 0) input_uV = rdev->constraints->input_uV; - if (input_uV <= 0) { - rdev_err(rdev, "invalid input voltage found\n"); - return -EINVAL; - } + + /* + * Don't return an error; if regulator driver cares about + * input_uV then it's up to the driver to validate. + */ + if (input_uV <= 0) + rdev_dbg(rdev, "invalid input voltage found\n"); /* now get the optimum mode for our new total regulator load */ mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, @@ -2681,7 +2699,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * return -ETIMEDOUT. */ if (rdev->desc->poll_enabled_time) { - unsigned int time_remaining = delay; + int time_remaining = delay; while (time_remaining > 0) { _regulator_delay_helper(rdev->desc->poll_enabled_time); @@ -3502,10 +3520,8 @@ static int _regulator_set_voltage_time(struct regulator_dev *rdev, (new_uV < old_uV)) return rdev->constraints->settling_time_down; - if (ramp_delay == 0) { - rdev_dbg(rdev, "ramp_delay not set\n"); + if (ramp_delay == 0) return 0; - } return DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay); } @@ -5398,6 +5414,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); @@ -5501,24 +5518,10 @@ regulator_register(const struct regulator_desc *regulator_desc, BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work); - /* preform any regulator specific init */ - if (init_data && init_data->regulator_init) { - ret = init_data->regulator_init(rdev->reg_data); - if (ret < 0) - goto clean; - } - - if (config->ena_gpiod) { - ret = regulator_ena_gpio_request(rdev, config); - if (ret != 0) { - rdev_err(rdev, "Failed to request enable GPIO: %pe\n", - ERR_PTR(ret)); - goto clean; - } - /* The regulator core took over the GPIO descriptor */ - dangling_cfg_gpiod = false; - dangling_of_gpiod = false; - } + 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; @@ -5540,13 +5543,38 @@ regulator_register(const struct regulator_desc *regulator_desc, 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)) { + 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 wash; + } + + if (config->ena_gpiod) { + ret = regulator_ena_gpio_request(rdev, config); + if (ret != 0) { + rdev_err(rdev, "Failed to request enable GPIO: %pe\n", + ERR_PTR(ret)); + goto wash; + } + /* The regulator core took over the GPIO descriptor */ + dangling_cfg_gpiod = false; + dangling_of_gpiod = false; + } 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 */ |