]> Pileus Git - ~andy/linux/blobdiff - drivers/regulator/core.c
Merge branch 'exynos-drm-fixes' of git://git.infradead.org/users/kmpark/linux-samsung...
[~andy/linux] / drivers / regulator / core.c
index aa5186608aecee07009187433c071fc3d1178c72..e70dd382a009a2db05d78087b6e0e588584e6b6e 100644 (file)
@@ -13,8 +13,6 @@
  *
  */
 
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
@@ -54,9 +52,7 @@ static LIST_HEAD(regulator_map_list);
 static bool has_full_constraints;
 static bool board_wants_dummy_regulator;
 
-#ifdef CONFIG_DEBUG_FS
 static struct dentry *debugfs_root;
-#endif
 
 /*
  * struct regulator_map
@@ -84,9 +80,7 @@ struct regulator {
        char *supply_name;
        struct device_attribute dev_attr;
        struct regulator_dev *rdev;
-#ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs;
-#endif
 };
 
 static int _regulator_is_enabled(struct regulator_dev *rdev);
@@ -154,7 +148,7 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
        regnode = of_parse_phandle(dev->of_node, prop_name, 0);
 
        if (!regnode) {
-               dev_warn(dev, "%s property in node %s references invalid phandle",
+               dev_dbg(dev, "Looking up %s property in node %s failed",
                                prop_name, dev->of_node->full_name);
                return NULL;
        }
@@ -807,6 +801,11 @@ static void print_constraints(struct regulator_dev *rdev)
                count += sprintf(buf + count, "standby");
 
        rdev_info(rdev, "%s\n", buf);
+
+       if ((constraints->min_uV != constraints->max_uV) &&
+           !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
+               rdev_warn(rdev,
+                         "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
 }
 
 static int machine_constraints_voltage(struct regulator_dev *rdev,
@@ -996,7 +995,6 @@ static int set_supply(struct regulator_dev *rdev,
 /**
  * set_consumer_device_supply - Bind a regulator to a symbolic supply
  * @rdev:         regulator source
- * @consumer_dev: device the supply applies to
  * @consumer_dev_name: dev_name() string for device supply applies to
  * @supply:       symbolic name for supply
  *
@@ -1004,22 +1002,14 @@ static int set_supply(struct regulator_dev *rdev,
  * sources to symbolic names for supplies for use by devices.  Devices
  * should use these symbolic names to request regulators, avoiding the
  * need to provide board-specific regulator names as platform data.
- *
- * Only one of consumer_dev and consumer_dev_name may be specified.
  */
 static int set_consumer_device_supply(struct regulator_dev *rdev,
-       struct device *consumer_dev, const char *consumer_dev_name,
-       const char *supply)
+                                     const char *consumer_dev_name,
+                                     const char *supply)
 {
        struct regulator_map *node;
        int has_dev;
 
-       if (consumer_dev && consumer_dev_name)
-               return -EINVAL;
-
-       if (!consumer_dev_name && consumer_dev)
-               consumer_dev_name = dev_name(consumer_dev);
-
        if (supply == NULL)
                return -EINVAL;
 
@@ -1039,11 +1029,12 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
                if (strcmp(node->supply, supply) != 0)
                        continue;
 
-               dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n",
-                       dev_name(&node->regulator->dev),
-                       node->regulator->desc->name,
-                       supply,
-                       dev_name(&rdev->dev), rdev_get_name(rdev));
+               pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n",
+                        consumer_dev_name,
+                        dev_name(&node->regulator->dev),
+                        node->regulator->desc->name,
+                        supply,
+                        dev_name(&rdev->dev), rdev_get_name(rdev));
                return -EBUSY;
        }
 
@@ -1142,12 +1133,10 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                        goto attr_err;
        }
 
-#ifdef CONFIG_DEBUG_FS
        regulator->debugfs = debugfs_create_dir(regulator->supply_name,
                                                rdev->debugfs);
-       if (IS_ERR_OR_NULL(regulator->debugfs)) {
+       if (!regulator->debugfs) {
                rdev_warn(rdev, "Failed to create debugfs directory\n");
-               regulator->debugfs = NULL;
        } else {
                debugfs_create_u32("uA_load", 0444, regulator->debugfs,
                                   &regulator->uA_load);
@@ -1156,7 +1145,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                debugfs_create_u32("max_uV", 0444, regulator->debugfs,
                                   &regulator->max_uV);
        }
-#endif
 
        mutex_unlock(&rdev->mutex);
        return regulator;
@@ -1210,7 +1198,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 {
        struct regulator_dev *rdev;
        struct regulator_map *map;
-       struct regulator *regulator = ERR_PTR(-ENODEV);
+       struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
        const char *devname = NULL;
        int ret;
 
@@ -1399,9 +1387,7 @@ void regulator_put(struct regulator *regulator)
        mutex_lock(&regulator_list_mutex);
        rdev = regulator->rdev;
 
-#ifdef CONFIG_DEBUG_FS
        debugfs_remove_recursive(regulator->debugfs);
-#endif
 
        /* remove any sysfs entries */
        if (regulator->dev) {
@@ -1904,8 +1890,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                        if (ret < 0)
                                return ret;
                        old_selector = ret;
-                       delay = rdev->desc->ops->set_voltage_time_sel(rdev,
+                       ret = rdev->desc->ops->set_voltage_time_sel(rdev,
                                                old_selector, selector);
+                       if (ret < 0)
+                               rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
+                       else
+                               delay = ret;
                }
 
                if (best_val != INT_MAX) {
@@ -2456,7 +2446,7 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
        return 0;
 
 err:
-       for (i = 0; i < num_consumers && consumers[i].consumer; i++)
+       while (--i >= 0)
                regulator_put(consumers[i].consumer);
 
        return ret;
@@ -2552,12 +2542,9 @@ int regulator_bulk_enable(int num_consumers,
        return 0;
 
 err:
-       for (i = 0; i < num_consumers; i++)
-               if (consumers[i].ret == 0)
-                       regulator_disable(consumers[i].consumer);
-               else
-                       pr_err("Failed to enable %s: %d\n",
-                              consumers[i].supply, consumers[i].ret);
+       pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
+       while (--i >= 0)
+               regulator_disable(consumers[i].consumer);
 
        return ret;
 }
@@ -2571,8 +2558,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable);
  * @return         0 on success, an errno on failure
  *
  * This convenience API allows consumers to disable multiple regulator
- * clients in a single API call.  If any consumers cannot be enabled
- * then any others that were disabled will be disabled again prior to
+ * clients in a single API call.  If any consumers cannot be disabled
+ * then any others that were disabled will be enabled again prior to
  * return.
  */
 int regulator_bulk_disable(int num_consumers,
@@ -2581,7 +2568,7 @@ int regulator_bulk_disable(int num_consumers,
        int i;
        int ret;
 
-       for (i = 0; i < num_consumers; i++) {
+       for (i = num_consumers - 1; i >= 0; --i) {
                ret = regulator_disable(consumers[i].consumer);
                if (ret != 0)
                        goto err;
@@ -2591,7 +2578,7 @@ int regulator_bulk_disable(int num_consumers,
 
 err:
        pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
-       for (--i; i >= 0; --i)
+       for (++i; i < num_consumers; ++i)
                regulator_enable(consumers[i].consumer);
 
        return ret;
@@ -2818,11 +2805,9 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
 
 static void rdev_init_debugfs(struct regulator_dev *rdev)
 {
-#ifdef CONFIG_DEBUG_FS
        rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
-       if (IS_ERR(rdev->debugfs) || !rdev->debugfs) {
+       if (!rdev->debugfs) {
                rdev_warn(rdev, "Failed to create debugfs directory\n");
-               rdev->debugfs = NULL;
                return;
        }
 
@@ -2830,7 +2815,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
                           &rdev->use_count);
        debugfs_create_u32("open_count", 0444, rdev->debugfs,
                           &rdev->open_count);
-#endif
 }
 
 /**
@@ -2942,7 +2926,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 
                if (!r) {
                        dev_err(dev, "Failed to find supply %s\n", supply);
-                       ret = -ENODEV;
+                       ret = -EPROBE_DEFER;
                        goto scrub;
                }
 
@@ -2963,7 +2947,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        if (init_data) {
                for (i = 0; i < init_data->num_consumer_supplies; i++) {
                        ret = set_consumer_device_supply(rdev,
-                               init_data->consumer_supplies[i].dev,
                                init_data->consumer_supplies[i].dev_name,
                                init_data->consumer_supplies[i].supply);
                        if (ret < 0) {
@@ -3009,16 +2992,14 @@ void regulator_unregister(struct regulator_dev *rdev)
        if (rdev == NULL)
                return;
 
+       if (rdev->supply)
+               regulator_put(rdev->supply);
        mutex_lock(&regulator_list_mutex);
-#ifdef CONFIG_DEBUG_FS
        debugfs_remove_recursive(rdev->debugfs);
-#endif
        flush_work_sync(&rdev->disable_work.work);
        WARN_ON(rdev->open_count);
        unset_regulator_supplies(rdev);
        list_del(&rdev->list);
-       if (rdev->supply)
-               regulator_put(rdev->supply);
        kfree(rdev->constraints);
        device_unregister(&rdev->dev);
        mutex_unlock(&regulator_list_mutex);
@@ -3222,12 +3203,14 @@ static ssize_t supply_map_read_file(struct file *file, char __user *user_buf,
 
        return ret;
 }
+#endif
 
 static const struct file_operations supply_map_fops = {
+#ifdef CONFIG_DEBUG_FS
        .read = supply_map_read_file,
        .llseek = default_llseek,
-};
 #endif
+};
 
 static int __init regulator_init(void)
 {
@@ -3235,17 +3218,12 @@ static int __init regulator_init(void)
 
        ret = class_register(&regulator_class);
 
-#ifdef CONFIG_DEBUG_FS
        debugfs_root = debugfs_create_dir("regulator", NULL);
-       if (IS_ERR(debugfs_root) || !debugfs_root) {
+       if (!debugfs_root)
                pr_warn("regulator: Failed to create debugfs directory\n");
-               debugfs_root = NULL;
-       }
 
-       if (IS_ERR(debugfs_create_file("supply_map", 0444, debugfs_root,
-                                      NULL, &supply_map_fops)))
-               pr_warn("regulator: Failed to create supplies debugfs\n");
-#endif
+       debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
+                           &supply_map_fops);
 
        regulator_dummy_init();