]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/regulator/core.c
Merge remote-tracking branches 'regulator/topic/fixed', 'regulator/topic/id-const...
[karo-tx-linux.git] / drivers / regulator / core.c
index b97ffd2365d3a78c29e01c1cd3dfab46eb302803..4c1f999041dd1fe74433d7769e18fc3cde7d7804 100644 (file)
@@ -844,13 +844,22 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
        /* do we need to apply the constraint voltage */
        if (rdev->constraints->apply_uV &&
            rdev->constraints->min_uV == rdev->constraints->max_uV) {
-               ret = _regulator_do_set_voltage(rdev,
-                                               rdev->constraints->min_uV,
-                                               rdev->constraints->max_uV);
-               if (ret < 0) {
-                       rdev_err(rdev, "failed to apply %duV constraint\n",
-                                rdev->constraints->min_uV);
-                       return ret;
+               int current_uV = _regulator_get_voltage(rdev);
+               if (current_uV < 0) {
+                       rdev_err(rdev, "failed to get the current voltage\n");
+                       return current_uV;
+               }
+               if (current_uV < rdev->constraints->min_uV ||
+                   current_uV > rdev->constraints->max_uV) {
+                       ret = _regulator_do_set_voltage(
+                               rdev, rdev->constraints->min_uV,
+                               rdev->constraints->max_uV);
+                       if (ret < 0) {
+                               rdev_err(rdev,
+                                       "failed to apply %duV constraint\n",
+                                       rdev->constraints->min_uV);
+                               return ret;
+                       }
                }
        }
 
@@ -1430,9 +1439,9 @@ EXPORT_SYMBOL_GPL(regulator_get);
  *
  * Returns a struct regulator corresponding to the regulator producer,
  * or IS_ERR() condition containing errno.  Other consumers will be
- * unable to obtain this reference is held and the use count for the
- * regulator will be initialised to reflect the current state of the
- * regulator.
+ * unable to obtain this regulator while this reference is held and the
+ * use count for the regulator will be initialised to reflect the current
+ * state of the regulator.
  *
  * This is intended for use by consumers which cannot tolerate shared
  * use of the regulator such as those which need to force the
@@ -1456,10 +1465,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive);
  * @id: Supply name or regulator ID.
  *
  * Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno.  Other consumers will be
- * unable to obtain this reference is held and the use count for the
- * regulator will be initialised to reflect the current state of the
- * regulator.
+ * or IS_ERR() condition containing errno.
  *
  * This is intended for use by consumers for devices which can have
  * some supplies unconnected in normal use, such as some MMC devices.
@@ -1597,9 +1603,10 @@ EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias);
  * registered any aliases that were registered will be removed
  * before returning to the caller.
  */
-int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
+int regulator_bulk_register_supply_alias(struct device *dev,
+                                        const char *const *id,
                                         struct device *alias_dev,
-                                        const char **alias_id,
+                                        const char *const *alias_id,
                                         int num_id)
 {
        int i;
@@ -1637,7 +1644,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_register_supply_alias);
  * aliases in one operation.
  */
 void regulator_bulk_unregister_supply_alias(struct device *dev,
-                                           const char **id,
+                                           const char *const *id,
                                            int num_id)
 {
        int i;
@@ -2321,6 +2328,10 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                            regulator_list_voltage_linear)
                                ret = regulator_map_voltage_linear(rdev,
                                                                min_uV, max_uV);
+                       else if (rdev->desc->ops->list_voltage ==
+                                regulator_list_voltage_linear_range)
+                               ret = regulator_map_voltage_linear_range(rdev,
+                                                               min_uV, max_uV);
                        else
                                ret = regulator_map_voltage_iterate(rdev,
                                                                min_uV, max_uV);
@@ -3820,8 +3831,9 @@ static int __init regulator_init_complete(void)
        mutex_lock(&regulator_list_mutex);
 
        /* If we have a full configuration then disable any regulators
-        * which are not in use or always_on.  This will become the
-        * default behaviour in the future.
+        * we have permission to change the status for and which are
+        * not in use or always_on.  This is effectively the default
+        * for DT and ACPI as they have full constraints.
         */
        list_for_each_entry(rdev, &regulator_list, list) {
                ops = rdev->desc->ops;
@@ -3830,6 +3842,9 @@ static int __init regulator_init_complete(void)
                if (c && c->always_on)
                        continue;
 
+               if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
+                       continue;
+
                mutex_lock(&rdev->mutex);
 
                if (rdev->use_count)
@@ -3868,4 +3883,4 @@ unlock:
 
        return 0;
 }
-late_initcall(regulator_init_complete);
+late_initcall_sync(regulator_init_complete);