[PATCH 1/2] usb: dwc3-generic: set "mode" based on caller of dwc3_generic_probe()

Siddharth Vadapalli s-vadapalli at ti.com
Thu Nov 28 18:20:11 CET 2024


Hello Roger,

On 28-11-2024 18:40, Roger Quadros wrote:
> 
> 
> On 26/11/2024 14:03, Siddharth Vadapalli wrote:
>> There are only two callers of "dwc3_generic_probe()", namely:
>> 1. dwc3_generic_peripheral_probe()
>> 2. dwc3_generic_host_probe()
>> Currently, the "mode" is set based on the device-tree node of the
>> platform device. Also, the DWC3 core doesn't support updating the "mode"
>> dynamically at runtime if it is set to "OTG", i.e. "OTG" is treated as a
>> separate mode in itself, rather than being treated as a mode which should
>> eventually lead to "host"/"peripheral".
>>
>> Given that the callers of "dwc3_generic_probe()" clarify the expected
>> "mode" of the USB Controller, use that "mode" instead of the one
>> specified in the device-tree. This shall allow the USB Controller to
>> function both as a "Host" and as a "Peripheral" when the "mode" is "otg"
>> in the device-tree, based on the caller of "dwc3_generic_probe()".
>>
>> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
>> ---
>>  drivers/usb/dwc3/dwc3-generic.c | 9 +++++----
> 
> TI AM62a is not even using this driver so how did you test this?
> Did I miss a DT patch?

USB DFU boot utilizes this driver when the "dr_mode" is set to "otg" in
the device-tree for AM62A. This driver is invoked both for the host and
device commands corresponding to USB. I came up with this patch while
trying to enable USB DFU boot on AM62A with "dr_mode" as "otg" in the
device-tree. Additionally, USB DFU boot works on AM62A with the change
made by this patch and it doesn't work without this change. I have
traced the call sequence to see that the driver is probed and have come
up with the change performed in this patch on the basis of this observation.

> 
>>  1 file changed, 5 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
>> index 2ab41cbae45..55e62b35c61 100644
>> --- a/drivers/usb/dwc3/dwc3-generic.c
>> +++ b/drivers/usb/dwc3/dwc3-generic.c
>> @@ -51,7 +51,8 @@ struct dwc3_generic_host_priv {
>>  };
>>  
>>  static int dwc3_generic_probe(struct udevice *dev,
>> -			      struct dwc3_generic_priv *priv)
>> +			      struct dwc3_generic_priv *priv,
>> +			      enum usb_dr_mode mode)
>>  {
>>  	int rc;
>>  	struct dwc3_generic_plat *plat = dev_get_plat(dev);
>> @@ -62,7 +63,7 @@ static int dwc3_generic_probe(struct udevice *dev,
>>  
>>  	dwc3->dev = dev;
>>  	dwc3->maximum_speed = plat->maximum_speed;
>> -	dwc3->dr_mode = plat->dr_mode;
>> +	dwc3->dr_mode = mode;
> 
> if platform supported mode was "host" only or "peripheral" only
> then you shouldn't we prevent from using the other role?

Yes, but that check doesn't exist prior to this patch either. Platform
could support only "host" mode as specified by "dr_mode", but if the
user runs a command for device mode it will lead to
"dwc3_generic_peripheral_probe" in this driver. On the other hand, if
the check does exist outside this driver, then it doesn't have to be
checked within "dwc3_generic_probe". There are only two callers of
"dwc3_generic_probe", both of which are in this driver, and both of
which unconditionally invoke "dwc3_generic_probe".

However, I agree that having a check here will help. I will update this
patch to add the check to confirm if there is a conflict with what the
platform supports, though this doesn't seem to be the case with the
existing code.
> 
> In u-boot shell, if user starts Host driver first and then starts peripheral driver
> how does it work?
> Did you test this case?

I didn't test the case where both are used. I validated that peripheral
mode works across various stages of boot with "otg" mode via USB DFU
boot. This isn't the case without this patch.

If we forget the reason that this patch is introduced and take a moment
to analyze the existing code prior to this patch, we see that:
1. Both dwc3_generic_peripheral_probe() and dwc3_generic_host_probe()
invoke dwc3_generic_probe().
2. dwc3_generic_probe() sets the role based on the role specified in the
device-tree and not what the caller wants the role to be.
This seems to be strange to me considering that dwc3_generic_probe()
simply proceeds to configure without comparing the role supported by the
platform with the role requested by the caller.

So even if we entirely forget the "otg" fix being attempted by this
patch, the same patch is fixing something else i.e. ensuring that
dwc3_generic_probe() does what the caller wants it to do by using the
role that the caller expects. Isn't it incorrect that the existing code
might end up with:
a) Caller being dwc3_generic_host_probe() with dr_mode being set to
"peripheral" within dwc3_generic_probe() based on the device-tree and
proceeding to configure the controller.
b) Caller being dwc3_generic_peripheral_probe() with dr_mode being set
to "host" within dwc3_generic_probe() based on the device-tree and
proceeding to configure the controller.
Shouldn't this inconsistency be fixed? This patch fixes that by setting
dr_mode to what the caller expects. However, based on your suggestion, I
agree that there should have been a check within dwc3_generic_probe() to
ensure that the platform supports what the caller is requesting. I will
update this patch by adding the check.

Please let me know what you think.

[...]

-- 
Regards,
Siddharth.


More information about the U-Boot mailing list