]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/regulator/core.c
Merge tag 'kvm-4.20-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux.git] / drivers / regulator / core.c
index bb1324f93143f66e609fea2602329230f70ed4ce..2c66b528aedec02f4afdda7e8c04faf60711a70d 100644 (file)
@@ -426,19 +426,24 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(name);
 
-static ssize_t regulator_print_opmode(char *buf, int mode)
+static const char *regulator_opmode_to_str(int mode)
 {
        switch (mode) {
        case REGULATOR_MODE_FAST:
-               return sprintf(buf, "fast\n");
+               return "fast";
        case REGULATOR_MODE_NORMAL:
-               return sprintf(buf, "normal\n");
+               return "normal";
        case REGULATOR_MODE_IDLE:
-               return sprintf(buf, "idle\n");
+               return "idle";
        case REGULATOR_MODE_STANDBY:
-               return sprintf(buf, "standby\n");
+               return "standby";
        }
-       return sprintf(buf, "unknown\n");
+       return "unknown";
+}
+
+static ssize_t regulator_print_opmode(char *buf, int mode)
+{
+       return sprintf(buf, "%s\n", regulator_opmode_to_str(mode));
 }
 
 static ssize_t regulator_opmode_show(struct device *dev,
@@ -2783,6 +2788,11 @@ static int regulator_map_voltage(struct regulator_dev *rdev, int min_uV,
        if (desc->ops->list_voltage == regulator_list_voltage_linear_range)
                return regulator_map_voltage_linear_range(rdev, min_uV, max_uV);
 
+       if (desc->ops->list_voltage ==
+               regulator_list_voltage_pickable_linear_range)
+               return regulator_map_voltage_pickable_linear_range(rdev,
+                                                       min_uV, max_uV);
+
        return regulator_map_voltage_iterate(rdev, min_uV, max_uV);
 }
 
@@ -3161,7 +3171,7 @@ static inline int regulator_suspend_toggle(struct regulator_dev *rdev,
        if (!rstate->changeable)
                return -EPERM;
 
-       rstate->enabled = en;
+       rstate->enabled = (en) ? ENABLE_IN_SUSPEND : DISABLE_IN_SUSPEND;
 
        return 0;
 }
@@ -3470,21 +3480,23 @@ int regulator_set_current_limit(struct regulator *regulator,
 }
 EXPORT_SYMBOL_GPL(regulator_set_current_limit);
 
+static int _regulator_get_current_limit_unlocked(struct regulator_dev *rdev)
+{
+       /* sanity check */
+       if (!rdev->desc->ops->get_current_limit)
+               return -EINVAL;
+
+       return rdev->desc->ops->get_current_limit(rdev);
+}
+
 static int _regulator_get_current_limit(struct regulator_dev *rdev)
 {
        int ret;
 
        regulator_lock(rdev);
-
-       /* sanity check */
-       if (!rdev->desc->ops->get_current_limit) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = rdev->desc->ops->get_current_limit(rdev);
-out:
+       ret = _regulator_get_current_limit_unlocked(rdev);
        regulator_unlock(rdev);
+
        return ret;
 }
 
@@ -3549,21 +3561,23 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
 }
 EXPORT_SYMBOL_GPL(regulator_set_mode);
 
+static unsigned int _regulator_get_mode_unlocked(struct regulator_dev *rdev)
+{
+       /* sanity check */
+       if (!rdev->desc->ops->get_mode)
+               return -EINVAL;
+
+       return rdev->desc->ops->get_mode(rdev);
+}
+
 static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
 {
        int ret;
 
        regulator_lock(rdev);
-
-       /* sanity check */
-       if (!rdev->desc->ops->get_mode) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = rdev->desc->ops->get_mode(rdev);
-out:
+       ret = _regulator_get_mode_unlocked(rdev);
        regulator_unlock(rdev);
+
        return ret;
 }
 
@@ -4395,13 +4409,13 @@ regulator_register(const struct regulator_desc *regulator_desc,
            !rdev->desc->fixed_uV)
                rdev->is_switch = true;
 
+       dev_set_drvdata(&rdev->dev, rdev);
        ret = device_register(&rdev->dev);
        if (ret != 0) {
                put_device(&rdev->dev);
                goto unset_supplies;
        }
 
-       dev_set_drvdata(&rdev->dev, rdev);
        rdev_init_debugfs(rdev);
 
        /* try to resolve regulators supply since a new one was registered */
@@ -4455,41 +4469,33 @@ void regulator_unregister(struct regulator_dev *rdev)
 EXPORT_SYMBOL_GPL(regulator_unregister);
 
 #ifdef CONFIG_SUSPEND
-static int _regulator_suspend(struct device *dev, void *data)
-{
-       struct regulator_dev *rdev = dev_to_rdev(dev);
-       suspend_state_t *state = data;
-       int ret;
-
-       regulator_lock(rdev);
-       ret = suspend_set_state(rdev, *state);
-       regulator_unlock(rdev);
-
-       return ret;
-}
-
 /**
  * regulator_suspend - prepare regulators for system wide suspend
- * @state: system suspend state
+ * @dev: ``&struct device`` pointer that is passed to _regulator_suspend()
  *
  * Configure each regulator with it's suspend operating parameters for state.
  */
 static int regulator_suspend(struct device *dev)
 {
+       struct regulator_dev *rdev = dev_to_rdev(dev);
        suspend_state_t state = pm_suspend_target_state;
+       int ret;
+
+       regulator_lock(rdev);
+       ret = suspend_set_state(rdev, state);
+       regulator_unlock(rdev);
 
-       return class_for_each_device(&regulator_class, NULL, &state,
-                                    _regulator_suspend);
+       return ret;
 }
 
-static int _regulator_resume(struct device *dev, void *data)
+static int regulator_resume(struct device *dev)
 {
-       int ret = 0;
+       suspend_state_t state = pm_suspend_target_state;
        struct regulator_dev *rdev = dev_to_rdev(dev);
-       suspend_state_t *state = data;
        struct regulator_state *rstate;
+       int ret = 0;
 
-       rstate = regulator_get_suspend_state(rdev, *state);
+       rstate = regulator_get_suspend_state(rdev, state);
        if (rstate == NULL)
                return 0;
 
@@ -4504,15 +4510,6 @@ static int _regulator_resume(struct device *dev, void *data)
 
        return ret;
 }
-
-static int regulator_resume(struct device *dev)
-{
-       suspend_state_t state = pm_suspend_target_state;
-
-       return class_for_each_device(&regulator_class, NULL, &state,
-                                    _regulator_resume);
-}
-
 #else /* !CONFIG_SUSPEND */
 
 #define regulator_suspend      NULL
@@ -4670,17 +4667,23 @@ static void regulator_summary_show_subtree(struct seq_file *s,
        struct regulation_constraints *c;
        struct regulator *consumer;
        struct summary_data summary_data;
+       unsigned int opmode;
 
        if (!rdev)
                return;
 
-       seq_printf(s, "%*s%-*s %3d %4d %6d ",
+       regulator_lock_nested(rdev, level);
+
+       opmode = _regulator_get_mode_unlocked(rdev);
+       seq_printf(s, "%*s%-*s %3d %4d %6d %7s ",
                   level * 3 + 1, "",
                   30 - level * 3, rdev_get_name(rdev),
-                  rdev->use_count, rdev->open_count, rdev->bypass_count);
+                  rdev->use_count, rdev->open_count, rdev->bypass_count,
+                  regulator_opmode_to_str(opmode));
 
        seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000);
-       seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000);
+       seq_printf(s, "%5dmA ",
+                  _regulator_get_current_limit_unlocked(rdev) / 1000);
 
        c = rdev->constraints;
        if (c) {
@@ -4709,7 +4712,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
 
                switch (rdev->desc->type) {
                case REGULATOR_VOLTAGE:
-                       seq_printf(s, "%37dmV %5dmV",
+                       seq_printf(s, "%37dmA %5dmV %5dmV",
+                                  consumer->uA_load / 1000,
                                   consumer->voltage[PM_SUSPEND_ON].min_uV / 1000,
                                   consumer->voltage[PM_SUSPEND_ON].max_uV / 1000);
                        break;
@@ -4726,6 +4730,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
 
        class_for_each_device(&regulator_class, NULL, &summary_data,
                              regulator_summary_show_children);
+
+       regulator_unlock(rdev);
 }
 
 static int regulator_summary_show_roots(struct device *dev, void *data)
@@ -4741,8 +4747,8 @@ static int regulator_summary_show_roots(struct device *dev, void *data)
 
 static int regulator_summary_show(struct seq_file *s, void *data)
 {
-       seq_puts(s, " regulator                      use open bypass voltage current     min     max\n");
-       seq_puts(s, "-------------------------------------------------------------------------------\n");
+       seq_puts(s, " regulator                      use open bypass  opmode voltage current     min     max\n");
+       seq_puts(s, "---------------------------------------------------------------------------------------\n");
 
        class_for_each_device(&regulator_class, NULL, s,
                              regulator_summary_show_roots);