Roger Quadros writes: > UDC core calls .udc_set_speed() with the speed parameter > containing the maximum speed supported by the gadget function > driver. This might very well be more or less than that > supported by the dwc3 controller driver. > > Select the lesser of the 2 speeds so both are operating > within limits. > > This fixes PHY Erratic errors and 2 second enumeration delay on > TI's AM437x platforms. > > Fixes: 7d8d0639565f ("usb: dwc3: gadget: implement ->udc_set_speed()") > Cc: # v4.13+ > Reported-by: Dylan Howey > Signed-off-by: Roger Quadros > --- > drivers/usb/dwc3/gadget.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index f064f15..9f27ec0 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -2008,6 +2008,8 @@ static void dwc3_gadget_set_speed(struct usb_gadget *g, > unsigned long flags; > u32 reg; > > + speed = min(g->max_speed, speed); should we do that in udc core itself? @@ -1080,8 +1080,12 @@ static inline void usb_gadget_udc_stop(struct usb_udc *udc) static inline void usb_gadget_udc_set_speed(struct usb_udc *udc, enum usb_device_speed speed) { - if (udc->gadget->ops->udc_set_speed) - udc->gadget->ops->udc_set_speed(udc->gadget, speed); + if (udc->gadget->ops->udc_set_speed) { + enum usb_device_speed s; + + s = min(speed, udc->gadget->max_speed); + udc->gadget->ops->udc_set_speed(udc->gadget, s); + } } /** then the fix applies for all UDCs. -- balbi