diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 2dfa3242a7ab..490ac7548fa3 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -882,9 +882,12 @@ static void em28xx_v4l2_media_release(struct em28xx *dev) for (i = 0; i < MAX_EM28XX_INPUT; i++) { if (!INPUT(i)->type) - return; + break; media_device_unregister_entity(&dev->input_ent[i]); } + media_device_unregister_entity(&dev->v4l2->vdev.entity); + if (em28xx_vbi_supported(dev)) + media_device_unregister_entity(&dev->v4l2->vbi_dev.entity); #endif } @@ -2126,10 +2129,19 @@ static int em28xx_v4l2_open(struct file *filp) { struct video_device *vdev = video_devdata(filp); struct em28xx *dev = video_drvdata(filp); - struct em28xx_v4l2 *v4l2 = dev->v4l2; + struct em28xx_v4l2 *v4l2; enum v4l2_buf_type fh_type = 0; int ret; + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + + v4l2 = dev->v4l2; + if (!v4l2) { + mutex_unlock(&dev->lock); + return -EIO; + } + switch (vdev->vfl_type) { case VFL_TYPE_VIDEO: fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -2140,6 +2152,7 @@ static int em28xx_v4l2_open(struct file *filp) case VFL_TYPE_RADIO: break; default: + mutex_unlock(&dev->lock); return -EINVAL; } @@ -2147,8 +2160,6 @@ static int em28xx_v4l2_open(struct file *filp) video_device_node_name(vdev), v4l2_type_names[fh_type], v4l2->users); - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; ret = v4l2_fh_open(filp); if (ret) { diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 10a126e50c1c..72dd761d6ec8 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -441,6 +441,9 @@ static int v4l2_open(struct inode *inode, struct file *filp) } done: + if (ret == -EIO) + return ret; + if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP) dprintk("%s: open (%d)\n", video_device_node_name(vdev), ret);