public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.1 1/9] regulator: core: Only increment use_count when enable_count changes
@ 2024-01-16  0:14 Sasha Levin
  2024-01-16  0:14 ` [PATCH AUTOSEL 6.1 2/9] audit: Send netlink ACK before setting connection in auditd_set Sasha Levin
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ 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 34d3d8281906..c8702011b761 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2925,7 +2925,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;
 
@@ -3000,37 +3001,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] 9+ messages in thread

end of thread, other threads:[~2024-01-16  0:14 UTC | newest]

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox