|
@@ -19,6 +19,7 @@
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/mutex.h>
|
|
|
#include <linux/suspend.h>
|
|
|
+#include <linux/delay.h>
|
|
|
#include <linux/regulator/consumer.h>
|
|
|
#include <linux/regulator/driver.h>
|
|
|
#include <linux/regulator/machine.h>
|
|
@@ -1084,6 +1085,13 @@ overflow_err:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static int _regulator_get_enable_time(struct regulator_dev *rdev)
|
|
|
+{
|
|
|
+ if (!rdev->desc->ops->enable_time)
|
|
|
+ return 0;
|
|
|
+ return rdev->desc->ops->enable_time(rdev);
|
|
|
+}
|
|
|
+
|
|
|
/* Internal regulator request function */
|
|
|
static struct regulator *_regulator_get(struct device *dev, const char *id,
|
|
|
int exclusive)
|
|
@@ -1251,7 +1259,7 @@ static int _regulator_can_change_status(struct regulator_dev *rdev)
|
|
|
/* locks held by regulator_enable() */
|
|
|
static int _regulator_enable(struct regulator_dev *rdev)
|
|
|
{
|
|
|
- int ret;
|
|
|
+ int ret, delay;
|
|
|
|
|
|
/* do we need to enable the supply regulator first */
|
|
|
if (rdev->supply) {
|
|
@@ -1275,13 +1283,34 @@ static int _regulator_enable(struct regulator_dev *rdev)
|
|
|
if (!_regulator_can_change_status(rdev))
|
|
|
return -EPERM;
|
|
|
|
|
|
- if (rdev->desc->ops->enable) {
|
|
|
- ret = rdev->desc->ops->enable(rdev);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- } else {
|
|
|
+ if (!rdev->desc->ops->enable)
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
+ /* Query before enabling in case configuration
|
|
|
+ * dependant. */
|
|
|
+ ret = _regulator_get_enable_time(rdev);
|
|
|
+ if (ret >= 0) {
|
|
|
+ delay = ret;
|
|
|
+ } else {
|
|
|
+ printk(KERN_WARNING
|
|
|
+ "%s: enable_time() failed for %s: %d\n",
|
|
|
+ __func__, rdev_get_name(rdev),
|
|
|
+ ret);
|
|
|
+ delay = 0;
|
|
|
}
|
|
|
+
|
|
|
+ /* Allow the regulator to ramp; it would be useful
|
|
|
+ * to extend this for bulk operations so that the
|
|
|
+ * regulators can ramp together. */
|
|
|
+ ret = rdev->desc->ops->enable(rdev);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (delay >= 1000)
|
|
|
+ mdelay(delay / 1000);
|
|
|
+ else if (delay)
|
|
|
+ udelay(delay);
|
|
|
+
|
|
|
} else if (ret < 0) {
|
|
|
printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
|
|
|
__func__, rdev_get_name(rdev), ret);
|