diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-04-27 00:19:43 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-05-01 14:26:04 -0700 |
commit | cd5759db61c9d0d2b2f2b340fc2fc91667cd4763 (patch) | |
tree | 047f57451732beebe3d1ac79412a2cd0f4102c8d /drivers/regulator/core.c | |
parent | 24c1b0906d11919aae53d840b385be356183b4be (diff) |
regulator: add sysfs for rail enable/disable
Added support for enable/disable rails from user space.
bug 966960
Change-Id: Iae660699c60f537296f90508a78bd40959c46535
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/99186
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Hunk Lin <hulin@nvidia.com>
Tested-by: Hunk Lin <hulin@nvidia.com>
GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r-- | drivers/regulator/core.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1b7d64118e4d..cbe36b93639b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -91,6 +91,8 @@ struct regulator { static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_disable(struct regulator_dev *rdev); +static int _regulator_enable(struct regulator_dev *rdev); +static int _regulator_get_enable_time(struct regulator_dev *rdev); static int _regulator_get_voltage(struct regulator_dev *rdev); static int _regulator_get_current_limit(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev); @@ -358,7 +360,65 @@ static ssize_t regulator_state_show(struct device *dev, return ret; } -static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); + +static ssize_t regulator_state_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct regulator_dev *rdev = dev_get_drvdata(dev); + int ret; + bool enabled; + + if ((*buf == 'E') || (*buf == 'e')) + enabled = true; + else if ((*buf == 'D') || (*buf == 'd')) + enabled = false; + else + return -EINVAL; + + if ((_regulator_is_enabled(rdev) && enabled) || + (!_regulator_is_enabled(rdev) && !enabled)) + return count; + + mutex_lock(&rdev->mutex); + if (enabled) { + int delay = 0; + if (!rdev->desc->ops->enable) { + ret = -EINVAL; + goto end; + } + ret = _regulator_get_enable_time(rdev); + if (ret >= 0) + delay = ret; + ret = rdev->desc->ops->enable(rdev); + if (ret < 0) { + rdev_warn(rdev, "enable() failed: %d\n", ret); + goto end; + } + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } + } else { + if (!rdev->desc->ops->disable) { + ret = -EINVAL; + goto end; + } + ret = rdev->desc->ops->disable(rdev); + if (ret < 0) { + rdev_warn(rdev, "disable() failed: %d\n", ret); + goto end; + } + } + +end: + mutex_unlock(&rdev->mutex); + if (ret < 0) + return ret; + return count; +} +static DEVICE_ATTR(state, 0644, regulator_state_show, regulator_state_set); static ssize_t regulator_status_show(struct device *dev, struct device_attribute *attr, char *buf) |