diff options
author | Thinh Nguyen <Thinh.Nguyen@synopsys.com> | 2021-01-13 18:53:07 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-01-18 18:40:08 +0100 |
commit | ead4c124852e66b6aa033e34cf9c4f08d40aeffc (patch) | |
tree | 81931a1eb770559d9d826acbfc1f57af1cd0e971 | |
parent | db615c6264cffcd8f117c5628db1794afbd0f254 (diff) |
usb: gadget: Introduce udc_set_ssp_rate() for SSP
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@synopsys.com>
Link: https://lore.kernel.org/r/9b85357cdadc02e3f0d653fd05f89eb46af836e1.1610592135.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/gadget/udc/core.c | 16 | ||||
-rw-r--r-- | 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 *); |