diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-12-16 16:49:36 +0100 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2011-01-12 15:33:05 +0100 |
commit | 606a25628187ce863b48d43ca42bc0cbe8342de9 (patch) | |
tree | 98057c2d49e5fccb8d9e72d2b961a4f28585afeb /drivers/regulator | |
parent | regulator: Staticise non-exported functions in mc13892 (diff) | |
download | linux-606a25628187ce863b48d43ca42bc0cbe8342de9.tar.xz linux-606a25628187ce863b48d43ca42bc0cbe8342de9.zip |
regulator: Add API to re-apply voltage to hardware
When cooperating with an external control source the regulator setup
may be changed underneath the API. Currently consumers can just redo
the regulator_set_voltage() to restore a previously set configuration
but provide an explicit API for doing this as optimsations in the
regulator_set_voltage() implementation will shortly prevent that.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3d72cc8e2f3e..a12cba32460e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1727,6 +1727,53 @@ out: } EXPORT_SYMBOL_GPL(regulator_set_voltage); +/** + * regulator_sync_voltage - re-apply last regulator output voltage + * @regulator: regulator source + * + * Re-apply the last configured voltage. This is intended to be used + * where some external control source the consumer is cooperating with + * has caused the configured voltage to change. + */ +int regulator_sync_voltage(struct regulator *regulator) +{ + struct regulator_dev *rdev = regulator->rdev; + int ret, min_uV, max_uV; + + mutex_lock(&rdev->mutex); + + if (!rdev->desc->ops->set_voltage && + !rdev->desc->ops->set_voltage_sel) { + ret = -EINVAL; + goto out; + } + + /* This is only going to work if we've had a voltage configured. */ + if (!regulator->min_uV && !regulator->max_uV) { + ret = -EINVAL; + goto out; + } + + min_uV = regulator->min_uV; + max_uV = regulator->max_uV; + + /* This should be a paranoia check... */ + ret = regulator_check_voltage(rdev, &min_uV, &max_uV); + if (ret < 0) + goto out; + + ret = regulator_check_consumers(rdev, &min_uV, &max_uV); + if (ret < 0) + goto out; + + ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); + +out: + mutex_unlock(&rdev->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(regulator_sync_voltage); + static int _regulator_get_voltage(struct regulator_dev *rdev) { int sel; |