]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/regulator/core.c
Merge remote-tracking branches 'regulator/fix/constrain' and 'regulator/fix/defer...
[mirror_ubuntu-artful-kernel.git] / drivers / regulator / core.c
index fd0e4e37f4e1427beded905b75ffe694c774fcb7..6af38691ec48ff4d114b4a3fc5d08a2b9e4d74ad 100644 (file)
@@ -906,7 +906,8 @@ 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) {
+           rdev->constraints->min_uV && rdev->constraints->max_uV) {
+               int target_min, target_max;
                int current_uV = _regulator_get_voltage(rdev);
                if (current_uV < 0) {
                        rdev_err(rdev,
@@ -914,15 +915,32 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
                                 current_uV);
                        return current_uV;
                }
-               if (current_uV < rdev->constraints->min_uV ||
-                   current_uV > rdev->constraints->max_uV) {
+
+               /*
+                * If we're below the minimum voltage move up to the
+                * minimum voltage, if we're above the maximum voltage
+                * then move down to the maximum.
+                */
+               target_min = current_uV;
+               target_max = current_uV;
+
+               if (current_uV < rdev->constraints->min_uV) {
+                       target_min = rdev->constraints->min_uV;
+                       target_max = rdev->constraints->min_uV;
+               }
+
+               if (current_uV > rdev->constraints->max_uV) {
+                       target_min = rdev->constraints->max_uV;
+                       target_max = rdev->constraints->max_uV;
+               }
+
+               if (target_min != current_uV || target_max != current_uV) {
                        ret = _regulator_do_set_voltage(
-                               rdev, rdev->constraints->min_uV,
-                               rdev->constraints->max_uV);
+                               rdev, target_min, target_max);
                        if (ret < 0) {
                                rdev_err(rdev,
-                                       "failed to apply %duV constraint(%d)\n",
-                                       rdev->constraints->min_uV, ret);
+                                       "failed to apply %d-%duV constraint(%d)\n",
+                                       target_min, target_max, ret);
                                return ret;
                        }
                }
@@ -1150,17 +1168,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                }
        }
 
-       if (rdev->constraints->active_discharge && ops->set_active_discharge) {
-               bool ad_state = (rdev->constraints->active_discharge ==
-                             REGULATOR_ACTIVE_DISCHARGE_ENABLE) ? true : false;
-
-               ret = ops->set_active_discharge(rdev, ad_state);
-               if (ret < 0) {
-                       rdev_err(rdev, "failed to set active discharge\n");
-                       return ret;
-               }
-       }
-
        print_constraints(rdev);
        return 0;
 }
@@ -4041,8 +4048,8 @@ void regulator_unregister(struct regulator_dev *rdev)
        WARN_ON(rdev->open_count);
        unset_regulator_supplies(rdev);
        list_del(&rdev->list);
-       mutex_unlock(&regulator_list_mutex);
        regulator_ena_gpio_free(rdev);
+       mutex_unlock(&regulator_list_mutex);
        device_unregister(&rdev->dev);
 }
 EXPORT_SYMBOL_GPL(regulator_unregister);