Merge remote-tracking branches 'regulator/topic/can-change', 'regulator/topic/constra...
authorMark Brown <broonie@kernel.org>
Fri, 13 May 2016 13:23:27 +0000 (14:23 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 13 May 2016 13:23:27 +0000 (14:23 +0100)
drivers/regulator/core.c
include/linux/regulator/consumer.h
include/linux/regulator/driver.h
include/linux/regulator/machine.h

index af88762..ec8184d 100644 (file)
@@ -132,6 +132,19 @@ static bool have_full_constraints(void)
        return has_full_constraints || of_have_populated_dt();
 }
 
+static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
+{
+       if (!rdev->constraints) {
+               rdev_err(rdev, "no constraints\n");
+               return false;
+       }
+
+       if (rdev->constraints->valid_ops_mask & ops)
+               return true;
+
+       return false;
+}
+
 static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
 {
        if (rdev && rdev->supply)
@@ -198,28 +211,13 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
        return regnode;
 }
 
-static int _regulator_can_change_status(struct regulator_dev *rdev)
-{
-       if (!rdev->constraints)
-               return 0;
-
-       if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
-               return 1;
-       else
-               return 0;
-}
-
 /* Platform voltage constraint check */
 static int regulator_check_voltage(struct regulator_dev *rdev,
                                   int *min_uV, int *max_uV)
 {
        BUG_ON(*min_uV > *max_uV);
 
-       if (!rdev->constraints) {
-               rdev_err(rdev, "no constraints\n");
-               return -ENODEV;
-       }
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
                rdev_err(rdev, "voltage operation not allowed\n");
                return -EPERM;
        }
@@ -275,11 +273,7 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
 {
        BUG_ON(*min_uA > *max_uA);
 
-       if (!rdev->constraints) {
-               rdev_err(rdev, "no constraints\n");
-               return -ENODEV;
-       }
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_CURRENT)) {
                rdev_err(rdev, "current operation not allowed\n");
                return -EPERM;
        }
@@ -312,11 +306,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
                return -EINVAL;
        }
 
-       if (!rdev->constraints) {
-               rdev_err(rdev, "no constraints\n");
-               return -ENODEV;
-       }
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_MODE)) {
                rdev_err(rdev, "mode operation not allowed\n");
                return -EPERM;
        }
@@ -333,20 +323,6 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
        return -EINVAL;
 }
 
-/* dynamic regulator mode switching constraint check */
-static int regulator_check_drms(struct regulator_dev *rdev)
-{
-       if (!rdev->constraints) {
-               rdev_err(rdev, "no constraints\n");
-               return -ENODEV;
-       }
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
-               rdev_dbg(rdev, "drms operation not allowed\n");
-               return -EPERM;
-       }
-       return 0;
-}
-
 static ssize_t regulator_uV_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
@@ -692,8 +668,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
         * first check to see if we can set modes at all, otherwise just
         * tell the consumer everything is OK.
         */
-       err = regulator_check_drms(rdev);
-       if (err < 0)
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
                return 0;
 
        if (!rdev->desc->ops->get_optimum_mode &&
@@ -891,7 +866,7 @@ static void print_constraints(struct regulator_dev *rdev)
        rdev_dbg(rdev, "%s\n", buf);
 
        if ((constraints->min_uV != constraints->max_uV) &&
-           !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
+           !regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
                rdev_warn(rdev,
                          "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
 }
@@ -933,6 +908,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
                }
 
                if (target_min != current_uV || target_max != current_uV) {
+                       rdev_info(rdev, "Bringing %duV into %d-%duV\n",
+                                 current_uV, target_min, target_max);
                        ret = _regulator_do_set_voltage(
                                rdev, target_min, target_max);
                        if (ret < 0) {
@@ -1277,6 +1254,55 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
        }
 }
 
+#ifdef CONFIG_DEBUG_FS
+static ssize_t constraint_flags_read_file(struct file *file,
+                                         char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       const struct regulator *regulator = file->private_data;
+       const struct regulation_constraints *c = regulator->rdev->constraints;
+       char *buf;
+       ssize_t ret;
+
+       if (!c)
+               return 0;
+
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       ret = snprintf(buf, PAGE_SIZE,
+                       "always_on: %u\n"
+                       "boot_on: %u\n"
+                       "apply_uV: %u\n"
+                       "ramp_disable: %u\n"
+                       "soft_start: %u\n"
+                       "pull_down: %u\n"
+                       "over_current_protection: %u\n",
+                       c->always_on,
+                       c->boot_on,
+                       c->apply_uV,
+                       c->ramp_disable,
+                       c->soft_start,
+                       c->pull_down,
+                       c->over_current_protection);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+       kfree(buf);
+
+       return ret;
+}
+
+#endif
+
+static const struct file_operations constraint_flags_fops = {
+#ifdef CONFIG_DEBUG_FS
+       .open = simple_open,
+       .read = constraint_flags_read_file,
+       .llseek = default_llseek,
+#endif
+};
+
 #define REG_STR_SIZE   64
 
 static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -1332,6 +1358,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                                   &regulator->min_uV);
                debugfs_create_u32("max_uV", 0444, regulator->debugfs,
                                   &regulator->max_uV);
+               debugfs_create_file("constraint_flags", 0444,
+                                   regulator->debugfs, regulator,
+                                   &constraint_flags_fops);
        }
 
        /*
@@ -1339,7 +1368,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
         * it is then we don't need to do nearly so much work for
         * enable/disable calls.
         */
-       if (!_regulator_can_change_status(rdev) &&
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS) &&
            _regulator_is_enabled(rdev))
                regulator->always_on = true;
 
@@ -2117,15 +2146,15 @@ static int _regulator_enable(struct regulator_dev *rdev)
        lockdep_assert_held_once(&rdev->mutex);
 
        /* check voltage and requested load before enabling */
-       if (rdev->constraints &&
-           (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
+       if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
                drms_uA_update(rdev);
 
        if (rdev->use_count == 0) {
                /* The regulator may on if it's not switchable or left on */
                ret = _regulator_is_enabled(rdev);
                if (ret == -EINVAL || ret == 0) {
-                       if (!_regulator_can_change_status(rdev))
+                       if (!regulator_ops_is_valid(rdev,
+                                       REGULATOR_CHANGE_STATUS))
                                return -EPERM;
 
                        ret = _regulator_do_enable(rdev);
@@ -2227,7 +2256,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
            (rdev->constraints && !rdev->constraints->always_on)) {
 
                /* we are last user */
-               if (_regulator_can_change_status(rdev)) {
+               if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
                        ret = _notifier_call_chain(rdev,
                                                   REGULATOR_EVENT_PRE_DISABLE,
                                                   NULL);
@@ -2248,10 +2277,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
 
                rdev->use_count = 0;
        } else if (rdev->use_count > 1) {
-
-               if (rdev->constraints &&
-                       (rdev->constraints->valid_ops_mask &
-                       REGULATOR_CHANGE_DRMS))
+               if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
                        drms_uA_update(rdev);
 
                rdev->use_count--;
@@ -2495,8 +2521,7 @@ int regulator_can_change_voltage(struct regulator *regulator)
 {
        struct regulator_dev    *rdev = regulator->rdev;
 
-       if (rdev->constraints &&
-           (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
+       if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
                if (rdev->desc->n_voltages - rdev->desc->linear_min_sel > 1)
                        return 1;
 
@@ -2650,7 +2675,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
        int i, voltages, ret;
 
        /* If we can't change voltage check the current voltage */
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
                ret = regulator_get_voltage(regulator);
                if (ret >= 0)
                        return min_uV <= ret && ret <= max_uV;
@@ -2856,7 +2881,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
         * return successfully even though the regulator does not support
         * changing the voltage.
         */
-       if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
                current_uV = _regulator_get_voltage(rdev);
                if (min_uV <= current_uV && current_uV <= max_uV) {
                        regulator->min_uV = min_uV;
@@ -3388,8 +3413,7 @@ int regulator_allow_bypass(struct regulator *regulator, bool enable)
        if (!rdev->desc->ops->set_bypass)
                return 0;
 
-       if (rdev->constraints &&
-           !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_BYPASS))
                return 0;
 
        mutex_lock(&rdev->mutex);
@@ -4429,7 +4453,7 @@ static int __init regulator_late_cleanup(struct device *dev, void *data)
        if (c && c->always_on)
                return 0;
 
-       if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
+       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS))
                return 0;
 
        mutex_lock(&rdev->mutex);
index 4860350..80dc4e5 100644 (file)
@@ -224,7 +224,7 @@ int regulator_bulk_force_disable(int num_consumers,
 void regulator_bulk_free(int num_consumers,
                         struct regulator_bulk_data *consumers);
 
-int regulator_can_change_voltage(struct regulator *regulator);
+int __deprecated regulator_can_change_voltage(struct regulator *regulator);
 int regulator_count_voltages(struct regulator *regulator);
 int regulator_list_voltage(struct regulator *regulator, unsigned selector);
 int regulator_is_supported_voltage(struct regulator *regulator,
@@ -436,7 +436,7 @@ static inline void regulator_bulk_free(int num_consumers,
 {
 }
 
-static inline int regulator_can_change_voltage(struct regulator *regulator)
+static inline int __deprecated regulator_can_change_voltage(struct regulator *regulator)
 {
        return 0;
 }
index 9ac3f98..fcfa40a 100644 (file)
@@ -93,6 +93,9 @@ struct regulator_linear_range {
  * @get_current_limit: Get the configured limit for a current-limited regulator.
  * @set_input_current_limit: Configure an input limit.
  *
+ * @set_over_current_protection: Support capability of automatically shutting
+ *                               down when detecting an over current event.
+ *
  * @set_active_discharge: Set active discharge enable/disable of regulators.
  *
  * @set_mode: Set the configured operating mode for the regulator.
@@ -255,6 +258,8 @@ enum regulator_type {
  *
  * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
  * @vsel_mask: Mask for register bitfield used for selector
+ * @csel_reg: Register for TPS65218 LS3 current regulator
+ * @csel_mask: Mask for TPS65218 LS3 current regulator
  * @apply_reg: Register for initiate voltage change on the output when
  *                using regulator_set_voltage_sel_regmap
  * @apply_bit: Register bitfield used for initiate voltage change on the
index 5d627c8..ad3e515 100644 (file)
@@ -97,6 +97,7 @@ struct regulator_state {
  * @ramp_disable: Disable ramp delay when initialising or when setting voltage.
  * @soft_start: Enable soft start so that voltage ramps slowly.
  * @pull_down: Enable pull down when regulator is disabled.
+ * @over_current_protection: Auto disable on over current event.
  *
  * @input_uV: Input voltage for regulator when supplied by another regulator.
  *