diff options
author | Axel Lin <axel.lin@ingics.com> | 2013-04-16 11:29:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-17 10:08:33 -0400 |
commit | 66511fa4a7902fb9ffdffc8c153f1758817fb8a4 (patch) | |
tree | 50ff9b1d779a064207a72618a564d2bccabb9b92 /drivers/regulator/ab8500-ext.c | |
parent | 0b665062a1dde470d69ff3bd435b090a119991ab (diff) |
regulator: ab8500-ext: Don't update info->update_val if set_mode() fails
This ensures info->update_val status is still correct if set_mode() call fails.
Otherwise, get_mode() may return wrong status if a set_mode() call fails.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/ab8500-ext.c')
-rw-r--r-- | drivers/regulator/ab8500-ext.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 20680f30a968..03faf9c698c4 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c | |||
@@ -181,6 +181,7 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev, | |||
181 | { | 181 | { |
182 | int ret = 0; | 182 | int ret = 0; |
183 | struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); | 183 | struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); |
184 | u8 regval; | ||
184 | 185 | ||
185 | if (info == NULL) { | 186 | if (info == NULL) { |
186 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); | 187 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); |
@@ -189,23 +190,30 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev, | |||
189 | 190 | ||
190 | switch (mode) { | 191 | switch (mode) { |
191 | case REGULATOR_MODE_NORMAL: | 192 | case REGULATOR_MODE_NORMAL: |
192 | info->update_val = info->update_val_hp; | 193 | regval = info->update_val_hp; |
193 | break; | 194 | break; |
194 | case REGULATOR_MODE_IDLE: | 195 | case REGULATOR_MODE_IDLE: |
195 | info->update_val = info->update_val_lp; | 196 | regval = info->update_val_lp; |
196 | break; | 197 | break; |
197 | 198 | ||
198 | default: | 199 | default: |
199 | return -EINVAL; | 200 | return -EINVAL; |
200 | } | 201 | } |
201 | 202 | ||
202 | if (ab8500_ext_regulator_is_enabled(rdev)) { | 203 | /* If regulator is enabled and info->cfg->hwreq is set, the regulator |
203 | u8 regval; | 204 | must be on in high power, so we don't need to write the register with |
204 | 205 | the same value. | |
205 | ret = enable(info, ®val); | 206 | */ |
206 | if (ret < 0) | 207 | if (ab8500_ext_regulator_is_enabled(rdev) && |
208 | !(info->cfg && info->cfg->hwreq)) { | ||
209 | ret = abx500_mask_and_set_register_interruptible(info->dev, | ||
210 | info->update_bank, info->update_reg, | ||
211 | info->update_mask, regval); | ||
212 | if (ret < 0) { | ||
207 | dev_err(rdev_get_dev(rdev), | 213 | dev_err(rdev_get_dev(rdev), |
208 | "Could not set regulator mode.\n"); | 214 | "Could not set regulator mode.\n"); |
215 | return ret; | ||
216 | } | ||
209 | 217 | ||
210 | dev_dbg(rdev_get_dev(rdev), | 218 | dev_dbg(rdev_get_dev(rdev), |
211 | "%s-set_mode (bank, reg, mask, value): " | 219 | "%s-set_mode (bank, reg, mask, value): " |
@@ -214,7 +222,9 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev, | |||
214 | info->update_mask, regval); | 222 | info->update_mask, regval); |
215 | } | 223 | } |
216 | 224 | ||
217 | return ret; | 225 | info->update_val = regval; |
226 | |||
227 | return 0; | ||
218 | } | 228 | } |
219 | 229 | ||
220 | static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev) | 230 | static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev) |