X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=drivers%2Fregulator%2Fcore.c;h=67426c0477d34b2b5805826664bbc4074acfe591;hb=abb5a14fa20fdd400995926134b7be9eb8ce6048;hp=db320e8fa865f96c0742777403baab9ac4c218a8;hpb=f44dd184634d401f5cf88a6d8b4a60d5ff4f417f;p=cascardo%2Flinux.git diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index db320e8fa865..67426c0477d3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -679,24 +679,6 @@ static int drms_uA_update(struct regulator_dev *rdev) !rdev->desc->ops->set_load) return -EINVAL; - /* get output voltage */ - output_uV = _regulator_get_voltage(rdev); - if (output_uV <= 0) { - rdev_err(rdev, "invalid output voltage found\n"); - return -EINVAL; - } - - /* get input voltage */ - input_uV = 0; - if (rdev->supply) - 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; - } - /* calc total requested load */ list_for_each_entry(sibling, &rdev->consumer_list, list) current_uA += sibling->uA_load; @@ -709,6 +691,24 @@ static int drms_uA_update(struct regulator_dev *rdev) if (err < 0) rdev_err(rdev, "failed to set load %d\n", current_uA); } else { + /* get output voltage */ + output_uV = _regulator_get_voltage(rdev); + if (output_uV <= 0) { + rdev_err(rdev, "invalid output voltage found\n"); + return -EINVAL; + } + + /* get input voltage */ + input_uV = 0; + if (rdev->supply) + 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; + } + /* now get the optimum mode for our new total regulator load */ mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, output_uV, current_uA); @@ -2743,6 +2743,24 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev, return ret; } +static int _regulator_set_voltage_time(struct regulator_dev *rdev, + int old_uV, int new_uV) +{ + unsigned int ramp_delay = 0; + + if (rdev->constraints->ramp_delay) + ramp_delay = rdev->constraints->ramp_delay; + else if (rdev->desc->ramp_delay) + ramp_delay = rdev->desc->ramp_delay; + + if (ramp_delay == 0) { + rdev_warn(rdev, "ramp_delay not set\n"); + return 0; + } + + return DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay); +} + static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { @@ -2751,6 +2769,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, int best_val = 0; unsigned int selector; int old_selector = -1; + const struct regulator_ops *ops = rdev->desc->ops; + int old_uV = _regulator_get_voltage(rdev); trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); @@ -2762,29 +2782,28 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, * info to call set_voltage_time_sel(). */ if (_regulator_is_enabled(rdev) && - rdev->desc->ops->set_voltage_time_sel && - rdev->desc->ops->get_voltage_sel) { - old_selector = rdev->desc->ops->get_voltage_sel(rdev); + ops->set_voltage_time_sel && ops->get_voltage_sel) { + old_selector = ops->get_voltage_sel(rdev); if (old_selector < 0) return old_selector; } - if (rdev->desc->ops->set_voltage) { + if (ops->set_voltage) { ret = _regulator_call_set_voltage(rdev, min_uV, max_uV, &selector); if (ret >= 0) { - if (rdev->desc->ops->list_voltage) - best_val = rdev->desc->ops->list_voltage(rdev, - selector); + if (ops->list_voltage) + best_val = ops->list_voltage(rdev, + selector); else best_val = _regulator_get_voltage(rdev); } - } else if (rdev->desc->ops->set_voltage_sel) { + } else if (ops->set_voltage_sel) { ret = regulator_map_voltage(rdev, min_uV, max_uV); if (ret >= 0) { - best_val = rdev->desc->ops->list_voltage(rdev, ret); + best_val = ops->list_voltage(rdev, ret); if (min_uV <= best_val && max_uV >= best_val) { selector = ret; if (old_selector == selector) @@ -2800,34 +2819,50 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ret = -EINVAL; } - /* Call set_voltage_time_sel if successfully obtained old_selector */ - if (ret == 0 && !rdev->constraints->ramp_disable && old_selector >= 0 - && old_selector != selector) { + if (ret) + goto out; - delay = rdev->desc->ops->set_voltage_time_sel(rdev, - old_selector, selector); - if (delay < 0) { - rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", - delay); - delay = 0; + if (ops->set_voltage_time_sel) { + /* + * Call set_voltage_time_sel if successfully obtained + * old_selector + */ + if (old_selector >= 0 && old_selector != selector) + delay = ops->set_voltage_time_sel(rdev, old_selector, + selector); + } else { + if (old_uV != best_val) { + if (ops->set_voltage_time) + delay = ops->set_voltage_time(rdev, old_uV, + best_val); + else + delay = _regulator_set_voltage_time(rdev, + old_uV, + best_val); } + } - /* Insert any necessary delays */ - if (delay >= 1000) { - mdelay(delay / 1000); - udelay(delay % 1000); - } else if (delay) { - udelay(delay); - } + if (delay < 0) { + rdev_warn(rdev, "failed to get delay: %d\n", delay); + delay = 0; } - if (ret == 0 && best_val >= 0) { + /* Insert any necessary delays */ + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } + + if (best_val >= 0) { unsigned long data = best_val; _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, (void *)data); } +out: trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val); return ret; @@ -2998,9 +3033,13 @@ int regulator_set_voltage_time(struct regulator *regulator, int voltage; int i; + if (ops->set_voltage_time) + return ops->set_voltage_time(rdev, old_uV, new_uV); + else if (!ops->set_voltage_time_sel) + return _regulator_set_voltage_time(rdev, old_uV, new_uV); + /* Currently requires operations to do this */ - if (!ops->list_voltage || !ops->set_voltage_time_sel - || !rdev->desc->n_voltages) + if (!ops->list_voltage || !rdev->desc->n_voltages) return -EINVAL; for (i = 0; i < rdev->desc->n_voltages; i++) { @@ -3039,19 +3078,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) { - unsigned int ramp_delay = 0; int old_volt, new_volt; - if (rdev->constraints->ramp_delay) - ramp_delay = rdev->constraints->ramp_delay; - else if (rdev->desc->ramp_delay) - ramp_delay = rdev->desc->ramp_delay; - - if (ramp_delay == 0) { - rdev_warn(rdev, "ramp_delay not set\n"); - return 0; - } - /* sanity check */ if (!rdev->desc->ops->list_voltage) return -EINVAL; @@ -3059,7 +3087,11 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, old_volt = rdev->desc->ops->list_voltage(rdev, old_selector); new_volt = rdev->desc->ops->list_voltage(rdev, new_selector); - return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); + if (rdev->desc->ops->set_voltage_time) + return rdev->desc->ops->set_voltage_time(rdev, old_volt, + new_volt); + else + return _regulator_set_voltage_time(rdev, old_volt, new_volt); } EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); @@ -3483,10 +3515,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = _regulator_get(dev, - consumers[i].supply, - false, - !consumers[i].optional); + consumers[i].consumer = regulator_get(dev, + consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n",