aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorThomas Petazzoni <t-petazzoni@ti.com>2010-12-03 05:31:07 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2011-01-12 09:33:01 -0500
commit05fda3b1abc23d832144e9497fb218870927d645 (patch)
tree6f847a88c7d6fbbdc90b6457cc29acc252b0e92a /drivers/regulator
parent5da84fd99bb1ab1c7cd39d0cf7c08bb63931a59a (diff)
regulator: Take into account the requirements of all consumers
Extend the regulator_set_voltage() function to take into account the voltage requirements of all consumers of the regulator being changed, in order to set the voltage to the minimum voltage acceptable to all consumers. The existing behaviour was that the latest regulator_set_voltage() call would win over previous regulator_set_voltage() calls even if setting the voltage to a non-acceptable level from other consumers. Signed-off-by: Thomas Petazzoni <t-petazzoni@ti.com> Cc: Liam Girdwood <lrg@slimlogic.co.uk> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Acked-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.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e63366f826f9..a1b12379b09f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -142,6 +142,27 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
142 return 0; 142 return 0;
143} 143}
144 144
145/* Make sure we select a voltage that suits the needs of all
146 * regulator consumers
147 */
148static int regulator_check_consumers(struct regulator_dev *rdev,
149 int *min_uV, int *max_uV)
150{
151 struct regulator *regulator;
152
153 list_for_each_entry(regulator, &rdev->consumer_list, list) {
154 if (*max_uV > regulator->max_uV)
155 *max_uV = regulator->max_uV;
156 if (*min_uV < regulator->min_uV)
157 *min_uV = regulator->min_uV;
158 }
159
160 if (*min_uV > *max_uV)
161 return -EINVAL;
162
163 return 0;
164}
165
145/* current constraint check */ 166/* current constraint check */
146static int regulator_check_current_limit(struct regulator_dev *rdev, 167static int regulator_check_current_limit(struct regulator_dev *rdev,
147 int *min_uA, int *max_uA) 168 int *min_uA, int *max_uA)
@@ -1637,6 +1658,10 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1637 regulator->min_uV = min_uV; 1658 regulator->min_uV = min_uV;
1638 regulator->max_uV = max_uV; 1659 regulator->max_uV = max_uV;
1639 1660
1661 ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
1662 if (ret < 0)
1663 goto out;
1664
1640 trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); 1665 trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
1641 1666
1642 ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); 1667 ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector);