Merge tag 'perf-core-for-mingo-4.21-20190103' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / drivers / regulator / core.c
index 26a0c52..b9d7b45 100644 (file)
@@ -211,6 +211,7 @@ void regulator_lock(struct regulator_dev *rdev)
 {
        regulator_lock_nested(rdev, NULL);
 }
+EXPORT_SYMBOL_GPL(regulator_lock);
 
 /**
  * regulator_unlock - unlock a single regulator
@@ -232,6 +233,7 @@ void regulator_unlock(struct regulator_dev *rdev)
 
        mutex_unlock(&regulator_nesting_mutex);
 }
+EXPORT_SYMBOL_GPL(regulator_unlock);
 
 static bool regulator_supply_is_couple(struct regulator_dev *rdev)
 {
@@ -1342,17 +1344,12 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                        rdev_err(rdev, "failed to set initial mode: %d\n", ret);
                        return ret;
                }
-       }
-
-       /* If the constraints say the regulator should be on at this point
-        * and we have control then make sure it is enabled.
-        */
-       if (rdev->constraints->always_on || rdev->constraints->boot_on) {
-               ret = _regulator_do_enable(rdev);
-               if (ret < 0 && ret != -EINVAL) {
-                       rdev_err(rdev, "failed to enable\n");
-                       return ret;
-               }
+       } else if (rdev->constraints->system_load) {
+               /*
+                * We'll only apply the initial system load if an
+                * initial mode wasn't specified.
+                */
+               drms_uA_update(rdev);
        }
 
        if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable)
@@ -1400,6 +1397,27 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                }
        }
 
+       /* If the constraints say the regulator should be on at this point
+        * and we have control then make sure it is enabled.
+        */
+       if (rdev->constraints->always_on || rdev->constraints->boot_on) {
+               if (rdev->supply) {
+                       ret = regulator_enable(rdev->supply);
+                       if (ret < 0) {
+                               _regulator_put(rdev->supply);
+                               rdev->supply = NULL;
+                               return ret;
+                       }
+               }
+
+               ret = _regulator_do_enable(rdev);
+               if (ret < 0 && ret != -EINVAL) {
+                       rdev_err(rdev, "failed to enable\n");
+                       return ret;
+               }
+               rdev->use_count++;
+       }
+
        print_constraints(rdev);
        return 0;
 }
@@ -1814,8 +1832,12 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                return ret;
        }
 
-       /* Cascade always-on state to supply */
-       if (_regulator_is_enabled(rdev)) {
+       /*
+        * In set_machine_constraints() we may have turned this regulator on
+        * but we couldn't propagate to the supply if it hadn't been resolved
+        * yet.  Do it now.
+        */
+       if (rdev->use_count) {
                ret = regulator_enable(rdev->supply);
                if (ret < 0) {
                        _regulator_put(rdev->supply);
@@ -2491,7 +2513,7 @@ static int _regulator_enable(struct regulator *regulator)
 
        lockdep_assert_held_once(&rdev->mutex.base);
 
-       if (rdev->supply) {
+       if (rdev->use_count == 0 && rdev->supply) {
                ret = _regulator_enable(rdev->supply);
                if (ret < 0)
                        return ret;
@@ -2539,7 +2561,7 @@ err_consumer_disable:
        _regulator_handle_consumer_disable(regulator);
 
 err_disable_supply:
-       if (rdev->supply)
+       if (rdev->use_count == 0 && rdev->supply)
                _regulator_disable(rdev->supply);
 
        return ret;
@@ -2648,7 +2670,7 @@ static int _regulator_disable(struct regulator *regulator)
        if (ret == 0 && rdev->coupling_desc.n_coupled > 1)
                ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
 
-       if (ret == 0 && rdev->supply)
+       if (ret == 0 && rdev->use_count == 0 && rdev->supply)
                ret = _regulator_disable(rdev->supply);
 
        return ret;
@@ -2733,11 +2755,10 @@ int regulator_force_disable(struct regulator *regulator)
                ret = drms_uA_update(rdev);
        }
 
-       regulator_unlock_dependent(rdev, &ww_ctx);
+       if (rdev->use_count != 0 && rdev->supply)
+               _regulator_disable(rdev->supply);
 
-       if (rdev->supply)
-               while (rdev->open_count--)
-                       regulator_disable(rdev->supply);
+       regulator_unlock_dependent(rdev, &ww_ctx);
 
        return ret;
 }
@@ -2783,16 +2804,6 @@ static void regulator_disable_work(struct work_struct *work)
                regulator_balance_voltage(rdev, PM_SUSPEND_ON);
 
        regulator_unlock_dependent(rdev, &ww_ctx);
-
-       if (rdev->supply) {
-               for (i = 0; i < count; i++) {
-                       ret = regulator_disable(rdev->supply);
-                       if (ret != 0) {
-                               rdev_err(rdev,
-                                        "Supply disable failed: %d\n", ret);
-                       }
-               }
-       }
 }
 
 /**
@@ -4862,21 +4873,33 @@ regulator_register(const struct regulator_desc *regulator_desc,
        struct regulator_config *config = NULL;
        static atomic_t regulator_no = ATOMIC_INIT(-1);
        struct regulator_dev *rdev;
+       bool dangling_cfg_gpiod = false;
+       bool dangling_of_gpiod = false;
        struct device *dev;
        int ret, i;
 
-       if (regulator_desc == NULL || cfg == NULL)
+       if (cfg == NULL)
                return ERR_PTR(-EINVAL);
+       if (cfg->ena_gpiod)
+               dangling_cfg_gpiod = true;
+       if (regulator_desc == NULL) {
+               ret = -EINVAL;
+               goto rinse;
+       }
 
        dev = cfg->dev;
        WARN_ON(!dev);
 
-       if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
-               return ERR_PTR(-EINVAL);
+       if (regulator_desc->name == NULL || regulator_desc->ops == NULL) {
+               ret = -EINVAL;
+               goto rinse;
+       }
 
        if (regulator_desc->type != REGULATOR_VOLTAGE &&
-           regulator_desc->type != REGULATOR_CURRENT)
-               return ERR_PTR(-EINVAL);
+           regulator_desc->type != REGULATOR_CURRENT) {
+               ret = -EINVAL;
+               goto rinse;
+       }
 
        /* Only one of each should be implemented */
        WARN_ON(regulator_desc->ops->get_voltage &&
@@ -4887,16 +4910,20 @@ regulator_register(const struct regulator_desc *regulator_desc,
        /* If we're using selectors we must implement list_voltage. */
        if (regulator_desc->ops->get_voltage_sel &&
            !regulator_desc->ops->list_voltage) {
-               return ERR_PTR(-EINVAL);
+               ret = -EINVAL;
+               goto rinse;
        }
        if (regulator_desc->ops->set_voltage_sel &&
            !regulator_desc->ops->list_voltage) {
-               return ERR_PTR(-EINVAL);
+               ret = -EINVAL;
+               goto rinse;
        }
 
        rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
-       if (rdev == NULL)
-               return ERR_PTR(-ENOMEM);
+       if (rdev == NULL) {
+               ret = -ENOMEM;
+               goto rinse;
+       }
 
        /*
         * Duplicate the config so the driver could override it after
@@ -4905,11 +4932,22 @@ regulator_register(const struct regulator_desc *regulator_desc,
        config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL);
        if (config == NULL) {
                kfree(rdev);
-               return ERR_PTR(-ENOMEM);
+               ret = -ENOMEM;
+               goto rinse;
        }
 
        init_data = regulator_of_get_init_data(dev, regulator_desc, config,
                                               &rdev->dev.of_node);
+       /*
+        * We need to keep track of any GPIO descriptor coming from the
+        * device tree until we have handled it over to the core. If the
+        * config that was passed in to this function DOES NOT contain
+        * a descriptor, and the config after this call DOES contain
+        * a descriptor, we definately got one from parsing the device
+        * tree.
+        */
+       if (!cfg->ena_gpiod && config->ena_gpiod)
+               dangling_of_gpiod = true;
        if (!init_data) {
                init_data = config->init_data;
                rdev->dev.of_node = of_node_get(config->of_node);
@@ -4948,6 +4986,9 @@ regulator_register(const struct regulator_desc *regulator_desc,
                                 config->ena_gpio, ret);
                        goto clean;
                }
+               /* The regulator core took over the GPIO descriptor */
+               dangling_cfg_gpiod = false;
+               dangling_of_gpiod = false;
        }
 
        /* register with sysfs */
@@ -5033,8 +5074,13 @@ wash:
        regulator_ena_gpio_free(rdev);
        mutex_unlock(&regulator_list_mutex);
 clean:
+       if (dangling_of_gpiod)
+               gpiod_put(config->ena_gpiod);
        kfree(rdev);
        kfree(config);
+rinse:
+       if (dangling_cfg_gpiod)
+               gpiod_put(cfg->ena_gpiod);
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(regulator_register);
@@ -5224,23 +5270,8 @@ static int supply_map_show(struct seq_file *sf, void *data)
 
        return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(supply_map);
 
-static int supply_map_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, supply_map_show, inode->i_private);
-}
-#endif
-
-static const struct file_operations supply_map_fops = {
-#ifdef CONFIG_DEBUG_FS
-       .open = supply_map_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-#endif
-};
-
-#ifdef CONFIG_DEBUG_FS
 struct summary_data {
        struct seq_file *s;
        struct regulator_dev *parent;
@@ -5462,21 +5493,8 @@ static int regulator_summary_show(struct seq_file *s, void *data)
 
        return 0;
 }
-
-static int regulator_summary_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, regulator_summary_show, inode->i_private);
-}
-#endif
-
-static const struct file_operations regulator_summary_fops = {
-#ifdef CONFIG_DEBUG_FS
-       .open           = regulator_summary_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-#endif
-};
+DEFINE_SHOW_ATTRIBUTE(regulator_summary);
+#endif /* CONFIG_DEBUG_FS */
 
 static int __init regulator_init(void)
 {
@@ -5488,12 +5506,13 @@ static int __init regulator_init(void)
        if (!debugfs_root)
                pr_warn("regulator: Failed to create debugfs directory\n");
 
+#ifdef CONFIG_DEBUG_FS
        debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
                            &supply_map_fops);
 
        debugfs_create_file("regulator_summary", 0444, debugfs_root,
                            NULL, &regulator_summary_fops);
-
+#endif
        regulator_dummy_init();
 
        return ret;