[PATCH] usb: cdns3: fix cdns3_bind() to avoid returning error and probe parent

Siddharth Vadapalli s-vadapalli at ti.com
Sun Mar 1 02:02:14 CET 2026


On 27/02/26 5:21 PM, Marek Vasut wrote:
> On 2/27/26 6:59 AM, Siddharth Vadapalli wrote:
>> While commit bfb530e06ca6 ("usb: cdns3: use VBUS Valid to determine role
>> for dr_mode OTG") enhances the driver, it causes boot failure for non-USB
>> boot mode when the 'dr_mode' is 'otg'. The reason for it is that the
>> cdns3_get_otg_mode() function reads the USB Controller registers to
>> determine the appropriate role. If the boot mode happens to be USB, then
>> the USB Controller will be powered ON and the registers are accessible.
>> For non-USB boot modes, the USB Controller is not necessarily powered ON
>> as a result of which the register accesses cause boot failure.
>>
>> Another issue is that the error code from cdns3_get_otg_mode() is 
>> returned
>> as-is by cdns3_bind(). The cdns3_bind() function already has a comment
>> near the 'fail' label stating that an error code should __not__ be 
>> returned
>> as it will cause the board to hang.
>>
>> Fix the aforementioned issues in the following manner:
>> 1. Probe the parent device before calling cdns3_get_otg_mode() to ensure
>>     that the USB Controller is powered ON and its registers are 
>> accessible.
>> 2. If cdns3_get_otg_mode() returns an error code, instead of returning
>>     the error code, jump to the 'fail' label and return '0'.
> 
> [...]
> 
>> 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(), 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.

Regards,
Siddharth.



More information about the U-Boot mailing list