diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 4888af0f8955..c32e7ef435d1 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -501,6 +501,7 @@ uvc_function_disable(struct usb_function *f) v4l2_event_queue(&uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_DISCONNECTED; + f->config->cdev->gadget->uvc_enabled = false; usb_ep_disable(uvc->video.ep); usb_ep_disable(uvc->control_ep); @@ -516,6 +517,8 @@ uvc_function_connect(struct uvc_device *uvc) struct usb_composite_dev *cdev = uvc->func.config->cdev; int ret; + cdev->gadget->uvc_enabled = true; + if ((ret = usb_function_activate(&uvc->func)) < 0) INFO(cdev, "UVC connect failed with %d\n", ret); } diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 43f37725ae41..8dbd970762a1 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -787,7 +787,7 @@ int usb_gadget_deactivate(struct usb_gadget *gadget) if (!gadget || gadget->deactivated) goto out; - if (gadget->connected) { + if (gadget->connected && !gadget->uvc_enabled) { ret = usb_gadget_disconnect(gadget); if (ret) goto out; diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 1cb5ca45a7c2..fee44ebf5591 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -448,6 +448,7 @@ struct usb_gadget_ops { * indicates that it supports LPM as per the LPM ECN & errata. * @remote_wakeup: Indicates if the host has enabled the remote_wakeup * feature. + * @uvc_enabled: True if uvc function is enabled. * * Gadgets have a mostly-portable "gadget driver" implementing device * functions, handling all usb configurations and interfaces. Gadget @@ -503,6 +504,7 @@ struct usb_gadget { unsigned connected:1; unsigned lpm_capable:1; unsigned remote_wakeup:1; + unsigned uvc_enabled:1; ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2);