]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/regulator/core.c
staging: gdm724x: check for overflow in gdm_lte_netif_rx()
[mirror_ubuntu-hirsute-kernel.git] / drivers / regulator / core.c
index cfc3bc9df93a0912bacf6790096e501bb49e892c..1818fbd640b9acfe0acfbd36d5c55e0b56edc686 100644 (file)
@@ -1422,6 +1422,12 @@ static int set_machine_constraints(struct regulator_dev *rdev)
         * and we have control then make sure it is enabled.
         */
        if (rdev->constraints->always_on || rdev->constraints->boot_on) {
+               /* If we want to enable this regulator, make sure that we know
+                * the supplying regulator.
+                */
+               if (rdev->supply_name && !rdev->supply)
+                       return -EPROBE_DEFER;
+
                if (rdev->supply) {
                        ret = regulator_enable(rdev->supply);
                        if (ret < 0) {
@@ -1617,7 +1623,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                                          const char *supply_name)
 {
        struct regulator *regulator;
-       int err;
+       int err = 0;
 
        if (dev) {
                char buf[REG_STR_SIZE];
@@ -1663,8 +1669,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                }
        }
 
-       regulator->debugfs = debugfs_create_dir(supply_name,
-                                               rdev->debugfs);
+       if (err != -EEXIST)
+               regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
        if (!regulator->debugfs) {
                rdev_dbg(rdev, "Failed to create debugfs directory\n");
        } else {
@@ -1823,17 +1829,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
        if (rdev->supply)
                return 0;
 
-       /*
-        * Recheck rdev->supply with rdev->mutex lock held to avoid a race
-        * between rdev->supply null check and setting rdev->supply in
-        * set_supply() from concurrent tasks.
-        */
-       regulator_lock(rdev);
-
-       /* Supply just resolved by a concurrent task? */
-       if (rdev->supply)
-               goto out;
-
        r = regulator_dev_lookup(dev, rdev->supply_name);
        if (IS_ERR(r)) {
                ret = PTR_ERR(r);
@@ -1885,12 +1880,29 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                goto out;
        }
 
+       /*
+        * Recheck rdev->supply with rdev->mutex lock held to avoid a race
+        * between rdev->supply null check and setting rdev->supply in
+        * set_supply() from concurrent tasks.
+        */
+       regulator_lock(rdev);
+
+       /* Supply just resolved by a concurrent task? */
+       if (rdev->supply) {
+               regulator_unlock(rdev);
+               put_device(&r->dev);
+               goto out;
+       }
+
        ret = set_supply(rdev, r);
        if (ret < 0) {
+               regulator_unlock(rdev);
                put_device(&r->dev);
                goto out;
        }
 
+       regulator_unlock(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
@@ -1906,7 +1918,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
        }
 
 out:
-       regulator_unlock(rdev);
        return ret;
 }