aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 60fcd986ff3f..dbf27bf028c4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1191,16 +1191,21 @@ void regulator_put(struct regulator *regulator)
1191} 1191}
1192EXPORT_SYMBOL_GPL(regulator_put); 1192EXPORT_SYMBOL_GPL(regulator_put);
1193 1193
1194static int _regulator_can_change_status(struct regulator_dev *rdev)
1195{
1196 if (!rdev->constraints)
1197 return 0;
1198
1199 if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
1200 return 1;
1201 else
1202 return 0;
1203}
1204
1194/* locks held by regulator_enable() */ 1205/* locks held by regulator_enable() */
1195static int _regulator_enable(struct regulator_dev *rdev) 1206static int _regulator_enable(struct regulator_dev *rdev)
1196{ 1207{
1197 int ret = -EINVAL; 1208 int ret;
1198
1199 if (!rdev->constraints) {
1200 printk(KERN_ERR "%s: %s has no constraints\n",
1201 __func__, rdev->desc->name);
1202 return ret;
1203 }
1204 1209
1205 /* do we need to enable the supply regulator first */ 1210 /* do we need to enable the supply regulator first */
1206 if (rdev->supply) { 1211 if (rdev->supply) {
@@ -1213,24 +1218,34 @@ static int _regulator_enable(struct regulator_dev *rdev)
1213 } 1218 }
1214 1219
1215 /* check voltage and requested load before enabling */ 1220 /* check voltage and requested load before enabling */
1216 if (rdev->desc->ops->enable) { 1221 if (rdev->constraints &&
1222 (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
1223 drms_uA_update(rdev);
1217 1224
1218 if (rdev->constraints && 1225 if (rdev->use_count == 0) {
1219 (rdev->constraints->valid_ops_mask & 1226 /* The regulator may on if it's not switchable or left on */
1220 REGULATOR_CHANGE_DRMS)) 1227 ret = _regulator_is_enabled(rdev);
1221 drms_uA_update(rdev); 1228 if (ret == -EINVAL || ret == 0) {
1222 1229 if (!_regulator_can_change_status(rdev))
1223 ret = rdev->desc->ops->enable(rdev); 1230 return -EPERM;
1224 if (ret < 0) { 1231
1225 printk(KERN_ERR "%s: failed to enable %s: %d\n", 1232 if (rdev->desc->ops->enable) {
1233 ret = rdev->desc->ops->enable(rdev);
1234 if (ret < 0)
1235 return ret;
1236 } else {
1237 return -EINVAL;
1238 }
1239 } else {
1240 printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
1226 __func__, rdev->desc->name, ret); 1241 __func__, rdev->desc->name, ret);
1227 return ret; 1242 return ret;
1228 } 1243 }
1229 rdev->use_count++;
1230 return ret;
1231 } 1244 }
1232 1245
1233 return ret; 1246 rdev->use_count++;
1247
1248 return 0;
1234} 1249}
1235 1250
1236/** 1251/**
@@ -1270,7 +1285,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
1270 if (rdev->use_count == 1 && !rdev->constraints->always_on) { 1285 if (rdev->use_count == 1 && !rdev->constraints->always_on) {
1271 1286
1272 /* we are last user */ 1287 /* we are last user */
1273 if (rdev->desc->ops->disable) { 1288 if (_regulator_can_change_status(rdev) &&
1289 rdev->desc->ops->disable) {
1274 ret = rdev->desc->ops->disable(rdev); 1290 ret = rdev->desc->ops->disable(rdev);
1275 if (ret < 0) { 1291 if (ret < 0) {
1276 printk(KERN_ERR "%s: failed to disable %s\n", 1292 printk(KERN_ERR "%s: failed to disable %s\n",