]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Thu, 11 Feb 2021 18:05:13 +0000 (13:05 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 11 Feb 2021 18:05:13 +0000 (13:05 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/regulator-core-clean-enabling-always-on-regulators-t.patch [new file with mode: 0644]
queue-4.19/regulator-core-enable-power-when-setting-up-constrai.patch [new file with mode: 0644]
queue-4.19/regulator-fix-lockdep-warning-resolving-supplies.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/regulator-core-clean-enabling-always-on-regulators-t.patch b/queue-4.19/regulator-core-clean-enabling-always-on-regulators-t.patch
new file mode 100644 (file)
index 0000000..f184c7e
--- /dev/null
@@ -0,0 +1,106 @@
+From 1100c4b652441bc91aa322c5caee05a3738a9ea1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Dec 2018 14:23:18 -0800
+Subject: regulator: core: Clean enabling always-on regulators + their supplies
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 05f224ca669398b567d09feb6e2ceefcb7d7f945 ]
+
+At the end of regulator_resolve_supply() we have historically turned
+on our supply in some cases.  This could be for one of two reasons:
+
+1. If resolving supplies was happening before the call to
+   set_machine_constraints() we needed to predict if
+   set_machine_constraints() was going to turn the regulator on and we
+   needed to preemptively turn the supply on.
+2. Maybe set_machine_constraints() happened before we could resolve
+   supplies (because we failed the first time to resolve) and thus we
+   might need to propagate an enable that already happened up to our
+   supply.
+
+Historically regulator_resolve_supply() used _regulator_is_enabled()
+to decide whether to turn on the supply.
+
+Let's change things a little bit.  Specifically:
+
+1. Let's try to enable the supply and the regulator in the same place,
+   both in set_machine_constraints().  This means that we have exactly
+   the same logic for enabling the supply and the regulator.
+2. Let's properly set use_count when we enable always-on or boot-on
+   regulators even for those that don't have supplies.  The previous
+   commit 1fc12b05895e ("regulator: core: Avoid propagating to
+   supplies when possible") only did this right for regulators with
+   supplies.
+3. Let's make it clear that the only time we need to enable the supply
+   in regulator_resolve_supply() is if the main regulator is currently
+   in use.  By using use_count (like the rest of the code) to decide
+   if we're going to enable our supply we keep everything consistent.
+
+Overall the new scheme should be cleaner and easier to reason about.
+In addition to fixing regulator_summary to be more correct (because of
+the more correct use_count), this change also has the effect of no
+longer using _regulator_is_enabled() in this code path.
+_regulator_is_enabled() could return an error code for some regulators
+at bootup (like RPMh) that can't read their initial state.  While one
+can argue that the design of those regulators is sub-optimal, the new
+logic sidesteps this brokenness.  This fix in particular fixes
+observed problems on Qualcomm sdm845 boards which use the
+above-mentioned RPMh regulator.  Those problems were made worse by
+commit 1fc12b05895e ("regulator: core: Avoid propagating to supplies
+when possible") because now we'd think at bootup that the SD
+regulators were already enabled and we'd never try them again.
+
+Fixes: 1fc12b05895e ("regulator: core: Avoid propagating to supplies when possible")
+Reported-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 870baa7036ecd..b79ecf37e40f8 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1191,11 +1191,21 @@ 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 (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);
+@@ -1645,8 +1655,12 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
+               goto out;
+       }
+-      /* 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);
+-- 
+2.27.0
+
diff --git a/queue-4.19/regulator-core-enable-power-when-setting-up-constrai.patch b/queue-4.19/regulator-core-enable-power-when-setting-up-constrai.patch
new file mode 100644 (file)
index 0000000..37f5f4a
--- /dev/null
@@ -0,0 +1,73 @@
+From 9224f99447bb9ee3f5a622baaa093278518923ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Nov 2018 17:27:44 +0200
+Subject: regulator: core: enable power when setting up constraints
+
+From: Olliver Schinagl <oliver@schinagl.nl>
+
+[ Upstream commit 2bb1666369339f69f227ad060c250afde94d5c69 ]
+
+When a regulator is marked as always on, it is enabled early on, when
+checking and setting up constraints. It makes the assumption that the
+bootloader properly initialized the regulator, and just in case enables
+the regulator anyway.
+
+Some constraints however currently get missed, such as the soft-start
+and ramp-delay. This causes the regulator to be enabled, without the
+soft-start and ramp-delay being applied, which in turn can cause
+high-currents or other start-up problems.
+
+By moving the always-enabled constraints later in the constraints check,
+we can at least ensure all constraints for the regulator are followed.
+
+Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
+Signed-off-by: Priit Laes <plaes@plaes.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index fa8f5fc04d8fd..870baa7036ecd 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1142,17 +1142,6 @@ 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) {
+-              ret = _regulator_do_enable(rdev);
+-              if (ret < 0 && ret != -EINVAL) {
+-                      rdev_err(rdev, "failed to enable\n");
+-                      return ret;
+-              }
+-      }
+-
+       if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable)
+               && ops->set_ramp_delay) {
+               ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
+@@ -1198,6 +1187,17 @@ 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) {
++              ret = _regulator_do_enable(rdev);
++              if (ret < 0 && ret != -EINVAL) {
++                      rdev_err(rdev, "failed to enable\n");
++                      return ret;
++              }
++      }
++
+       print_constraints(rdev);
+       return 0;
+ }
+-- 
+2.27.0
+
diff --git a/queue-4.19/regulator-fix-lockdep-warning-resolving-supplies.patch b/queue-4.19/regulator-fix-lockdep-warning-resolving-supplies.patch
new file mode 100644 (file)
index 0000000..c66797c
--- /dev/null
@@ -0,0 +1,94 @@
+From b5d4423f125c87cdc5c5df88e67dab91d091ba7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jan 2021 13:20:42 +0000
+Subject: regulator: Fix lockdep warning resolving supplies
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 14a71d509ac809dcf56d7e3ca376b15d17bd0ddd ]
+
+With commit eaa7995c529b54 (regulator: core: avoid
+regulator_resolve_supply() race condition) we started holding the rdev
+lock while resolving supplies, an operation that requires holding the
+regulator_list_mutex. This results in lockdep warnings since in other
+places we take the list mutex then the mutex on an individual rdev.
+
+Since the goal is to make sure that we don't call set_supply() twice
+rather than a concern about the cost of resolution pull the rdev lock
+and check for duplicate resolution down to immediately before we do the
+set_supply() and drop it again once the allocation is done.
+
+Fixes: eaa7995c529b54 (regulator: core: avoid regulator_resolve_supply() race condition)
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20210122132042.10306-1-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index b79ecf37e40f8..65e1cde13d59e 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1587,17 +1587,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);
+@@ -1649,12 +1638,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
+@@ -1670,7 +1676,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
+       }
+ out:
+-      regulator_unlock(rdev);
+       return ret;
+ }
+-- 
+2.27.0
+
index b583450f34b1d55a87c132fd9cc3005c3d946184..7a355a52dd1fc2deb2b7158609773a6f79af90b8 100644 (file)
@@ -22,3 +22,6 @@ blk-mq-don-t-hold-q-sysfs_lock-in-blk_mq_map_swqueue.patch
 squashfs-add-more-sanity-checks-in-id-lookup.patch
 squashfs-add-more-sanity-checks-in-inode-lookup.patch
 squashfs-add-more-sanity-checks-in-xattr-id-lookup.patch
+regulator-core-enable-power-when-setting-up-constrai.patch
+regulator-core-clean-enabling-always-on-regulators-t.patch
+regulator-fix-lockdep-warning-resolving-supplies.patch