From: Alan Stern Date: Fri, 10 Aug 2018 19:32:25 +0000 (-0400) Subject: USB: gadget core: Issue ->disconnect() callback from usb_gadget_disconnect() X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=0a55187a1ec8c03d0619e7ce41d10fdc39cff036;p=openwrt%2Fstaging%2Fblogic.git USB: gadget core: Issue ->disconnect() callback from usb_gadget_disconnect() The gadget documentation doesn't state clearly whether a gadget driver's ->disconnect() callback should be invoked when the D+ pullup is turned off. Some UDC drivers do this and some don't. This patch settles the issue by making the core function usb_gadget_disconnect() issue the callback, so that UDC drivers don't need to worry about it. A description of the new behavior is added to the function's kerneldoc. Also, the patch removes a few superseded callbacks from other core routines. Future patches will remove the ->disconnect() calls from the UDC drivers that make them, as they are now unnecessary. Until all those patches are merged gadget drivers may receive extra ->disconnect() callbacks, but this should be harmless. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi --- diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index af88b48c1cea..87d6b12779f2 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -690,6 +690,9 @@ EXPORT_SYMBOL_GPL(usb_gadget_connect); * as a disconnect (when a VBUS session is active). Not all systems * support software pullup controls. * + * Following a successful disconnect, invoke the ->disconnect() callback + * for the current gadget driver so that UDC drivers don't need to. + * * Returns zero on success, else negative errno. */ int usb_gadget_disconnect(struct usb_gadget *gadget) @@ -711,8 +714,10 @@ int usb_gadget_disconnect(struct usb_gadget *gadget) } ret = gadget->ops->pullup(gadget, 0); - if (!ret) + if (!ret) { gadget->connected = 0; + gadget->udc->driver->disconnect(gadget); + } out: trace_usb_gadget_disconnect(gadget, ret); @@ -1281,7 +1286,6 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); usb_gadget_disconnect(udc->gadget); - udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc); @@ -1471,7 +1475,6 @@ static ssize_t soft_connect_store(struct device *dev, usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); - udc->driver->disconnect(udc->gadget); usb_gadget_udc_stop(udc); } else { dev_err(dev, "unsupported command '%s'\n", buf);