]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/regulator/core.c
Merge tag 'disintegrate-fbdev-20121220' of git://git.infradead.org/users/dhowells...
[karo-tx-linux.git] / drivers / regulator / core.c
index 278584302f2d162c56599ad61a62ade3cdcceadd..da9782bd27d0a182d32578c4779481072d0657ef 100644 (file)
@@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
        }
 
        if (*min_uV > *max_uV) {
-               dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n",
-                       regulator->min_uV, regulator->max_uV);
+               rdev_err(rdev, "Restricting voltage, %u-%uuV\n",
+                       *min_uV, *max_uV);
                return -EINVAL;
        }
 
@@ -2080,10 +2080,20 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
  */
 int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
 {
+       int ret;
+
        sel <<= ffs(rdev->desc->vsel_mask) - 1;
 
-       return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+       ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
                                  rdev->desc->vsel_mask, sel);
+       if (ret)
+               return ret;
+
+       if (rdev->desc->apply_bit)
+               ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
+                                        rdev->desc->apply_bit,
+                                        rdev->desc->apply_bit);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
 
@@ -2229,8 +2239,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                        best_val = rdev->desc->ops->list_voltage(rdev, ret);
                        if (min_uV <= best_val && max_uV >= best_val) {
                                selector = ret;
-                               ret = rdev->desc->ops->set_voltage_sel(rdev,
-                                                                      ret);
+                               if (old_selector == selector)
+                                       ret = 0;
+                               else
+                                       ret = rdev->desc->ops->set_voltage_sel(
+                                                               rdev, ret);
                        } else {
                                ret = -EINVAL;
                        }
@@ -2241,7 +2254,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 
        /* Call set_voltage_time_sel if successfully obtained old_selector */
        if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 &&
-           rdev->desc->ops->set_voltage_time_sel) {
+           old_selector != selector && rdev->desc->ops->set_voltage_time_sel) {
 
                delay = rdev->desc->ops->set_voltage_time_sel(rdev,
                                                old_selector, selector);
@@ -2294,6 +2307,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
 {
        struct regulator_dev *rdev = regulator->rdev;
        int ret = 0;
+       int old_min_uV, old_max_uV;
 
        mutex_lock(&rdev->mutex);
 
@@ -2315,18 +2329,29 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
        ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
        if (ret < 0)
                goto out;
+       
+       /* restore original values in case of error */
+       old_min_uV = regulator->min_uV;
+       old_max_uV = regulator->max_uV;
        regulator->min_uV = min_uV;
        regulator->max_uV = max_uV;
 
        ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
        if (ret < 0)
-               goto out;
+               goto out2;
 
        ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
-
+       if (ret < 0)
+               goto out2;
+       
 out:
        mutex_unlock(&rdev->mutex);
        return ret;
+out2:
+       regulator->min_uV = old_min_uV;
+       regulator->max_uV = old_max_uV;
+       mutex_unlock(&rdev->mutex);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(regulator_set_voltage);
 
@@ -3208,7 +3233,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
                if (status < 0)
                        return status;
        }
-       if (ops->is_enabled) {
+       if (rdev->ena_gpio || ops->is_enabled) {
                status = device_create_file(dev, &dev_attr_state);
                if (status < 0)
                        return status;