All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 5.10 1/8] regulator: core: Only increment use_count when enable_count changes
@ 2024-01-16  0:14 Sasha Levin
  2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 2/8] audit: Send netlink ACK before setting connection in auditd_set Sasha Levin
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Sasha Levin @ 2024-01-16  0:14 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: Rui Zhang, Mark Brown, Sasha Levin, lgirdwood

From: Rui Zhang <zr.zhang@vivo.com>

[ Upstream commit 7993d3a9c34f609c02171e115fd12c10e2105ff4 ]

The use_count of a regulator should only be incremented when the
enable_count changes from 0 to 1. Similarly, the use_count should
only be decremented when the enable_count changes from 1 to 0.

In the previous implementation, use_count was sometimes decremented
to 0 when some consumer called unbalanced disable,
leading to unexpected disable even the regulator is enabled by
other consumers. With this change, the use_count accurately reflects
the number of users which the regulator is enabled.

This should make things more robust in the case where a consumer does
leak references.

Signed-off-by: Rui Zhang <zr.zhang@vivo.com>
Link: https://lore.kernel.org/r/20231103074231.8031-1-zr.zhang@vivo.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/regulator/core.c | 56 +++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 51c4f604d3b2..54330eb0d03b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2768,7 +2768,8 @@ static int _regulator_enable(struct regulator *regulator)
 		/* Fallthrough on positive return values - already enabled */
 	}
 
-	rdev->use_count++;
+	if (regulator->enable_count == 1)
+		rdev->use_count++;
 
 	return 0;
 
@@ -2846,37 +2847,40 @@ static int _regulator_disable(struct regulator *regulator)
 
 	lockdep_assert_held_once(&rdev->mutex.base);
 
-	if (WARN(rdev->use_count <= 0,
+	if (WARN(regulator->enable_count == 0,
 		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
 		return -EIO;
 
-	/* are we the last user and permitted to disable ? */
-	if (rdev->use_count == 1 &&
-	    (rdev->constraints && !rdev->constraints->always_on)) {
-
-		/* we are last user */
-		if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
-			ret = _notifier_call_chain(rdev,
-						   REGULATOR_EVENT_PRE_DISABLE,
-						   NULL);
-			if (ret & NOTIFY_STOP_MASK)
-				return -EINVAL;
-
-			ret = _regulator_do_disable(rdev);
-			if (ret < 0) {
-				rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret));
-				_notifier_call_chain(rdev,
-						REGULATOR_EVENT_ABORT_DISABLE,
+	if (regulator->enable_count == 1) {
+	/* disabling last enable_count from this regulator */
+		/* are we the last user and permitted to disable ? */
+		if (rdev->use_count == 1 &&
+		    (rdev->constraints && !rdev->constraints->always_on)) {
+
+			/* we are last user */
+			if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
+				ret = _notifier_call_chain(rdev,
+							   REGULATOR_EVENT_PRE_DISABLE,
+							   NULL);
+				if (ret & NOTIFY_STOP_MASK)
+					return -EINVAL;
+
+				ret = _regulator_do_disable(rdev);
+				if (ret < 0) {
+					rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret));
+					_notifier_call_chain(rdev,
+							REGULATOR_EVENT_ABORT_DISABLE,
+							NULL);
+					return ret;
+				}
+				_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
 						NULL);
-				return ret;
 			}
-			_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
-					NULL);
-		}
 
-		rdev->use_count = 0;
-	} else if (rdev->use_count > 1) {
-		rdev->use_count--;
+			rdev->use_count = 0;
+		} else if (rdev->use_count > 1) {
+			rdev->use_count--;
+		}
 	}
 
 	if (ret == 0)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-01-30 21:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-16  0:14 [PATCH AUTOSEL 5.10 1/8] regulator: core: Only increment use_count when enable_count changes Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 2/8] audit: Send netlink ACK before setting connection in auditd_set Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 3/8] platform/chrome: cros_ec_debugfs: Fix permissions for panicinfo Sasha Levin
2024-01-16 20:45   ` Pavel Machek
2024-01-30 21:05     ` Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 4/8] ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 5/8] PNP: ACPI: fix fortify warning Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 6/8] ACPI: extlog: fix NULL pointer dereference check Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 7/8] PM / devfreq: Synchronize devfreq_monitor_[start/stop] Sasha Levin
2024-01-16  0:14 ` [PATCH AUTOSEL 5.10 8/8] ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous events Sasha Levin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.