summaryrefslogtreecommitdiff
path: root/drivers/regulator/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r--drivers/regulator/core.c98
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 = &regulator_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
*/