[PATCH 2/2] dt-bindings: usb: snps,dwc3: Fix downstream port numbering
Neil Armstrong
neil.armstrong at linaro.org
Wed Oct 14 05:15:28 PDT 2026
On 10/14/26 12:14, Chen-Yu Tsai wrote:
> On Wed, Oct 14, 2026 at 6:44 PM Neil Armstrong
> <neil.armstrong at linaro.org> wrote:
>>
>> On 10/14/26 11:29, Chen-Yu Tsai wrote:
>>> On Wed, Oct 14, 2026 at 5:28 PM Neil Armstrong
>>> <neil.armstrong at linaro.org> wrote:
>>>>
>>>> On 10/14/26 10:20, Chen-Yu Tsai wrote:
>>>>> The DWC3 controller can operate in host mode. It does so with a XHCI
>>>>> compliant host controller. The XHCI has two downstream ports, one for
>>>>> HS and one for SS. USB downstream ports start from 1, not 0.
>>>>
>>>> Is there something in index 0 we will need to define at some point ?
>>>
>>> On the host side, no. Downstream ports start at 1.
>>>
>>> On the device mode side, I believe the numbers are completely made up.
>>>
>>>> Using 0 as base for numbering in DT isn't incompatible with the USB
>>>> spec using base 1 for numbering,
>>>
>>> But you end up with diverging numbering schemes, and it diverges
>>> from other USB controllers, particularly XHCI, which DWC3 embeds.
>>>
>>> And it also differs from the numbering currently used for directly
>>> connected onboard devices (like hubs), which use or expect the USB
>>> numbering scheme.
>>>
>>> Sure we can make DWC3 "special", drop inclusion of usb-hcd.yaml,
>>> and duplicate the section for onboard devices. On Linux, we can
>>> add some more code to xhci_find_raw_port_number() to make an
>>> exception for DWC3 controllers.
>>>
>>> Also, usb_of_get_connect_type() is already broken for DWC3 based
>>> controllers that only describe the HS connection but not the SS
>>> connection. usb_of_get_connect_type() currently doesn't call
>>> usb_hcd_find_raw_port_number() so both HS and SS get mapped to port 1,
>>> which wouldn't be in the DT since HS is currently port at 0. But even if
>>> it did, SS would get mapped to port 2 anyway.
>>>
>>>
>>> IMHO having consistent numbering across controller types would be
>>> better. This avoids making the USB core and hub code deal with more
>>> exceptions, and also easier to understand and write device trees.
>>
>> I was in the impression the port number not necessarily reflects
>> an actual physical numbering, and can be a logical number we would
>> then map in the kernel.
>>
>> I don't see any issue here having base 0 for the bindings and then
>> converting it to base 1 for the XHCI port numbering.
>>
>> Each controller (Host, Device, OTG) will have it's own numbering anyway,
>> so using the XHCI numbering only sounds a bad idea TBH.
>
> OK. So we keep the port numbering, which is different from the embedded
> device numbering, even for the same dual role controller? See below.
>
> I hope you see why I think it is confusing.
>
>>>
>>>>> Reconcile the downstream port numbering with the common USB host
>>>>> binding, renumbering the downstream port numbers from 0 and 1 to
>>>>> 1 and 2.
>>>>>
>>>>> This is non-backwards compatible, however it won't break current
>>>>> major implementations:
>>>>>
>>>>> - dwc3 "gadget mode" in Linux kernel only requires a connection to be
>>>>> present; it doesn't matter which port it is
>>>>> - dwc3 "host mode" OF graph connections aren't supported yet [1]
>>>>> - FreeBSD doesn't use the OF graph for anything
>>>>> - U-boot doesn't use the OF graph for USB
>>>>> - OpenBSD doesn't support dwc3, only the XHCI in dwc3, and doesn't use
>>>>> the OF graph for USB
>>>>> - coreboot doesn't use the OF graph for anything
>>>>> - Zephyr doesn't support dwc3
>>>>> - TF-A doesn't use the OF graph for anything
>>>>> - EDK2 doesn't support dwc3 and doesn't support OF graph
>>>>> - OP-TEE doesn't support dwc3 and doesn't support OF graph
>>>>>
>>>>> [1] WIP to tie OF graph port node to USB port device
>>>>>
>>>>> Fixes: a33113f73693 ("dt-bindings: usb: snps,dwc3: document HS & SS OF graph ports")
>>>>> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>>>>> ---
>>>>> It is unclear to me whether the HS/SS numbering is fixed for all dwc3
>>>>> variants. I checked Allwinner H616 and Rockchip RK3588 and they both
>>>>> have HS as port 1 and SS as port 2.
>>>>>
>>>>> This also doesn't cover a potential "multi-port" DWC3 implementation,
>>>>> which Qualcomm seems to have.
>>>>
>>>> It breaks the current Qualcomm numbering on numerous boards.
>>>
>>> Yes. It breaks _everyone_ using the current numbering in the sense that
>>> they are no longer valid, but should not affect actual usage.
>>
>> Older DT are supposed to be working on new kernels, you will break ABI
>> and will break usage if the port numbering is enforced to enabled embedded
>> hubs for example.
>
> On that front, embedded hubs already require you to use the USB numbering.
>
> If you write
>
> dwc3 {
> hub at 0 {
> compatible = "usb0123,abcd";
> reg = "0";
> };
> };
>
> It won't match anything. The current USB HCD binding doesn't prevent you
> from using port 0, but the kernel won't tie the USB device to it, even
> if it is a single port USB controller. As I mentioned, USB downstream
> ports start at 1, even for root hubs that only have 1 downstream port.
>
> The kernel also doesn't check if the compatible property is correct, but
> that is a separate issue. Maybe it should though, so people can see that
> their DT is incorrect, like if they swapped HS and SS ports for a USB 3.x
> hub.
TBH this USB device bindings for embedded hubs is wrong in many of ways.
So, is the downstream port index a numbering scheme from Linux ? Will each port
will have the same number on every OS implementation ? Do all OSes implement
the root as a the virtual root hub ? do they always use the same indexing ?
My comparison is PCI(e) where the controller port number is a Linux internal
numbering we don't use in DT, we only use the BDF of the downstream bus/endpoints
enumeration which is standardized.
So I think we should actually use the same scheme for usb, but having a subnode
per controller usb port with a hierarchy of nodes representing devices.
Keeping the current USB device bindings and trying to make it work is wrong here.
Neil
>
>
> ChenYu
>
>
>> Neil
>>
>>>
>>> This comment refers to "multiport" controllers from Qualcomm [1], which
>>> would have ports beyond 1 and 2.
>>>
>>> [1] https://lore.kernel.org/all/20240420044901.884098-8-quic_kriskura@quicinc.com/
>>>
>>>
>>>>> ---
>>>>> Documentation/devicetree/bindings/usb/snps,dwc3-common.yaml | 4 ++--
>>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3-common.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3-common.yaml
>>>>> index 6c0b8b653824..4b6304bd2ec1 100644
>>>>> --- a/Documentation/devicetree/bindings/usb/snps,dwc3-common.yaml
>>>>> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3-common.yaml
>>>>> @@ -410,11 +410,11 @@ properties:
>>>>> property is used.
>>>>>
>>>>> properties:
>>>>> - port at 0:
>>>>> + port at 1:
>>>>> $ref: /schemas/graph.yaml#/properties/port
>>>>> description: High Speed (HS) data bus.
>>>>>
>>>>> - port at 1:
>>>>> + port at 2:
>>>>> $ref: /schemas/graph.yaml#/properties/port
>>>>> description: Super Speed (SS) data bus.
>>>>>
>>>>
>>
More information about the linux-riscv
mailing list