aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-21 07:21:52 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-03-03 09:49:23 -0500
commit31aae2beeb3d601d556b6a8c39085940ad1e9f42 (patch)
tree7a608cabf48e020c5d23e8a96a59c095f0946d2b /drivers/regulator
parent84b6826306119dc3c41ef9d7ed6c408112f63301 (diff)
regulator: Allow regulators to specify the time taken to ramp on enable
Regulators may sometimes take longer to enable than the control operation used to do so, either because the regulator has ramp rate control used to limit inrush current or because the control operation is very fast (GPIO being the most common example of this). In order to ensure that consumers do not rely on the regulator before it is enabled provide an enable_time() operation and have the core delay for that time before returning to the caller. This is implemented as a function since the ramp rate may be specified in voltage per unit time and therefore the time depend on the configuration. In future it would be desirable to allow the bulk operations to run the delays for multiple enables in parallel but this is not currently supported. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/core.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6d2ce8a05331..ca8e1642538b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -19,6 +19,7 @@
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/mutex.h> 20#include <linux/mutex.h>
21#include <linux/suspend.h> 21#include <linux/suspend.h>
22#include <linux/delay.h>
22#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
23#include <linux/regulator/driver.h> 24#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h> 25#include <linux/regulator/machine.h>
@@ -1084,6 +1085,13 @@ overflow_err:
1084 return NULL; 1085 return NULL;
1085} 1086}
1086 1087
1088static int _regulator_get_enable_time(struct regulator_dev *rdev)
1089{
1090 if (!rdev->desc->ops->enable_time)
1091 return 0;
1092 return rdev->desc->ops->enable_time(rdev);
1093}
1094
1087/* Internal regulator request function */ 1095/* Internal regulator request function */
1088static struct regulator *_regulator_get(struct device *dev, const char *id, 1096static struct regulator *_regulator_get(struct device *dev, const char *id,
1089 int exclusive) 1097 int exclusive)
@@ -1251,7 +1259,7 @@ static int _regulator_can_change_status(struct regulator_dev *rdev)
1251/* locks held by regulator_enable() */ 1259/* locks held by regulator_enable() */
1252static int _regulator_enable(struct regulator_dev *rdev) 1260static int _regulator_enable(struct regulator_dev *rdev)
1253{ 1261{
1254 int ret; 1262 int ret, delay;
1255 1263
1256 /* do we need to enable the supply regulator first */ 1264 /* do we need to enable the supply regulator first */
1257 if (rdev->supply) { 1265 if (rdev->supply) {
@@ -1275,13 +1283,34 @@ static int _regulator_enable(struct regulator_dev *rdev)
1275 if (!_regulator_can_change_status(rdev)) 1283 if (!_regulator_can_change_status(rdev))
1276 return -EPERM; 1284 return -EPERM;
1277 1285
1278 if (rdev->desc->ops->enable) { 1286 if (!rdev->desc->ops->enable)
1279 ret = rdev->desc->ops->enable(rdev);
1280 if (ret < 0)
1281 return ret;
1282 } else {
1283 return -EINVAL; 1287 return -EINVAL;
1288
1289 /* Query before enabling in case configuration
1290 * dependant. */
1291 ret = _regulator_get_enable_time(rdev);
1292 if (ret >= 0) {
1293 delay = ret;
1294 } else {
1295 printk(KERN_WARNING
1296 "%s: enable_time() failed for %s: %d\n",
1297 __func__, rdev_get_name(rdev),
1298 ret);
1299 delay = 0;
1284 } 1300 }
1301
1302 /* Allow the regulator to ramp; it would be useful
1303 * to extend this for bulk operations so that the
1304 * regulators can ramp together. */
1305 ret = rdev->desc->ops->enable(rdev);
1306 if (ret < 0)
1307 return ret;
1308
1309 if (delay >= 1000)
1310 mdelay(delay / 1000);
1311 else if (delay)
1312 udelay(delay);
1313
1285 } else if (ret < 0) { 1314 } else if (ret < 0) {
1286 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", 1315 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
1287 __func__, rdev_get_name(rdev), ret); 1316 __func__, rdev_get_name(rdev), ret);