grumpy DWC3+UCSI, usb-role-switch semantics

From: Konrad Dybcio

Date: Wed Mar 11 2026 - 08:40:18 EST


Hi,

The description for the usb-role-switch property (usb-drd.yaml) states:

Indicates that the device is capable of assigning the USB data role
(USB host or USB device) for a given USB connector, such as Type-C,
Type-B(micro). See connector/usb-connector.yaml.

That to me sounds like a description of the capability of the on-SoC
controller (i.e. should/could be set regardless of device specifics),
however in this configuration:

&usb {
dr_mode = "host";
usb-role-switch;
};

the role switch device is never registered on devices with a DWC3
controller, since that's handled in dwc3_drd_init(), which is only called
if dr_mode = "otg" (or absent since otg is the default).


This notably causes:

ucsi_init()
-> ucsi_register_port()
-> fwnode_usb_role_switch_get()

to loop in -EPROBE_DEFER, since the 'usb-role-switch' property is present
on the connected DWC3 core, but the rolesw device is never registered.

Now, it seems like different drivers do this differently, e.g. DWC2 seems
to always register a rolesw.


How should we tackle this?

FWIW I'd prefer (for maintainability reasons) to not have to set/remove
'usb-role-switch' separately for each board, depending on whether whatever is
at the other end of the USB cables is rolesw-capable (since again, the controller
itself is), but if we go that route, I'd request that we explicitly forbid the
combination of usb-role-switch && dr_mode=host/peripheral in bindings, so that
the computer yells at me if I overlook that

Konrad

P.S. this is the reason behind the issue we encountered at:
https://lore.kernel.org/linux-arm-msm/Z1gbyXk-SktGjL6-@xxxxxxxxxxxxxxxxxxxx/