diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/regulator/core.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9a644d41b81..c2b7ec90103 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -79,7 +79,7 @@ struct regulator { | |||
| 79 | int uA_load; | 79 | int uA_load; |
| 80 | int min_uV; | 80 | int min_uV; |
| 81 | int max_uV; | 81 | int max_uV; |
| 82 | int enabled; /* client has called enabled */ | 82 | int enabled; /* count of client enables */ |
| 83 | char *supply_name; | 83 | char *supply_name; |
| 84 | struct device_attribute dev_attr; | 84 | struct device_attribute dev_attr; |
| 85 | struct regulator_dev *rdev; | 85 | struct regulator_dev *rdev; |
| @@ -963,16 +963,13 @@ void regulator_put(struct regulator *regulator) | |||
| 963 | if (regulator == NULL || IS_ERR(regulator)) | 963 | if (regulator == NULL || IS_ERR(regulator)) |
| 964 | return; | 964 | return; |
| 965 | 965 | ||
| 966 | if (regulator->enabled) { | ||
| 967 | printk(KERN_WARNING "Releasing supply %s while enabled\n", | ||
| 968 | regulator->supply_name); | ||
| 969 | WARN_ON(regulator->enabled); | ||
| 970 | regulator_disable(regulator); | ||
| 971 | } | ||
| 972 | |||
| 973 | mutex_lock(®ulator_list_mutex); | 966 | mutex_lock(®ulator_list_mutex); |
| 974 | rdev = regulator->rdev; | 967 | rdev = regulator->rdev; |
| 975 | 968 | ||
| 969 | if (WARN(regulator->enabled, "Releasing supply %s while enabled\n", | ||
| 970 | regulator->supply_name)) | ||
| 971 | _regulator_disable(rdev); | ||
| 972 | |||
| 976 | /* remove any sysfs entries */ | 973 | /* remove any sysfs entries */ |
| 977 | if (regulator->dev) { | 974 | if (regulator->dev) { |
| 978 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); | 975 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); |
| @@ -1042,21 +1039,17 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
| 1042 | */ | 1039 | */ |
| 1043 | int regulator_enable(struct regulator *regulator) | 1040 | int regulator_enable(struct regulator *regulator) |
| 1044 | { | 1041 | { |
| 1045 | int ret; | 1042 | struct regulator_dev *rdev = regulator->rdev; |
| 1046 | 1043 | int ret = 0; | |
| 1047 | if (regulator->enabled) { | ||
| 1048 | printk(KERN_CRIT "Regulator %s already enabled\n", | ||
| 1049 | regulator->supply_name); | ||
| 1050 | WARN_ON(regulator->enabled); | ||
| 1051 | return 0; | ||
| 1052 | } | ||
| 1053 | 1044 | ||
| 1054 | mutex_lock(®ulator->rdev->mutex); | 1045 | mutex_lock(&rdev->mutex); |
| 1055 | regulator->enabled = 1; | 1046 | if (regulator->enabled == 0) |
| 1056 | ret = _regulator_enable(regulator->rdev); | 1047 | ret = _regulator_enable(rdev); |
| 1057 | if (ret != 0) | 1048 | else if (regulator->enabled < 0) |
| 1058 | regulator->enabled = 0; | 1049 | ret = -EIO; |
| 1059 | mutex_unlock(®ulator->rdev->mutex); | 1050 | if (ret == 0) |
| 1051 | regulator->enabled++; | ||
| 1052 | mutex_unlock(&rdev->mutex); | ||
| 1060 | return ret; | 1053 | return ret; |
| 1061 | } | 1054 | } |
| 1062 | EXPORT_SYMBOL_GPL(regulator_enable); | 1055 | EXPORT_SYMBOL_GPL(regulator_enable); |
| @@ -1108,19 +1101,21 @@ static int _regulator_disable(struct regulator_dev *rdev) | |||
| 1108 | */ | 1101 | */ |
| 1109 | int regulator_disable(struct regulator *regulator) | 1102 | int regulator_disable(struct regulator *regulator) |
| 1110 | { | 1103 | { |
| 1111 | int ret; | 1104 | struct regulator_dev *rdev = regulator->rdev; |
| 1112 | 1105 | int ret = 0; | |
| 1113 | if (!regulator->enabled) { | ||
| 1114 | printk(KERN_ERR "%s: not in use by this consumer\n", | ||
| 1115 | __func__); | ||
| 1116 | return 0; | ||
| 1117 | } | ||
| 1118 | 1106 | ||
| 1119 | mutex_lock(®ulator->rdev->mutex); | 1107 | mutex_lock(&rdev->mutex); |
| 1120 | regulator->enabled = 0; | 1108 | if (regulator->enabled == 1) { |
| 1121 | regulator->uA_load = 0; | 1109 | ret = _regulator_disable(rdev); |
| 1122 | ret = _regulator_disable(regulator->rdev); | 1110 | if (ret == 0) |
| 1123 | mutex_unlock(®ulator->rdev->mutex); | 1111 | regulator->uA_load = 0; |
| 1112 | } else if (WARN(regulator->enabled <= 0, | ||
| 1113 | "unbalanced disables for supply %s\n", | ||
| 1114 | regulator->supply_name)) | ||
| 1115 | ret = -EIO; | ||
| 1116 | if (ret == 0) | ||
| 1117 | regulator->enabled--; | ||
| 1118 | mutex_unlock(&rdev->mutex); | ||
| 1124 | return ret; | 1119 | return ret; |
| 1125 | } | 1120 | } |
| 1126 | EXPORT_SYMBOL_GPL(regulator_disable); | 1121 | EXPORT_SYMBOL_GPL(regulator_disable); |
| @@ -1196,7 +1191,13 @@ out: | |||
| 1196 | * regulator_is_enabled - is the regulator output enabled | 1191 | * regulator_is_enabled - is the regulator output enabled |
| 1197 | * @regulator: regulator source | 1192 | * @regulator: regulator source |
| 1198 | * | 1193 | * |
| 1199 | * Returns zero for disabled otherwise return number of enable requests. | 1194 | * Returns positive if the regulator driver backing the source/client |
| 1195 | * has requested that the device be enabled, zero if it hasn't, else a | ||
| 1196 | * negative errno code. | ||
| 1197 | * | ||
| 1198 | * Note that the device backing this regulator handle can have multiple | ||
| 1199 | * users, so it might be enabled even if regulator_enable() was never | ||
| 1200 | * called for this particular source. | ||
| 1200 | */ | 1201 | */ |
| 1201 | int regulator_is_enabled(struct regulator *regulator) | 1202 | int regulator_is_enabled(struct regulator *regulator) |
| 1202 | { | 1203 | { |
