diff options
-rw-r--r-- | drivers/regulator/core.c | 41 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 6 |
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 | ||
1088 | static 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 */ |
1088 | static struct regulator *_regulator_get(struct device *dev, const char *id, | 1096 | static 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() */ |
1252 | static int _regulator_enable(struct regulator_dev *rdev) | 1260 | static 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. |