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 for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20180304032018.12238-1-adi@adirat.com>
Date:   Sun,  4 Mar 2018 05:20:18 +0200
From:   Ioan-Adrian Ratiu <adi@...rat.com>
To:     johnyoun@...opsys.com, gregkh@...uxfoundation.org
Cc:     linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH] usb: dwc2: detect power supplies to reduce spam

By statically hardcoding at compile time the number of supplies
("#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)"), the
driver assumed that every controller uses supplies and issued a
warning if none were detected via the device tree [1], even though the
vast majority of devices (with 1 exception from Samsung) don't need
nor use them.

So to return to normality and stop warning everyone unconditionally,
detect if there are any supplies and no-op just like the dummy
regulator which got loudly auto-asigned does.

This issue has been previously discussed based on an alternative fix
at [2] a year back but nothing came out of it then.

[1]
dwc2 3f980000.usb: 3f980000.usb supply vusb_d not found, using dummy regulator
dwc2 3f980000.usb: 3f980000.usb supply vusb_a not found, using dummy regulator

[2]
https://www.spinics.net/lists/linux-usb/msg153010.html

Signed-off-by: Ioan-Adrian Ratiu <adi@...rat.com>
---
 drivers/usb/dwc2/core.h     |  5 +++--
 drivers/usb/dwc2/platform.c | 46 +++++++++++++++++++++++++++++++--------------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index cd77af3b1565..c50b9fc4a162 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -128,7 +128,7 @@ static const char * const dwc2_hsotg_supply_names[] = {
 	"vusb_a",               /* analog USB supply, 1.1V */
 };
 
-#define DWC2_NUM_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)
+#define DWC2_MAX_SUPPLIES ARRAY_SIZE(dwc2_hsotg_supply_names)
 
 /*
  * EP0_MPS_LIMIT
@@ -921,7 +921,8 @@ struct dwc2_hsotg {
 	struct phy *phy;
 	struct usb_phy *uphy;
 	struct dwc2_hsotg_plat *plat;
-	struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
+	struct regulator_bulk_data supplies[DWC2_MAX_SUPPLIES];
+	u8 num_supplies;
 	u32 phyif;
 
 	spinlock_t lock;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 4703478f702f..3acf658af4e9 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -126,10 +126,12 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
 	int ret;
 
-	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-	if (ret)
-		return ret;
+	if (hsotg->num_supplies) {
+		ret = regulator_bulk_enable(hsotg->num_supplies,
+					    hsotg->supplies);
+		if (ret)
+			return ret;
+	}
 
 	if (hsotg->clk) {
 		ret = clk_prepare_enable(hsotg->clk);
@@ -186,8 +188,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 	if (hsotg->clk)
 		clk_disable_unprepare(hsotg->clk);
 
-	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-				     hsotg->supplies);
+	if (hsotg->num_supplies)
+		ret = regulator_bulk_disable(hsotg->num_supplies,
+					     hsotg->supplies);
 
 	return ret;
 }
@@ -210,6 +213,7 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 
 static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 {
+	struct regulator *reg;
 	int i, ret;
 
 	hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
@@ -290,16 +294,30 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 		dev_dbg(hsotg->dev, "cannot get otg clock\n");
 	}
 
-	/* Regulators */
-	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
-		hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
+	/* Regulators, vast majority of dwc2 devices don't use them at all */
+	for (i = 0; i < DWC2_MAX_SUPPLIES; i++) {
+		reg = regulator_get_optional(hsotg->dev,
+					     dwc2_hsotg_supply_names[i]);
+
+		/* All or nothing (bulk): regs either are or aren't present */
+		if (IS_ERR(reg)) {
+			while (--i >= 0) {
+				regulator_put(hsotg->supplies[i].consumer);
+				hsotg->supplies[i].consumer = NULL;
+				hsotg->supplies[i].supply = NULL;
+				--hsotg->num_supplies;
+			}
+			break;
+		}
 
-	ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
-				      hsotg->supplies);
-	if (ret) {
-		dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
-		return ret;
+		hsotg->supplies[i].consumer = reg;
+		hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
+		++hsotg->num_supplies;
 	}
+
+	WARN_ON(hsotg->num_supplies &&
+		hsotg->num_supplies != DWC2_MAX_SUPPLIES);
+
 	return 0;
 }
 
-- 
2.16.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ