* [PATCH v4] USB: bcma: add regulator support
@ 2026-09-28 20:22 Rosen Penev
0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-09-28 20:22 UTC (permalink / raw)
To: linux-usb; +Cc: Greg Kroah-Hartman, open list
bcma-hcd drives the USB power line by grabbing the undocumented
"vcc-gpio" from the controller node and poking it through gpiolib.
Besides relying on a non-standard binding, this cannot work on boards
such as the NETGEAR R7000 and R8000 where one chipcommon GPIO powers
both the USB2 and USB3 cores: the two controllers each request that
GPIO exclusively, so the second one fails with -EBUSY and its port
stays dead.
Add support for the standard regulator interface. VBUS is fetched with
devm_regulator_get() so existing boards keep working. Those with
"vcc-gpio" are unchanged. A dummy regulator warning is now emitted to
encourage migration to the new regulator setup.
Both mechanisms now start with VBUS off and enable it only after the
host controller has been set up, so a SuperSpeed device no longer falls
back to high-speed because EHCI started with VBUS already on. VBUS is
dropped again on suspend, shutdown and remove.
Assisted-by: LLM
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v4: split into own patch as it's not dependent on dts changes.
v3: don't drop GPIO.
v2: fixup dts and keep GPIO working.
drivers/usb/host/bcma-hcd.c | 38 ++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index 9a5704358996..ef4d6746e588 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/regulator/consumer.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
@@ -41,6 +42,7 @@ struct bcma_hcd_device {
struct platform_device *ehci_dev;
struct platform_device *ohci_dev;
struct gpio_desc *gpio_desc;
+ struct regulator *regulator;
};
/* Wait for bitmask in a register to get set or cleared.
@@ -280,14 +282,18 @@ static int bcma_hcd_usb20_ns_init(struct bcma_hcd_device *bcma_hcd)
return 0;
}
-static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+static int bcma_hci_platform_power(struct bcma_device *dev, bool on)
{
struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+ int err = 0;
- if (!usb_dev->gpio_desc)
- return;
+ if (usb_dev->gpio_desc)
+ err = gpiod_set_value(usb_dev->gpio_desc, on);
+ if (err)
+ return err;
- gpiod_set_value(usb_dev->gpio_desc, val);
+ return on ? regulator_enable(usb_dev->regulator) :
+ regulator_disable(usb_dev->regulator);
}
static const struct usb_ehci_pdata ehci_pdata = {
@@ -416,6 +422,11 @@ static int bcma_hcd_probe(struct bcma_device *core)
return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc),
"error obtaining VCC GPIO");
+ usb_dev->regulator = devm_regulator_get(&core->dev, "vbus");
+ if (IS_ERR(usb_dev->regulator))
+ return dev_err_probe(&core->dev, PTR_ERR(usb_dev->regulator),
+ "error obtaining VBUS regulator");
+
switch (core->id.id) {
case BCMA_CORE_USB20_HOST:
if (IS_ENABLED(CONFIG_ARM))
@@ -437,6 +448,10 @@ static int bcma_hcd_probe(struct bcma_device *core)
if (err)
return err;
+ err = regulator_enable(usb_dev->regulator);
+ if (err)
+ return dev_err_probe(&core->dev, err, "error enabling VBUS");
+
bcma_set_drvdata(core, usb_dev);
return 0;
}
@@ -452,12 +467,13 @@ static void bcma_hcd_remove(struct bcma_device *dev)
if (ehci_dev)
platform_device_unregister(ehci_dev);
+ bcma_hci_platform_power(dev, false);
bcma_core_disable(dev, 0);
}
static void bcma_hcd_shutdown(struct bcma_device *dev)
{
- bcma_hci_platform_power_gpio(dev, false);
+ bcma_hci_platform_power(dev, false);
bcma_core_disable(dev, 0);
}
@@ -465,7 +481,11 @@ static void bcma_hcd_shutdown(struct bcma_device *dev)
static int bcma_hcd_suspend(struct bcma_device *dev)
{
- bcma_hci_platform_power_gpio(dev, false);
+ int err;
+
+ err = bcma_hci_platform_power(dev, false);
+ if (err)
+ return err;
bcma_core_disable(dev, 0);
return 0;
@@ -473,7 +493,11 @@ static int bcma_hcd_suspend(struct bcma_device *dev)
static int bcma_hcd_resume(struct bcma_device *dev)
{
- bcma_hci_platform_power_gpio(dev, true);
+ int err;
+
+ err = bcma_hci_platform_power(dev, true);
+ if (err)
+ return err;
bcma_core_enable(dev, 0);
return 0;
--
2.55.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-28 20:22 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-28 20:22 [PATCH v4] USB: bcma: add regulator support Rosen Penev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®