lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20220829165543.24856-1-christian@kohlschutter.com>
Date:   Mon, 29 Aug 2022 16:55:43 +0000
From:   Christian Kohlschütter 
        <christian@...lschutter.com>
To:     m.szyprowski@...sung.com, Liam Girdwood <lgirdwood@...il.com>,
        Mark Brown <broonie@...nel.org>,
        Christian Kohlschütter 
        <christian@...lschutter.com>
Cc:     linux-kernel@...r.kernel.org
Subject: [PATCH] regulator: core: Fix regulator supply registration with sysfs

In "regulator: core: Resolve supply name earlier to prevent
double-init", we introduced a bug that prevented the regulator names
from registering properly with sysfs.

Reorder regulator_register such that supply names are properly resolved
and registered.

Fixes: 8a866d527ac0 ("regulator: core: Resolve supply name earlier to prevent double-init")
Link: https://lore.kernel.org/all/58b92e75-f373-dae7-7031-8abd465bb874@samsung.com/
Signed-off-by: Christian Kohlschütter <christian@...lschutter.com>
---
 drivers/regulator/core.c | 44 +++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 1d030831ae..b1ece764de 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -5414,6 +5414,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 	bool dangling_of_gpiod = false;
 	struct device *dev;
 	int ret, i;
+	bool resolved_early = false;
 
 	if (cfg == NULL)
 		return ERR_PTR(-EINVAL);
@@ -5517,6 +5518,18 @@ regulator_register(const struct regulator_desc *regulator_desc,
 	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
 	INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
 
+	if (init_data && init_data->supply_regulator)
+		rdev->supply_name = init_data->supply_regulator;
+	else if (regulator_desc->supply_name)
+		rdev->supply_name = regulator_desc->supply_name;
+
+	/* register with sysfs */
+	rdev->dev.class = &regulator_class;
+	rdev->dev.parent = dev;
+	dev_set_name(&rdev->dev, "regulator.%lu",
+		    (unsigned long) atomic_inc_return(&regulator_no));
+	dev_set_drvdata(&rdev->dev, rdev);
+
 	/* set regulator constraints */
 	if (init_data)
 		rdev->constraints = kmemdup(&init_data->constraints,
@@ -5527,33 +5540,25 @@ regulator_register(const struct regulator_desc *regulator_desc,
 					    GFP_KERNEL);
 	if (!rdev->constraints) {
 		ret = -ENOMEM;
-		goto clean;
+		goto wash;
 	}
 
-	if (init_data && init_data->supply_regulator)
-		rdev->supply_name = init_data->supply_regulator;
-	else if (regulator_desc->supply_name)
-		rdev->supply_name = regulator_desc->supply_name;
-
 	if ((rdev->supply_name && !rdev->supply) &&
-			(rdev->constraints->always_on ||
-			 rdev->constraints->boot_on)) {
-		/* Try to resolve the name of the supplying regulator here first
-		 * so we prevent double-initializing the regulator, which may
-		 * cause timing-specific voltage brownouts/glitches that are
-		 * hard to debug.
-		 */
+		(rdev->constraints->always_on ||
+		 rdev->constraints->boot_on)) {
 		ret = regulator_resolve_supply(rdev);
 		if (ret)
 			rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
 					 ERR_PTR(ret));
+
+		resolved_early = true;
 	}
 
 	/* perform any regulator specific init */
 	if (init_data && init_data->regulator_init) {
 		ret = init_data->regulator_init(rdev->reg_data);
 		if (ret < 0)
-			goto clean;
+			goto wash;
 	}
 
 	if (config->ena_gpiod) {
@@ -5561,22 +5566,15 @@ regulator_register(const struct regulator_desc *regulator_desc,
 		if (ret != 0) {
 			rdev_err(rdev, "Failed to request enable GPIO: %pe\n",
 				 ERR_PTR(ret));
-			goto clean;
+			goto wash;
 		}
 		/* The regulator core took over the GPIO descriptor */
 		dangling_cfg_gpiod = false;
 		dangling_of_gpiod = false;
 	}
 
-	/* register with sysfs */
-	rdev->dev.class = &regulator_class;
-	rdev->dev.parent = dev;
-	dev_set_name(&rdev->dev, "regulator.%lu",
-		    (unsigned long) atomic_inc_return(&regulator_no));
-	dev_set_drvdata(&rdev->dev, rdev);
-
 	ret = set_machine_constraints(rdev);
-	if (ret == -EPROBE_DEFER) {
+	if (ret == -EPROBE_DEFER && !resolved_early) {
 		/* Regulator might be in bypass mode and so needs its supply
 		 * to set the constraints
 		 */
-- 
2.36.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ