* [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support
@ 2026-02-23 11:27 Marco Felsch
2026-02-23 11:27 ` [PATCH v5 1/4] usb: port: track the disabled state Marco Felsch
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel, Marco Felsch
Hi,
the whole purpose of this series is to make it possible to control the
USB VBUS regulators of an USB hub via host managed regulators.
Regards,
Marco
---
Changes in v5:
- Link to v4: https://lore.kernel.org/r/20250911-v6-16-topic-usb-onboard-dev-v4-0-1af288125d74@pengutronix.de
- rebase on top of v7.0-rc1
- dt-bindings: fix typo
- dt-bindings: move example into usb-device.yaml
Changes in v4:
- dt-bindings: change to vbus-supply and shift doc to usb-device.yaml
- onboard_dev: make use of new regulator API to parse child device
regulators.
- onboard_dev: drop hard coded downstream port number and make it more
dynamic
- onboard_dev: drop limiting support to SMSC hubs
- Link to v3: https://lore.kernel.org/r/20250821-v6-16-topic-usb-onboard-dev-v3-0-6d2b38a5d818@pengutronix.de
Changes in v3:
- fix dt-bindings issues
- Link to v2: https://lore.kernel.org/all/20250327172803.3404615-1-m.felsch@pengutronix.de/
Changes in v2:
- fix compile time errors in case the module builds
- Link to v1: https://lore.kernel.org/all/20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de/
---
Marco Felsch (4):
usb: port: track the disabled state
usb: hub: add infrastructure to pass onboard_dev port features
dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport
usb: misc: onboard_dev: add hub downstream port host vbus-supply handling
.../devicetree/bindings/usb/usb-device.yaml | 15 +++
drivers/usb/core/hub.c | 55 +++++++++-
drivers/usb/core/hub.h | 4 +
drivers/usb/core/port.c | 6 ++
drivers/usb/misc/onboard_usb_dev.c | 117 +++++++++++++++++++++
include/linux/usb.h | 3 +
6 files changed, 198 insertions(+), 2 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20250821-v6-16-topic-usb-onboard-dev-b8d4d1d8a086
Best regards,
--
Marco Felsch <m.felsch@pengutronix.de>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 1/4] usb: port: track the disabled state
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
@ 2026-02-23 11:27 ` Marco Felsch
2026-03-11 14:43 ` Greg Kroah-Hartman
2026-02-23 11:27 ` [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features Marco Felsch
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel, Marco Felsch
The disable state isn't tracked at the moment, instead the state is
directly passed to the hub driver. Change this behavior to only trigger
the hub if a state change happened. Exit early in case of no state
changes but don't return an error.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
drivers/usb/core/hub.h | 2 ++
drivers/usb/core/port.c | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 9ebc5ef54a325d63e01b0deb59a1853d2b13c8d5..297adf2c6078809ca582104f228e5222c464f999 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -97,6 +97,7 @@ struct usb_hub {
* @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted.
* @early_stop: whether port initialization will be stopped earlier.
* @ignore_event: whether events of the port are ignored.
+ * @disabled: whether the port is disabled
*/
struct usb_port {
struct usb_device *child;
@@ -118,6 +119,7 @@ struct usb_port {
unsigned int is_superspeed:1;
unsigned int usb3_lpm_u1_permit:1;
unsigned int usb3_lpm_u2_permit:1;
+ unsigned int disabled:1;
};
#define to_usb_port(_dev) \
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 44e38f922bc553adee64b35c536dfd4154a42d8a..86e9d6d0c0f505782569565fde8e4a46b06b8b4d 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -117,6 +117,10 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
if (rc)
return rc;
+ /* Early quit if no change was detected */
+ if (port_dev->disabled == disabled)
+ return count;
+
hub_get(hub);
rc = usb_autopm_get_interface(intf);
if (rc < 0)
@@ -148,6 +152,8 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
}
+ port_dev->disabled = disabled;
+
if (!rc)
rc = count;
--
2.47.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
2026-02-23 11:27 ` [PATCH v5 1/4] usb: port: track the disabled state Marco Felsch
@ 2026-02-23 11:27 ` Marco Felsch
2026-03-11 14:44 ` Greg Kroah-Hartman
2026-02-23 11:27 ` [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport Marco Felsch
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel, Marco Felsch
On board devices may require special handling for en-/disable port
features due to PCB design decisions e.g. enable/disable the VBUS power
on the port via a host controlled regulator or GPIO.
This commit adds the necessary infrastructure to prepare the common code
base for such use-cases.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
drivers/usb/core/hub.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--
drivers/usb/core/hub.h | 2 ++
include/linux/usb.h | 3 +++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24960ba9caa915f12a4f5582269808fdebd1ee11..9fdfd2f0aacc9b1994cd3761330968e052167c67 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -453,9 +453,19 @@ static int clear_hub_feature(struct usb_device *hdev, int feature)
*/
int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
{
- return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+ struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+ int ret;
+
+ ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
NULL, 0, 1000);
+ if (ret)
+ return ret;
+
+ if (hub->onboard_hub_clear_port_feature)
+ ret = hub->onboard_hub_clear_port_feature(hdev, feature, port1);
+
+ return ret;
}
/*
@@ -463,9 +473,19 @@ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
*/
static int set_port_feature(struct usb_device *hdev, int port1, int feature)
{
- return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+ struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+ int ret;
+
+ ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
NULL, 0, 1000);
+ if (ret)
+ return ret;
+
+ if (hub->onboard_hub_set_port_feature)
+ ret = hub->onboard_hub_set_port_feature(hdev, feature, port1);
+
+ return ret;
}
static char *to_led_name(int selector)
@@ -6545,6 +6565,37 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
}
}
+/**
+ * usb_hub_register_port_feature_hooks - Register port set/get feature hooks
+ * @hdev: USB device belonging to the usb hub
+ * @set_port_feature: set_feature hook which gets called by the hub core
+ * @clear_port_feature: clear_feature hook which gets called by the hub core
+ *
+ * Register set/get_port_feature hooks for a onboard_dev hub.
+ */
+void usb_hub_register_port_feature_hooks(struct usb_device *hdev,
+ int (*set_port_feature)(struct usb_device *, int, int),
+ int (*clear_port_feature)(struct usb_device *, int, int))
+{
+ struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+
+ if (WARN_ON_ONCE(is_root_hub(hdev) || !hub))
+ return;
+
+ if (set_port_feature)
+ hub->onboard_hub_set_port_feature = set_port_feature;
+ if (clear_port_feature)
+ hub->onboard_hub_clear_port_feature = clear_port_feature;
+
+ /*
+ * Keep it simple for now. Just check the power state and re-sync it
+ * after adding the hooks since the onboard-dev may do some additional
+ * logic e.g. controlling regulators.
+ */
+ hub_power_on(hub, false);
+}
+EXPORT_SYMBOL_GPL(usb_hub_register_port_feature_hooks);
+
#ifdef CONFIG_ACPI
/**
* usb_get_hub_port_acpi_handle - Get the usb port's acpi handle
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 297adf2c6078809ca582104f228e5222c464f999..31800b5922ba896dc7cac5f9e3ed1a77e7c5a801 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -76,6 +76,8 @@ struct usb_hub {
struct timer_list irq_urb_retry;
struct usb_port **ports;
struct list_head onboard_devs;
+ int (*onboard_hub_set_port_feature)(struct usb_device *udev, int feature, int port1);
+ int (*onboard_hub_clear_port_feature)(struct usb_device *udev, int feature, int port1);
};
/**
diff --git a/include/linux/usb.h b/include/linux/usb.h
index fbfcc70b07fbe5dbaa1ca1be55af127c62294cf7..5f68a066029ea0508fad461daf7ebe6f534778d2 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -946,6 +946,9 @@ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1,
struct usb_dev_state *owner);
int usb_hub_release_port(struct usb_device *hdev, unsigned port1,
struct usb_dev_state *owner);
+void usb_hub_register_port_feature_hooks(struct usb_device *hdev,
+ int (*set_port_feature)(struct usb_device *, int, int),
+ int (*clear_port_feature)(struct usb_device *, int, int));
/**
* usb_make_path - returns stable device path in the usb tree
--
2.47.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
2026-02-23 11:27 ` [PATCH v5 1/4] usb: port: track the disabled state Marco Felsch
2026-02-23 11:27 ` [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features Marco Felsch
@ 2026-02-23 11:27 ` Marco Felsch
2026-02-23 11:28 ` Marco Felsch
2026-03-06 0:01 ` Rob Herring (Arm)
2026-02-23 11:27 ` [PATCH v5 4/4] usb: misc: onboard_dev: add hub downstream port host vbus-supply handling Marco Felsch
2026-03-05 11:29 ` [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
4 siblings, 2 replies; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel, Marco Felsch
Some PCB designs don't use the dedicated USB hub port power control GPIO
to control the port VBUS supply. Instead host managed GPIOs are used to
control the VBUS supply.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
Documentation/devicetree/bindings/usb/usb-device.yaml | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/usb-device.yaml b/Documentation/devicetree/bindings/usb/usb-device.yaml
index 09fceb469f10525e9dcdb91435b142b0d21964b8..c9abdbea0e5348dc25f8f9484142089cf60bd514 100644
--- a/Documentation/devicetree/bindings/usb/usb-device.yaml
+++ b/Documentation/devicetree/bindings/usb/usb-device.yaml
@@ -53,6 +53,12 @@ properties:
"#size-cells":
const: 0
+ vbus-supply:
+ description: USB hub port VBUS supply.
+ The host managed regulator which controls the USB hub port VBUS. This
+ regulator is only required if the hub internal control signals aren't
+ used to control the VBUS regulators.
+
patternProperties:
"^interface@[0-9a-f]{1,2}(,[0-9a-f]{1,2})$":
type: object
@@ -85,6 +91,7 @@ additionalProperties: true
examples:
# hub connected to port 1
+ # device connected to hub port 2, vbus controlled by ext. regulator
# device connected to port 2
# device connected to port 3
# interface 0 of configuration 1
@@ -99,6 +106,14 @@ examples:
hub@1 {
compatible = "usb5e3,608";
reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ device@2 {
+ compatible = "usb123,4321";
+ reg = <2>;
+ vbus-supply = <®_5v0_vbus>;
+ };
};
device@2 {
--
2.47.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 4/4] usb: misc: onboard_dev: add hub downstream port host vbus-supply handling
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
` (2 preceding siblings ...)
2026-02-23 11:27 ` [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport Marco Felsch
@ 2026-02-23 11:27 ` Marco Felsch
2026-03-05 11:29 ` [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
4 siblings, 0 replies; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel, Marco Felsch
Some PCB designs don't use the dedicated USB hub port power GPIOs.
Instead they route the signals to the host. So the host is in charge to
power the VBUS supplies.
As first step the USB hub OF information is parsed and possible optional
vbus-supply regulators are added. This is done during the platform
driver probe() function.
Afterwards, during the usb driver probe() function and in case this is
an USB hub, the set/clear features hooks are registered via the new
usb_hub_register_port_feature_hooks().
After this registration all generic usb hub set/clear features calls are
passed to the onboard_dev driver too. This allows the driver to
en-/disable the regulators.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
drivers/usb/misc/onboard_usb_dev.c | 117 +++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
index ba37eb99efbaf5237d4998a0fdb1c65b56628f2b..41274e0fdfa3e4da53ebef58e585d0aeb9cbab08 100644
--- a/drivers/usb/misc/onboard_usb_dev.c
+++ b/drivers/usb/misc/onboard_usb_dev.c
@@ -54,6 +54,12 @@ struct usbdev_node {
struct list_head list;
};
+struct onboard_dev_port_regulator {
+ struct regulator *vbus_supply;
+ unsigned int port;
+ struct list_head list;
+};
+
struct onboard_dev {
struct regulator_bulk_data supplies[MAX_SUPPLIES];
struct device *dev;
@@ -65,6 +71,7 @@ struct onboard_dev {
struct list_head udev_list;
struct mutex lock;
struct clk *clk;
+ struct list_head ext_vbus_supplies;
};
static int onboard_dev_get_regulators(struct onboard_dev *onboard_dev)
@@ -226,6 +233,71 @@ static int onboard_dev_add_usbdev(struct onboard_dev *onboard_dev,
return err;
}
+static int onboard_dev_port_power(struct onboard_dev *onboard_dev, int port1,
+ bool enable)
+{
+ struct onboard_dev_port_regulator *regulator;
+ struct regulator *vbus_supply = NULL;
+
+ list_for_each_entry(regulator, &onboard_dev->ext_vbus_supplies, list) {
+ if (regulator->port == port1) {
+ vbus_supply = regulator->vbus_supply;
+ break;
+ }
+ }
+
+ /* External supplies are optional, return no error */
+ if (!vbus_supply)
+ return 0;
+
+ if (enable)
+ return regulator_enable(vbus_supply);
+
+ return regulator_disable(vbus_supply);
+}
+
+static int onboard_dev_add_ext_vbus_supplies(struct onboard_dev *onboard_dev)
+{
+ struct device *dev = onboard_dev->dev;
+
+ if (!onboard_dev->pdata->is_hub)
+ return 0;
+
+ INIT_LIST_HEAD(&onboard_dev->ext_vbus_supplies);
+
+ for_each_child_of_node_scoped(dev->of_node, child) {
+ struct onboard_dev_port_regulator *regulator;
+ struct regulator *port_supply;
+ u32 port;
+
+ port_supply = devm_of_regulator_get_optional(dev, child, "vbus");
+ if (IS_ERR(port_supply)) {
+ if (PTR_ERR(port_supply) == -ENODEV)
+ continue;
+ return PTR_ERR(port_supply);
+ }
+
+ /*
+ * The VBUS of this downstream port is controlled by a host
+ * managed regulator
+ */
+ if (of_property_read_u32(child, "reg", &port)) {
+ dev_err(dev, "Failed to parse USB device reg property\n");
+ return -EINVAL;
+ }
+
+ regulator = devm_kzalloc(dev, sizeof(*regulator), GFP_KERNEL);
+ if (!regulator)
+ return -ENOMEM;
+
+ regulator->vbus_supply = port_supply;
+ regulator->port = port;
+ list_add(®ulator->list, &onboard_dev->ext_vbus_supplies);
+ }
+
+ return 0;
+}
+
static void onboard_dev_remove_usbdev(struct onboard_dev *onboard_dev,
const struct usb_device *udev)
{
@@ -460,6 +532,10 @@ static int onboard_dev_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(onboard_dev->reset_gpio),
"failed to get reset GPIO\n");
+ err = onboard_dev_add_ext_vbus_supplies(onboard_dev);
+ if (err)
+ return dev_err_probe(dev, err, "failed to parse port vbus supplies\n");
+
mutex_init(&onboard_dev->lock);
INIT_LIST_HEAD(&onboard_dev->udev_list);
@@ -574,6 +650,44 @@ static struct platform_driver onboard_dev_driver = {
#define VENDOR_ID_VIA 0x2109
#define VENDOR_ID_XMOS 0x20B1
+static int onboard_dev_port_feature(struct usb_device *udev, bool set,
+ int feature, int port1)
+{
+ struct device *dev = &udev->dev;
+ struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
+
+ /*
+ * Check usb_hub_register_port_feature_hooks() if you want to extent
+ * the list of handled features. At the moment only power is synced
+ * after adding the hook.
+ */
+ switch (feature) {
+ case USB_PORT_FEAT_POWER:
+ return onboard_dev_port_power(onboard_dev, port1, set);
+ default:
+ return 0;
+ }
+}
+
+static int
+onboard_dev_set_port_feature(struct usb_device *udev, int feature, int port1)
+{
+ return onboard_dev_port_feature(udev, true, feature, port1);
+}
+
+static int
+onboard_dev_clear_port_feature(struct usb_device *udev, int feature, int port1)
+{
+ return onboard_dev_port_feature(udev, false, feature, port1);
+}
+
+static void
+onboard_dev_register_hub_hooks(struct usb_device *udev)
+{
+ usb_hub_register_port_feature_hooks(udev, onboard_dev_set_port_feature,
+ onboard_dev_clear_port_feature);
+}
+
/*
* Returns the onboard_dev platform device that is associated with the USB
* device passed as parameter.
@@ -633,6 +747,9 @@ static int onboard_dev_usbdev_probe(struct usb_device *udev)
dev_set_drvdata(dev, onboard_dev);
+ if (onboard_dev->pdata->is_hub)
+ onboard_dev_register_hub_hooks(udev);
+
err = onboard_dev_add_usbdev(onboard_dev, udev);
if (err)
return err;
--
2.47.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport
2026-02-23 11:27 ` [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport Marco Felsch
@ 2026-02-23 11:28 ` Marco Felsch
2026-03-06 0:01 ` Rob Herring (Arm)
1 sibling, 0 replies; 13+ messages in thread
From: Marco Felsch @ 2026-02-23 11:28 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown
Cc: linux-usb, linux-kernel, devicetree, kernel
Hi Rob,
I didn't add your r-b since I moved the DTS example here.
Regards,
Marco
On 26-02-23, Marco Felsch wrote:
> Some PCB designs don't use the dedicated USB hub port power control GPIO
> to control the port VBUS supply. Instead host managed GPIOs are used to
> control the VBUS supply.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> Documentation/devicetree/bindings/usb/usb-device.yaml | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/usb/usb-device.yaml b/Documentation/devicetree/bindings/usb/usb-device.yaml
> index 09fceb469f10525e9dcdb91435b142b0d21964b8..c9abdbea0e5348dc25f8f9484142089cf60bd514 100644
> --- a/Documentation/devicetree/bindings/usb/usb-device.yaml
> +++ b/Documentation/devicetree/bindings/usb/usb-device.yaml
> @@ -53,6 +53,12 @@ properties:
> "#size-cells":
> const: 0
>
> + vbus-supply:
> + description: USB hub port VBUS supply.
> + The host managed regulator which controls the USB hub port VBUS. This
> + regulator is only required if the hub internal control signals aren't
> + used to control the VBUS regulators.
> +
> patternProperties:
> "^interface@[0-9a-f]{1,2}(,[0-9a-f]{1,2})$":
> type: object
> @@ -85,6 +91,7 @@ additionalProperties: true
>
> examples:
> # hub connected to port 1
> + # device connected to hub port 2, vbus controlled by ext. regulator
> # device connected to port 2
> # device connected to port 3
> # interface 0 of configuration 1
> @@ -99,6 +106,14 @@ examples:
> hub@1 {
> compatible = "usb5e3,608";
> reg = <1>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + device@2 {
> + compatible = "usb123,4321";
> + reg = <2>;
> + vbus-supply = <®_5v0_vbus>;
> + };
> };
>
> device@2 {
>
> --
> 2.47.3
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
` (3 preceding siblings ...)
2026-02-23 11:27 ` [PATCH v5 4/4] usb: misc: onboard_dev: add hub downstream port host vbus-supply handling Marco Felsch
@ 2026-03-05 11:29 ` Marco Felsch
2026-03-17 3:44 ` Ze Huang
4 siblings, 1 reply; 13+ messages in thread
From: Marco Felsch @ 2026-03-05 11:29 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Fabio Estevam, Matthias Kaehlcke, Liam Girdwood,
Mark Brown, huang.ze
Cc: linux-usb, linux-kernel, devicetree, kernel
Hi,
+To: huang.ze@linux.dev
On 26-02-23, Marco Felsch wrote:
> Hi,
>
> the whole purpose of this series is to make it possible to control the
> USB VBUS regulators of an USB hub via host managed regulators.
>
> Regards,
> Marco
>
> ---
> Changes in v5:
> - Link to v4: https://lore.kernel.org/r/20250911-v6-16-topic-usb-onboard-dev-v4-0-1af288125d74@pengutronix.de
> - rebase on top of v7.0-rc1
> - dt-bindings: fix typo
> - dt-bindings: move example into usb-device.yaml
>
> Changes in v4:
> - dt-bindings: change to vbus-supply and shift doc to usb-device.yaml
> - onboard_dev: make use of new regulator API to parse child device
> regulators.
> - onboard_dev: drop hard coded downstream port number and make it more
> dynamic
> - onboard_dev: drop limiting support to SMSC hubs
> - Link to v3: https://lore.kernel.org/r/20250821-v6-16-topic-usb-onboard-dev-v3-0-6d2b38a5d818@pengutronix.de
>
> Changes in v3:
> - fix dt-bindings issues
> - Link to v2: https://lore.kernel.org/all/20250327172803.3404615-1-m.felsch@pengutronix.de/
>
> Changes in v2:
> - fix compile time errors in case the module builds
> - Link to v1: https://lore.kernel.org/all/20240807-b4-v6-10-topic-usb-onboard-dev-v1-0-f33ce21353c9@pengutronix.de/
>
> ---
> Marco Felsch (4):
> usb: port: track the disabled state
> usb: hub: add infrastructure to pass onboard_dev port features
> dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport
> usb: misc: onboard_dev: add hub downstream port host vbus-supply handling
>
> .../devicetree/bindings/usb/usb-device.yaml | 15 +++
> drivers/usb/core/hub.c | 55 +++++++++-
> drivers/usb/core/hub.h | 4 +
> drivers/usb/core/port.c | 6 ++
> drivers/usb/misc/onboard_usb_dev.c | 117 +++++++++++++++++++++
> include/linux/usb.h | 3 +
> 6 files changed, 198 insertions(+), 2 deletions(-)
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20250821-v6-16-topic-usb-onboard-dev-b8d4d1d8a086
>
> Best regards,
> --
> Marco Felsch <m.felsch@pengutronix.de>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport
2026-02-23 11:27 ` [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport Marco Felsch
2026-02-23 11:28 ` Marco Felsch
@ 2026-03-06 0:01 ` Rob Herring (Arm)
1 sibling, 0 replies; 13+ messages in thread
From: Rob Herring (Arm) @ 2026-03-06 0:01 UTC (permalink / raw)
To: Marco Felsch
Cc: Liam Girdwood, devicetree, linux-kernel, Mark Brown, kernel,
Greg Kroah-Hartman, Fabio Estevam, Krzysztof Kozlowski, linux-usb,
Conor Dooley, Matthias Kaehlcke
On Mon, 23 Feb 2026 12:27:36 +0100, Marco Felsch wrote:
> Some PCB designs don't use the dedicated USB hub port power control GPIO
> to control the port VBUS supply. Instead host managed GPIOs are used to
> control the VBUS supply.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> Documentation/devicetree/bindings/usb/usb-device.yaml | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 1/4] usb: port: track the disabled state
2026-02-23 11:27 ` [PATCH v5 1/4] usb: port: track the disabled state Marco Felsch
@ 2026-03-11 14:43 ` Greg Kroah-Hartman
2026-03-20 22:16 ` Marco Felsch
0 siblings, 1 reply; 13+ messages in thread
From: Greg Kroah-Hartman @ 2026-03-11 14:43 UTC (permalink / raw)
To: Marco Felsch
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Fabio Estevam,
Matthias Kaehlcke, Liam Girdwood, Mark Brown, linux-usb,
linux-kernel, devicetree, kernel
On Mon, Feb 23, 2026 at 12:27:34PM +0100, Marco Felsch wrote:
> The disable state isn't tracked at the moment, instead the state is
> directly passed to the hub driver. Change this behavior to only trigger
> the hub if a state change happened. Exit early in case of no state
> changes but don't return an error.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> drivers/usb/core/hub.h | 2 ++
> drivers/usb/core/port.c | 6 ++++++
> 2 files changed, 8 insertions(+)
>
> diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
> index 9ebc5ef54a325d63e01b0deb59a1853d2b13c8d5..297adf2c6078809ca582104f228e5222c464f999 100644
> --- a/drivers/usb/core/hub.h
> +++ b/drivers/usb/core/hub.h
> @@ -97,6 +97,7 @@ struct usb_hub {
> * @usb3_lpm_u2_permit: whether USB3 U2 LPM is permitted.
> * @early_stop: whether port initialization will be stopped earlier.
> * @ignore_event: whether events of the port are ignored.
> + * @disabled: whether the port is disabled
> */
> struct usb_port {
> struct usb_device *child;
> @@ -118,6 +119,7 @@ struct usb_port {
> unsigned int is_superspeed:1;
> unsigned int usb3_lpm_u1_permit:1;
> unsigned int usb3_lpm_u2_permit:1;
> + unsigned int disabled:1;
> };
>
> #define to_usb_port(_dev) \
> diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
> index 44e38f922bc553adee64b35c536dfd4154a42d8a..86e9d6d0c0f505782569565fde8e4a46b06b8b4d 100644
> --- a/drivers/usb/core/port.c
> +++ b/drivers/usb/core/port.c
> @@ -117,6 +117,10 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
> if (rc)
> return rc;
>
> + /* Early quit if no change was detected */
> + if (port_dev->disabled == disabled)
> + return count;
> +
This will change behavior where someone tells the port to be enabled
again, when it already is. Is that ok?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features
2026-02-23 11:27 ` [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features Marco Felsch
@ 2026-03-11 14:44 ` Greg Kroah-Hartman
2026-03-20 22:26 ` Marco Felsch
0 siblings, 1 reply; 13+ messages in thread
From: Greg Kroah-Hartman @ 2026-03-11 14:44 UTC (permalink / raw)
To: Marco Felsch
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Fabio Estevam,
Matthias Kaehlcke, Liam Girdwood, Mark Brown, linux-usb,
linux-kernel, devicetree, kernel
On Mon, Feb 23, 2026 at 12:27:35PM +0100, Marco Felsch wrote:
> On board devices may require special handling for en-/disable port
> features due to PCB design decisions e.g. enable/disable the VBUS power
> on the port via a host controlled regulator or GPIO.
>
> This commit adds the necessary infrastructure to prepare the common code
> base for such use-cases.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> drivers/usb/core/hub.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--
> drivers/usb/core/hub.h | 2 ++
> include/linux/usb.h | 3 +++
> 3 files changed, 58 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 24960ba9caa915f12a4f5582269808fdebd1ee11..9fdfd2f0aacc9b1994cd3761330968e052167c67 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -453,9 +453,19 @@ static int clear_hub_feature(struct usb_device *hdev, int feature)
> */
> int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
> {
> - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> + struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
> + int ret;
> +
> + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
> NULL, 0, 1000);
> + if (ret)
> + return ret;
> +
> + if (hub->onboard_hub_clear_port_feature)
> + ret = hub->onboard_hub_clear_port_feature(hdev, feature, port1);
> +
> + return ret;
> }
>
> /*
> @@ -463,9 +473,19 @@ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
> */
> static int set_port_feature(struct usb_device *hdev, int port1, int feature)
> {
> - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> + struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
> + int ret;
> +
> + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
> NULL, 0, 1000);
> + if (ret)
> + return ret;
> +
> + if (hub->onboard_hub_set_port_feature)
> + ret = hub->onboard_hub_set_port_feature(hdev, feature, port1);
> +
> + return ret;
> }
>
> static char *to_led_name(int selector)
> @@ -6545,6 +6565,37 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
> }
> }
>
> +/**
> + * usb_hub_register_port_feature_hooks - Register port set/get feature hooks
> + * @hdev: USB device belonging to the usb hub
> + * @set_port_feature: set_feature hook which gets called by the hub core
> + * @clear_port_feature: clear_feature hook which gets called by the hub core
> + *
> + * Register set/get_port_feature hooks for a onboard_dev hub.
> + */
> +void usb_hub_register_port_feature_hooks(struct usb_device *hdev,
> + int (*set_port_feature)(struct usb_device *, int, int),
> + int (*clear_port_feature)(struct usb_device *, int, int))
This should be a structure, don't force function pointers to be passed
in a function, that way lies madness :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support
2026-03-05 11:29 ` [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
@ 2026-03-17 3:44 ` Ze Huang
0 siblings, 0 replies; 13+ messages in thread
From: Ze Huang @ 2026-03-17 3:44 UTC (permalink / raw)
To: Marco Felsch, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Fabio Estevam,
Matthias Kaehlcke, Liam Girdwood, Mark Brown, huang.ze
Cc: linux-usb, linux-kernel, devicetree, kernel
On Thu Mar 5, 2026 at 7:29 PM CST, Marco Felsch wrote:
> Hi,
>
> +To: huang.ze@linux.dev
>
> On 26-02-23, Marco Felsch wrote:
>> Hi,
>>
>> the whole purpose of this series is to make it possible to control the
>> USB VBUS regulators of an USB hub via host managed regulators.
>>
>> Regards,
>> Marco
>>
I have tested this patch series on the SpacemiT K1 Milkv Jupiter board.
Thanks for driving this!
Tested-by: Ze Huang <huang.ze@linux.dev>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 1/4] usb: port: track the disabled state
2026-03-11 14:43 ` Greg Kroah-Hartman
@ 2026-03-20 22:16 ` Marco Felsch
0 siblings, 0 replies; 13+ messages in thread
From: Marco Felsch @ 2026-03-20 22:16 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Fabio Estevam,
Matthias Kaehlcke, Liam Girdwood, Mark Brown, linux-usb,
linux-kernel, devicetree, kernel
On 26-03-11, Greg Kroah-Hartman wrote:
> On Mon, Feb 23, 2026 at 12:27:34PM +0100, Marco Felsch wrote:
> > The disable state isn't tracked at the moment, instead the state is
> > directly passed to the hub driver. Change this behavior to only trigger
> > the hub if a state change happened. Exit early in case of no state
> > changes but don't return an error.
> >
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
...
> > #define to_usb_port(_dev) \
> > diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
> > index 44e38f922bc553adee64b35c536dfd4154a42d8a..86e9d6d0c0f505782569565fde8e4a46b06b8b4d 100644
> > --- a/drivers/usb/core/port.c
> > +++ b/drivers/usb/core/port.c
> > @@ -117,6 +117,10 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
> > if (rc)
> > return rc;
> >
> > + /* Early quit if no change was detected */
> > + if (port_dev->disabled == disabled)
> > + return count;
> > +
>
> This will change behavior where someone tells the port to be enabled
> again, when it already is. Is that ok?
That's the whole purpose of this patch. Can you please elaborate why
someone wants to enable or disbale a port more than once in a row?
Regards,
Marco
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features
2026-03-11 14:44 ` Greg Kroah-Hartman
@ 2026-03-20 22:26 ` Marco Felsch
0 siblings, 0 replies; 13+ messages in thread
From: Marco Felsch @ 2026-03-20 22:26 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Fabio Estevam,
Matthias Kaehlcke, Liam Girdwood, Mark Brown, linux-usb,
linux-kernel, devicetree, kernel
On 26-03-11, Greg Kroah-Hartman wrote:
> On Mon, Feb 23, 2026 at 12:27:35PM +0100, Marco Felsch wrote:
> > On board devices may require special handling for en-/disable port
> > features due to PCB design decisions e.g. enable/disable the VBUS power
> > on the port via a host controlled regulator or GPIO.
> >
> > This commit adds the necessary infrastructure to prepare the common code
> > base for such use-cases.
> >
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> > drivers/usb/core/hub.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--
> > drivers/usb/core/hub.h | 2 ++
> > include/linux/usb.h | 3 +++
> > 3 files changed, 58 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> > index 24960ba9caa915f12a4f5582269808fdebd1ee11..9fdfd2f0aacc9b1994cd3761330968e052167c67 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -453,9 +453,19 @@ static int clear_hub_feature(struct usb_device *hdev, int feature)
> > */
> > int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
> > {
> > - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> > + struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
> > + int ret;
> > +
> > + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> > USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
> > NULL, 0, 1000);
> > + if (ret)
> > + return ret;
> > +
> > + if (hub->onboard_hub_clear_port_feature)
> > + ret = hub->onboard_hub_clear_port_feature(hdev, feature, port1);
> > +
> > + return ret;
> > }
> >
> > /*
> > @@ -463,9 +473,19 @@ int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
> > */
> > static int set_port_feature(struct usb_device *hdev, int port1, int feature)
> > {
> > - return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> > + struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
> > + int ret;
> > +
> > + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
> > USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port1,
> > NULL, 0, 1000);
> > + if (ret)
> > + return ret;
> > +
> > + if (hub->onboard_hub_set_port_feature)
> > + ret = hub->onboard_hub_set_port_feature(hdev, feature, port1);
> > +
> > + return ret;
> > }
> >
> > static char *to_led_name(int selector)
> > @@ -6545,6 +6565,37 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
> > }
> > }
> >
> > +/**
> > + * usb_hub_register_port_feature_hooks - Register port set/get feature hooks
> > + * @hdev: USB device belonging to the usb hub
> > + * @set_port_feature: set_feature hook which gets called by the hub core
> > + * @clear_port_feature: clear_feature hook which gets called by the hub core
> > + *
> > + * Register set/get_port_feature hooks for a onboard_dev hub.
> > + */
> > +void usb_hub_register_port_feature_hooks(struct usb_device *hdev,
> > + int (*set_port_feature)(struct usb_device *, int, int),
> > + int (*clear_port_feature)(struct usb_device *, int, int))
>
> This should be a structure, don't force function pointers to be passed
> in a function, that way lies madness :)
Sure, do you have a proper struct name in mind already? How about:
- usb_hub_hooks, or
- usb_onboard_hub_hooks
Regards,
Marco
>
> thanks,
>
> greg k-h
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-03-20 22:26 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-23 11:27 [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
2026-02-23 11:27 ` [PATCH v5 1/4] usb: port: track the disabled state Marco Felsch
2026-03-11 14:43 ` Greg Kroah-Hartman
2026-03-20 22:16 ` Marco Felsch
2026-02-23 11:27 ` [PATCH v5 2/4] usb: hub: add infrastructure to pass onboard_dev port features Marco Felsch
2026-03-11 14:44 ` Greg Kroah-Hartman
2026-03-20 22:26 ` Marco Felsch
2026-02-23 11:27 ` [PATCH v5 3/4] dt-bindings: usb: usb-device: add usb hub port vbus-supply suppport Marco Felsch
2026-02-23 11:28 ` Marco Felsch
2026-03-06 0:01 ` Rob Herring (Arm)
2026-02-23 11:27 ` [PATCH v5 4/4] usb: misc: onboard_dev: add hub downstream port host vbus-supply handling Marco Felsch
2026-03-05 11:29 ` [PATCH v5 0/4] Add onboard-dev USB hub host managed vbus handling support Marco Felsch
2026-03-17 3:44 ` Ze Huang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox