aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c41
-rw-r--r--include/linux/regulator/driver.h6
2 files changed, 41 insertions, 6 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6d2ce8a0533..ca8e1642538 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);
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 31f2055eae2..592cd7c642c 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -58,6 +58,9 @@ enum regulator_status {
58 * @get_optimum_mode: Get the most efficient operating mode for the regulator 58 * @get_optimum_mode: Get the most efficient operating mode for the regulator
59 * when running with the specified parameters. 59 * when running with the specified parameters.
60 * 60 *
61 * @enable_time: Time taken for the regulator voltage output voltage to
62 * stabalise after being enabled, in microseconds.
63 *
61 * @set_suspend_voltage: Set the voltage for the regulator when the system 64 * @set_suspend_voltage: Set the voltage for the regulator when the system
62 * is suspended. 65 * is suspended.
63 * @set_suspend_enable: Mark the regulator as enabled when the system is 66 * @set_suspend_enable: Mark the regulator as enabled when the system is
@@ -93,6 +96,9 @@ struct regulator_ops {
93 int (*set_mode) (struct regulator_dev *, unsigned int mode); 96 int (*set_mode) (struct regulator_dev *, unsigned int mode);
94 unsigned int (*get_mode) (struct regulator_dev *); 97 unsigned int (*get_mode) (struct regulator_dev *);
95 98
99 /* Time taken to enable the regulator */
100 int (*enable_time) (struct regulator_dev *);
101
96 /* report regulator status ... most other accessors report 102 /* report regulator status ... most other accessors report
97 * control inputs, this reports results of combining inputs 103 * control inputs, this reports results of combining inputs
98 * from Linux (and other sources) with the actual load. 104 * from Linux (and other sources) with the actual load.