regulator: core: Properly handle case where supply is the couple
authorDmitry Osipenko <digetx@gmail.com>
Sun, 18 Nov 2018 21:56:18 +0000 (00:56 +0300)
committerMark Brown <broonie@kernel.org>
Mon, 19 Nov 2018 12:33:18 +0000 (12:33 +0000)
Check whether supply regulator is the couple to avoid infinite recursion
during of locking.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/regulator/core.c

index 47ccd35..e46e53a 100644 (file)
@@ -233,6 +233,21 @@ void regulator_unlock(struct regulator_dev *rdev)
        mutex_unlock(&regulator_nesting_mutex);
 }
 
+static bool regulator_supply_is_couple(struct regulator_dev *rdev)
+{
+       struct regulator_dev *c_rdev;
+       int i;
+
+       for (i = 1; i < rdev->coupling_desc.n_coupled; i++) {
+               c_rdev = rdev->coupling_desc.coupled_rdevs[i];
+
+               if (rdev->supply->rdev == c_rdev)
+                       return true;
+       }
+
+       return false;
+}
+
 static void regulator_unlock_recursive(struct regulator_dev *rdev,
                                       unsigned int n_coupled)
 {
@@ -245,7 +260,7 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev,
                if (!c_rdev)
                        continue;
 
-               if (c_rdev->supply)
+               if (c_rdev->supply && !regulator_supply_is_couple(c_rdev))
                        regulator_unlock_recursive(
                                        c_rdev->supply->rdev,
                                        c_rdev->coupling_desc.n_coupled);
@@ -283,7 +298,7 @@ static int regulator_lock_recursive(struct regulator_dev *rdev,
                        *old_contended_rdev = NULL;
                }
 
-               if (c_rdev->supply) {
+               if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) {
                        err = regulator_lock_recursive(c_rdev->supply->rdev,
                                                       new_contended_rdev,
                                                       old_contended_rdev,