aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-24 06:11:33 -0400
committerMark Brown <broonie@linaro.org>2013-10-24 06:11:33 -0400
commit81e439f476a397af695e8141df6e7324a8ac4893 (patch)
tree8a79f8d7805e4f2f838a39cdc751d43a987ee1e1 /drivers
parentcea64d8c089289baede77c324e706d748e87725f (diff)
parent5df529d440aa4f0e67be9af3718e7edf05db7d02 (diff)
Merge remote-tracking branch 'regulator/topic/core' into regulator-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/core.c76
-rw-r--r--drivers/regulator/of_regulator.c6
2 files changed, 76 insertions, 6 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 16427de56ce8..916cadf45279 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -919,6 +919,36 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
919 return 0; 919 return 0;
920} 920}
921 921
922static int machine_constraints_current(struct regulator_dev *rdev,
923 struct regulation_constraints *constraints)
924{
925 struct regulator_ops *ops = rdev->desc->ops;
926 int ret;
927
928 if (!constraints->min_uA && !constraints->max_uA)
929 return 0;
930
931 if (constraints->min_uA > constraints->max_uA) {
932 rdev_err(rdev, "Invalid current constraints\n");
933 return -EINVAL;
934 }
935
936 if (!ops->set_current_limit || !ops->get_current_limit) {
937 rdev_warn(rdev, "Operation of current configuration missing\n");
938 return 0;
939 }
940
941 /* Set regulator current in constraints range */
942 ret = ops->set_current_limit(rdev, constraints->min_uA,
943 constraints->max_uA);
944 if (ret < 0) {
945 rdev_err(rdev, "Failed to set current constraint, %d\n", ret);
946 return ret;
947 }
948
949 return 0;
950}
951
922/** 952/**
923 * set_machine_constraints - sets regulator constraints 953 * set_machine_constraints - sets regulator constraints
924 * @rdev: regulator source 954 * @rdev: regulator source
@@ -949,6 +979,10 @@ static int set_machine_constraints(struct regulator_dev *rdev,
949 if (ret != 0) 979 if (ret != 0)
950 goto out; 980 goto out;
951 981
982 ret = machine_constraints_current(rdev, rdev->constraints);
983 if (ret != 0)
984 goto out;
985
952 /* do we need to setup our suspend state */ 986 /* do we need to setup our suspend state */
953 if (rdev->constraints->initial_state) { 987 if (rdev->constraints->initial_state) {
954 ret = suspend_prepare(rdev, rdev->constraints->initial_state); 988 ret = suspend_prepare(rdev, rdev->constraints->initial_state);
@@ -1182,6 +1216,8 @@ overflow_err:
1182 1216
1183static int _regulator_get_enable_time(struct regulator_dev *rdev) 1217static int _regulator_get_enable_time(struct regulator_dev *rdev)
1184{ 1218{
1219 if (rdev->constraints && rdev->constraints->enable_time)
1220 return rdev->constraints->enable_time;
1185 if (!rdev->desc->ops->enable_time) 1221 if (!rdev->desc->ops->enable_time)
1186 return rdev->desc->enable_time; 1222 return rdev->desc->enable_time;
1187 return rdev->desc->ops->enable_time(rdev); 1223 return rdev->desc->ops->enable_time(rdev);
@@ -1276,7 +1312,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
1276 1312
1277 if (id == NULL) { 1313 if (id == NULL) {
1278 pr_err("get() with no identifier\n"); 1314 pr_err("get() with no identifier\n");
1279 return regulator; 1315 return ERR_PTR(-EINVAL);
1280 } 1316 }
1281 1317
1282 if (dev) 1318 if (dev)
@@ -1733,11 +1769,39 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
1733 * together. */ 1769 * together. */
1734 trace_regulator_enable_delay(rdev_get_name(rdev)); 1770 trace_regulator_enable_delay(rdev_get_name(rdev));
1735 1771
1736 if (delay >= 1000) { 1772 /*
1737 mdelay(delay / 1000); 1773 * Delay for the requested amount of time as per the guidelines in:
1738 udelay(delay % 1000); 1774 *
1739 } else if (delay) { 1775 * Documentation/timers/timers-howto.txt
1740 udelay(delay); 1776 *
1777 * The assumption here is that regulators will never be enabled in
1778 * atomic context and therefore sleeping functions can be used.
1779 */
1780 if (delay) {
1781 unsigned int ms = delay / 1000;
1782 unsigned int us = delay % 1000;
1783
1784 if (ms > 0) {
1785 /*
1786 * For small enough values, handle super-millisecond
1787 * delays in the usleep_range() call below.
1788 */
1789 if (ms < 20)
1790 us += ms * 1000;
1791 else
1792 msleep(ms);
1793 }
1794
1795 /*
1796 * Give the scheduler some room to coalesce with any other
1797 * wakeup sources. For delays shorter than 10 us, don't even
1798 * bother setting up high-resolution timers and just busy-
1799 * loop.
1800 */
1801 if (us >= 10)
1802 usleep_range(us, us + 100);
1803 else
1804 udelay(us);
1741 } 1805 }
1742 1806
1743 trace_regulator_enable_complete(rdev_get_name(rdev)); 1807 trace_regulator_enable_complete(rdev_get_name(rdev));
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 7827384680d6..ea4f36f2cbe2 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -23,6 +23,8 @@ static void of_get_regulation_constraints(struct device_node *np,
23 const __be32 *min_uA, *max_uA, *ramp_delay; 23 const __be32 *min_uA, *max_uA, *ramp_delay;
24 struct property *prop; 24 struct property *prop;
25 struct regulation_constraints *constraints = &(*init_data)->constraints; 25 struct regulation_constraints *constraints = &(*init_data)->constraints;
26 int ret;
27 u32 pval;
26 28
27 constraints->name = of_get_property(np, "regulator-name", NULL); 29 constraints->name = of_get_property(np, "regulator-name", NULL);
28 30
@@ -73,6 +75,10 @@ static void of_get_regulation_constraints(struct device_node *np,
73 else 75 else
74 constraints->ramp_disable = true; 76 constraints->ramp_disable = true;
75 } 77 }
78
79 ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
80 if (!ret)
81 constraints->enable_time = pval;
76} 82}
77 83
78/** 84/**