diff mbox series

[U-Boot,4/8] usb: udc: Introduce ->udc_set_speed() method

Message ID 20191001115636.21052-5-vigneshr@ti.com
State Accepted
Commit 8d94e184ffdef48b40942c12d9e7b0290e60a1ef
Delegated to: Lukasz Majewski
Headers show
Series usb: Add support for Cadence USB controller driver | expand

Commit Message

Raghavendra, Vignesh Oct. 1, 2019, 11:56 a.m. UTC
From: Sherry Sun <sherry.sun@nxp.com>

This patch was copied from kernel commit: 67fdfda4a99ed.

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 because that will just fail.

So here introduce a new optional ->udc_set_speed() method which can be
implemented by interested UDC drivers to achieve this purpose.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/usb/gadget/udc/udc-core.c | 23 +++++++++++++++++++++++
 include/linux/usb/gadget.h        |  2 ++
 2 files changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 62b47781ddcc..8d1d90e3e39f 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -267,6 +267,27 @@  EXPORT_SYMBOL_GPL(usb_del_gadget_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) {
+		enum usb_device_speed s;
+
+		s = min(speed, udc->gadget->max_speed);
+		udc->gadget->ops->udc_set_speed(udc->gadget, s);
+	}
+}
+
 static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
 {
 	int ret;
@@ -276,6 +297,8 @@  static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
 
 	udc->driver = driver;
 
+	usb_gadget_udc_set_speed(udc, driver->speed);
+
 	ret = driver->bind(udc->gadget);
 	if (ret)
 		goto err1;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 7dba61bac131..66794d7894f6 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -470,6 +470,8 @@  struct usb_gadget_ops {
 	struct usb_ep *(*match_ep)(struct usb_gadget *,
 			struct usb_endpoint_descriptor *,
 			struct usb_ss_ep_comp_descriptor *);
+	void	(*udc_set_speed)(struct usb_gadget *gadget,
+				 enum usb_device_speed);
 };
 
 /**