aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/ab8500-ext.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2013-04-16 11:29:12 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-17 10:08:33 -0400
commit66511fa4a7902fb9ffdffc8c153f1758817fb8a4 (patch)
tree50ff9b1d779a064207a72618a564d2bccabb9b92 /drivers/regulator/ab8500-ext.c
parent0b665062a1dde470d69ff3bd435b090a119991ab (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.c26
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, &regval); 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
220static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev) 230static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)