summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2017-06-06 16:03:19 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2017-06-13 13:21:03 +0300
commit67fdfda4a99edea939a63bad1797d69dd8de00d6 (patch)
tree4f7ab3e9588a88340ddf3c95ef730f0aa76801c9 /drivers/usb/gadget
parent1b9f35adb0ffa143c7972a8459d6979c77d6c3c0 (diff)
downloadlinux-67fdfda4a99edea939a63bad1797d69dd8de00d6.tar.gz
linux-67fdfda4a99edea939a63bad1797d69dd8de00d6.tar.bz2
linux-67fdfda4a99edea939a63bad1797d69dd8de00d6.zip
usb: gadget: core: introduce ->udc_set_speed() method
Sometimes, the gadget driver we want to run has max_speed lower than what the UDC supports. In such situations, UDC might want to make sure we don't try to connect on speeds not supported by the gadget driver (e.g. super-speed capable dwc3 with high-speed capable g_midi) because that will just fail. In order to make sure this situation never happens, we introduce a new optional ->udc_set_speed() method which can be implemented by interested UDC drivers. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/udc/core.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 62d52fc0fcdc..eec388bccb25 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1056,6 +1056,23 @@ static inline void usb_gadget_udc_stop(struct usb_udc *udc)
}
/**
+ * usb_gadget_udc_set_speed - tells usb device controller speed supported by
+ * current driver
+ * @udc: The device we want to set maximum speed
+ * @speed: The maximum speed to allowed to run
+ *
+ * This call is issued by the UDC Class driver before calling
+ * usb_gadget_udc_start() in order to make sure that we don't try to
+ * connect on speeds the gadget driver doesn't support.
+ */
+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);
+}
+
+/**
* usb_udc_release - release the usb_udc struct
* @dev: the dev member within usb_udc
*
@@ -1288,6 +1305,9 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
udc->dev.driver = &driver->driver;
udc->gadget->dev.driver = &driver->driver;
+ if (driver->max_speed < udc->gadget->max_speed)
+ usb_gadget_udc_set_speed(udc, driver->max_speed);
+
ret = driver->bind(udc->gadget, driver);
if (ret)
goto err1;