diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 7a00af1f9624..237f9cc8bfba 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1047,12 +1047,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state); /* ------------------------------------------------------------------------- */ -static void usb_udc_connect_control(struct usb_udc *udc) +static int usb_udc_connect_control(struct usb_udc *udc) { + int ret; + if (udc->vbus) - usb_gadget_connect(udc->gadget); + ret = usb_gadget_connect(udc->gadget); else - usb_gadget_disconnect(udc->gadget); + ret = usb_gadget_disconnect(udc->gadget); + + return ret; } /** @@ -1507,15 +1511,26 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri if (ret) goto err1; ret = usb_gadget_udc_start(udc); - if (ret) { - driver->unbind(udc->gadget); - goto err1; - } + if (ret) + goto err_start; + usb_gadget_enable_async_callbacks(udc); - usb_udc_connect_control(udc); + ret = usb_udc_connect_control(udc); + if (ret) + goto err_connect_control; kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; + +err_connect_control: + usb_gadget_disable_async_callbacks(udc); + if (udc->gadget->irq) + synchronize_irq(udc->gadget->irq); + usb_gadget_udc_stop(udc); + +err_start: + driver->unbind(udc->gadget); + err1: if (ret != -EISNAM) dev_err(&udc->dev, "failed to start %s: %d\n",