in core.c [750:806]
static int _generic_set_opp_regulator(struct opp_table *opp_table,
struct device *dev,
struct dev_pm_opp *opp,
unsigned long freq,
int scaling_down)
{
struct regulator *reg = opp_table->regulators[0];
struct dev_pm_opp *old_opp = opp_table->current_opp;
int ret;
/* This function only supports single regulator per device */
if (WARN_ON(opp_table->regulator_count > 1)) {
dev_err(dev, "multiple regulators are not supported\n");
return -EINVAL;
}
/* Scaling up? Scale voltage before frequency */
if (!scaling_down) {
ret = _set_opp_voltage(dev, reg, opp->supplies);
if (ret)
goto restore_voltage;
}
/* Change frequency */
ret = _generic_set_opp_clk_only(dev, opp_table->clk, freq);
if (ret)
goto restore_voltage;
/* Scaling down? Scale voltage after frequency */
if (scaling_down) {
ret = _set_opp_voltage(dev, reg, opp->supplies);
if (ret)
goto restore_freq;
}
/*
* Enable the regulator after setting its voltages, otherwise it breaks
* some boot-enabled regulators.
*/
if (unlikely(!opp_table->enabled)) {
ret = regulator_enable(reg);
if (ret < 0)
dev_warn(dev, "Failed to enable regulator: %d", ret);
}
return 0;
restore_freq:
if (_generic_set_opp_clk_only(dev, opp_table->clk, old_opp->rate))
dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
__func__, old_opp->rate);
restore_voltage:
/* This shouldn't harm even if the voltages weren't updated earlier */
_set_opp_voltage(dev, reg, old_opp->supplies);
return ret;
}