[PATCH] usb: cdns3: fix cdns3_bind() to avoid returning error and probe parent
Siddharth Vadapalli
s-vadapalli at ti.com
Sun Mar 1 06:25:34 CET 2026
On 01/03/26 06:50, Marek Vasut wrote:
> On 3/1/26 2:02 AM, Siddharth Vadapalli wrote:
>
>>>> diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
>>>> index 10bc4cabed4..a775567b3bc 100644
>>>> --- a/drivers/usb/cdns3/core.c
>>>> +++ b/drivers/usb/cdns3/core.c
>>>> @@ -461,9 +461,18 @@ int cdns3_bind(struct udevice *parent)
>>>> /* Use VBUS Valid to determine role */
>>>> if (dr_mode == USB_DR_MODE_OTG) {
>>>> + /*
>>>> + * Since we perform register accesses in cdns3_get_otg_mode(),
>>>> + * we need to ensure that the parent has been probed and that
>>>> + * the USB Controller is powered ON.
>>>> + */
>>>> + ret = device_probe(parent);
>>>> + if (ret)
>>>> + goto fail;
>>>> +
>>>> ret = cdns3_get_otg_mode(parent, &dr_mode);
>>>> if (ret < 0)
>>>> - return ret;
>>>> + goto fail;
>>>> }
>>> Can you instead move this logic into driver .probe() ? Then you wouldn't
>>> need the device_probe() hackage.
>>>
>>
>> There are two users of cdns3_bind() which have registered their
>> own .bind() callback as cdns3_bind():
>> 1. cdns3-starfive.c driver
>> 2. cdns3-ti.c driver
>> Since .bind() is called before .probe()
>
> .bind callback is meant to BIND the driver instance (to a DT node), it is
> not meant to initialize the hardware. .probe callback is meant to
I agree. But that's exactly where the issue lies. When 'dr_mode' is set to
OTG, cdns3_bind() is unable to determine if the driver to bind to the DT
node is "cdns-usb3-host" or "cdns-usb3-peripheral".
Since [0], we attempt to identify if OTG should imply 'peripheral' or
'host'. But to do that, [0] needs to read the VBUS Valid field of the OTG
Status register. And register access requires the USB Controller to be
powered ON.
[0]: bfb530e06ca6 ("usb: cdns3: use VBUS Valid to determine role for
dr_mode OTG")
> initialize the hardware. This is fundamental part of the U-Boot DM lazy
> initialization scheme. If something does initialize hardware in .bind, then
> it is very likely wrong.
>
>> , and, since cdns3_bind() is also the .bind() callback of the above
>> drivers, device_probe() has to be added here itself. Moreover, it is only
>> due to the register accesses being performed by the recently introduced
>> cdns3_get_otg_mode() function that we need the USB Controller to be
>> powered ON at this stage.
> So, can we fix this so the HW initialization won't be happening in bind,
> but instead in .probe ?
That isn't possible when 'dr_mode' is OTG because the .probe() callback
itself is determined by cdns3_bind(). Whether it is "cdns-usb3-host"
driver's .probe() callback or "cdns-usb3-peripheral" driver's .probe()
callback depends on cdns3_bind() being able to decide which driver to bind
to the DT node. And for cdns3_bind() to decide the driver when 'dr_mode' is
OTG, we need to read the VBUS Valid field. So cdns3_bind() needs to ensure
that the USB Controller is powered ON (device_probe() of parent).
More information about the U-Boot
mailing list