diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8b97f777ddf4..b7cb9977f778 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -595,16 +595,12 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; - if (gspca_dev->present) { - if (gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - gspca_input_destroy_urb(gspca_dev); - gspca_set_alt0(gspca_dev); - gspca_input_create_urb(gspca_dev); - } - - /* always call stop0 to free the subdriver's resources */ + if (gspca_dev->sd_desc->stopN) + gspca_dev->sd_desc->stopN(gspca_dev); + destroy_urbs(gspca_dev); + gspca_input_destroy_urb(gspca_dev); + gspca_set_alt0(gspca_dev); + gspca_input_create_urb(gspca_dev); if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); @@ -2369,7 +2365,6 @@ void gspca_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); gspca_dev->dev = NULL; gspca_dev->present = 0; - wake_up_interruptible(&gspca_dev->wq); destroy_urbs(gspca_dev); #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) @@ -2380,6 +2375,11 @@ void gspca_disconnect(struct usb_interface *intf) input_unregister_device(input_dev); } #endif + /* Free subdriver's streaming resources / stop sd workqueue(s) */ + if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming) + gspca_dev->sd_desc->stop0(gspca_dev); + gspca_dev->streaming = 0; + wake_up_interruptible(&gspca_dev->wq); v4l2_device_disconnect(&gspca_dev->v4l2_dev); video_unregister_device(&gspca_dev->vdev);