Re: [PATCH v8 13/14] usb: gadget: udc: adapt to OTG core
From: Roger Quadros <hidden>
Date: 2016-06-02 11:08:21
Also in:
linux-omap, lkml
On 01/06/16 10:38, Peter Chen wrote:
On Fri, May 13, 2016 at 01:03:27PM +0300, Roger Quadros wrote:quoted
@@ -530,6 +683,8 @@ void usb_del_gadget_udc(struct usb_gadget *gadget) } mutex_unlock(&udc_lock); + mutex_unlock(&udc_lock); +Here, you have one more mutex_unlock.
Will fix it. Thanks.
quoted
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); flush_work(&gadget->work); device_unregister(&udc->dev);@@ -539,6 +694,13 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc); /* ------------------------------------------------------------------------- */ +struct otg_gadget_ops otg_gadget_intf = { + .start = usb_gadget_start, + .stop = usb_gadget_stop, + .connect_control = usb_gadget_connect_control, +}; + +/* udc_lock must be held */ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver) { int ret;@@ -553,12 +715,20 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri ret = driver->bind(udc->gadget, driver); if (ret) goto err1; - ret = usb_gadget_udc_start(udc); - if (ret) { - driver->unbind(udc->gadget); - goto err1; + + /* If OTG, the otg core starts the UDC when needed */ + if (udc->gadget->otg_dev) { + mutex_unlock(&udc_lock); + usb_otg_register_gadget(udc->gadget, &otg_gadget_intf); + mutex_lock(&udc_lock); + } else { + ret = usb_gadget_udc_start(udc); + if (ret) { + driver->unbind(udc->gadget); + goto err1; + } + usb_udc_connect_control(udc); } - usb_udc_connect_control(udc); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0;@@ -660,9 +830,15 @@ static ssize_t usb_udc_softconn_store(struct device *dev, return -EOPNOTSUPP; } + /* In OTG mode we don't support softconnect, but b_bus_req */ + if (udc->gadget->otg_dev) { + dev_err(dev, "soft-connect not supported in OTG mode\n"); + return -EOPNOTSUPP; + } + if (sysfs_streq(buf, "connect")) { usb_gadget_udc_start(udc); - usb_gadget_connect(udc->gadget); + usb_udc_connect_control(udc); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget);diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 3ecfddd..79d654f 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h@@ -1162,6 +1162,10 @@ extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); extern char *usb_get_gadget_udc_name(void); +extern int usb_otg_add_gadget_udc(struct device *parent, + struct usb_gadget *gadget, + struct device *otg_dev); + /*-------------------------------------------------------------------------*/ /* utility to simplify dealing with string descriptors */-- 2.7.4