A SuperSpeed Plus device may operate at different speed and lane count (i.e. gen2x2, gen1x2, or gen2x1). Introduce gadget ops udc_set_ssp_rate() to set the desire corresponding usb_ssp_rate for SuperSpeed Plus capable devices. If the USB device supports different speeds at SuperSpeed Plus, set the device to operate with the maximum number of lanes and speed. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> --- Changes in v6: - Rebase on Greg's usb-testing branch - Rename udc_set_num_lanes_and_speed() to udc_set_ssp_rate() - Use usb_ssp_rate enum as a parameter instead of SSID - Update commit message Changes in v5: - Rebase on Felipe's testing/next branch - Changed Signed-off-by email to match From: email header Changes in v4: - Add identifier name for usb_gadget in gadget ops (*udc_set_num_lanes_and_speed) to avoid checkpatch warning Changes in v3: - None Changes in v2: - None drivers/usb/gadget/udc/core.c | 16 +++++++++++----- include/linux/usb/gadget.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 98cf9216f3cb..4173acdcd35b 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1133,12 +1133,18 @@ 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) { - enum usb_device_speed s; + struct usb_gadget *gadget = udc->gadget; + enum usb_device_speed s; - s = min(speed, udc->gadget->max_speed); - udc->gadget->ops->udc_set_speed(udc->gadget, s); - } + if (speed == USB_SPEED_UNKNOWN) + s = gadget->max_speed; + else + s = min(speed, gadget->max_speed); + + if (s == USB_SPEED_SUPER_PLUS && gadget->ops->udc_set_ssp_rate) + gadget->ops->udc_set_ssp_rate(gadget, gadget->max_ssp_rate); + else if (gadget->ops->udc_set_speed) + gadget->ops->udc_set_speed(gadget, s); } /** diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 02483c862444..ee04ef214ce8 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -323,6 +323,8 @@ struct usb_gadget_ops { struct usb_gadget_driver *); int (*udc_stop)(struct usb_gadget *); void (*udc_set_speed)(struct usb_gadget *, enum usb_device_speed); + void (*udc_set_ssp_rate)(struct usb_gadget *gadget, + enum usb_ssp_rate rate); struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); -- 2.28.0