--- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -401,7 +401,6 @@ static int usbvision_v4l2_close(struct f if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); - usbvision_release(usbvision); return 0; } @@ -409,6 +408,11 @@ static int usbvision_v4l2_close(struct f return v4l2_fh_release(file); } +static void usbvision_video_device_release(struct video_device *vdev) +{ + struct usb_usbvision *usbvision = video_get_drvdata(vdev); + usbvision_release(usbvision); +} /* * usbvision_ioctl() @@ -1181,7 +1185,7 @@ static struct video_device usbvision_vid .fops = &usbvision_fops, .ioctl_ops = &usbvision_ioctl_ops, .name = "usbvision-video", - .release = video_device_release_empty, + .release = usbvision_video_device_release, .tvnorms = USBVISION_NORMS, }; --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -206,7 +206,10 @@ static void v4l2_device_release(struct d } #endif - /* Do not call v4l2_device_put if there is no release callback set. + /* + * Decrease v4l2_device refcount + * + * Do not call v4l2_device_put if there is no release callback set. * Drivers that have no v4l2_device release callback might free the * v4l2_dev instance in the video_device release callback below, so we * must perform this check here. @@ -214,16 +217,12 @@ static void v4l2_device_release(struct d * TODO: In the long run all drivers that use v4l2_device should use the * v4l2_device release callback. This check will then be unnecessary. */ - if (v4l2_dev->release == NULL) - v4l2_dev = NULL; + if (v4l2_dev->release) + v4l2_device_put(v4l2_dev); /* Release video_device and perform other cleanups as needed. */ vdev->release(vdev); - - /* Decrease v4l2_device refcount */ - if (v4l2_dev) - v4l2_device_put(v4l2_dev); } static struct class video_class = {