summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorThomas Petazzoni <t-petazzoni@ti.com>2010-12-03 11:31:07 +0100
committerNiket Sirsi <nsirsi@nvidia.com>2011-05-23 16:55:46 -0700
commitbfcebd948861654d11a02db03e5ac0ccbe641ab8 (patch)
tree2c593ec5ccea7ecc4b884161d3b830c0a81e5431 /drivers
parent54b9754390a04be871ab1defee7381e1fb580bbd (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> Reviewed-on: http://git.kernel.org/?p=linux/kernel/git/torvalds/ linux-2.6.git;a=commit;h=05fda3b1abc23d832144e9497fb218870927d645 Change-Id: I06ff317522fcd0018f14800cffd52f757c554c2a Reviewed-on: http://git-master/r/30955 Tested-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com>
Diffstat (limited to 'drivers')
-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 3a94ef493132..d06fee4d93b4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -133,6 +133,27 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
return 0;
}
+/* Make sure we select a voltage that suits the needs of all
+ * regulator consumers
+ */
+static int regulator_check_consumers(struct regulator_dev *rdev,
+ int *min_uV, int *max_uV)
+{
+ struct regulator *regulator;
+
+ list_for_each_entry(regulator, &rdev->consumer_list, list) {
+ if (*max_uV > regulator->max_uV)
+ *max_uV = regulator->max_uV;
+ if (*min_uV < regulator->min_uV)
+ *min_uV = regulator->min_uV;
+ }
+
+ if (*min_uV > *max_uV)
+ return -EINVAL;
+
+ return 0;
+}
+
/* current constraint check */
static int regulator_check_current_limit(struct regulator_dev *rdev,
int *min_uA, int *max_uA)
@@ -1639,6 +1660,10 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
+ ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
+ if (ret < 0)
+ goto out;
+
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
trace_regulator_set_voltage_complete(rdev_get_name(rdev), -1);