@@ -1117,12 +1117,26 @@ 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 the UDC supports super-speed-plus and different sublink speeds,
+ * then set the gadget to the max possible sublink speed for
+ * super-speed-plus symmetric lanes.
+ */
+ if (s == USB_SPEED_SUPER_PLUS &&
+ gadget->ops->udc_set_num_lanes_and_speed)
+ gadget->ops->udc_set_num_lanes_and_speed(gadget,
+ gadget->max_num_lanes,
+ gadget->max_speed_ssid);
+ else if (gadget->ops->udc_set_speed)
+ gadget->ops->udc_set_speed(gadget, s);
}
/**
@@ -323,6 +323,9 @@ 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_num_lanes_and_speed)(struct usb_gadget *gadget,
+ unsigned int num_lanes,
+ unsigned int ssid);
struct usb_ep *(*match_ep)(struct usb_gadget *,
struct usb_endpoint_descriptor *,
struct usb_ss_ep_comp_descriptor *);
A super-speed-plus device may operate at different sublink speeds (e.g. gen2x2, gen1x2, or gen2x1). If the USB device supports different sublink speeds at super-speed-plus, set the device to operate at the maximum number of lanes and sublink speed possible. Introduce gadget ops udc_set_num_lanes_and_speed to set the lane count and sublink speed for super-speed-plus capable devices. Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> --- 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 | 24 +++++++++++++++++++----- include/linux/usb/gadget.h | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-)