Esempio n. 1
0
/* Called when the last user of the video device exits. */
static void v4l2_device_release(struct device *cd)
{
    struct video_device *vdev = to_video_device(cd);
    struct v4l2_device *v4l2_dev = vdev->v4l2_dev;

    mutex_lock(&videodev_lock);
    if (video_device[vdev->minor] != vdev) {
        mutex_unlock(&videodev_lock);
        /* should not happen */
        WARN_ON(1);
        return;
    }

    /* Free up this device for reuse */
    video_device[vdev->minor] = NULL;

    /* Delete the cdev on this minor as well */
    cdev_del(vdev->cdev);
    /* Just in case some driver tries to access this from
       the release() callback. */
    vdev->cdev = NULL;

    /* Mark device node number as free */
    devnode_clear(vdev);

    mutex_unlock(&videodev_lock);

    /* Release video_device and perform other
       cleanups as needed. */
    vdev->release(vdev);

    /* Decrease v4l2_device refcount */
    if (v4l2_dev)
        v4l2_device_put(v4l2_dev);
}
Esempio n. 2
0
/* Called when the last user of the video device exits. */
static void v4l2_device_release(struct device *cd)
{
	struct video_device *vdev = to_video_device(cd);
	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;

	mutex_lock(&videodev_lock);
	if (WARN_ON(video_device[vdev->minor] != vdev)) {
		/* should not happen */
		mutex_unlock(&videodev_lock);
		return;
	}

	/* Free up this device for reuse */
	video_device[vdev->minor] = NULL;

	/* Delete the cdev on this minor as well */
	cdev_del(vdev->cdev);
	/* Just in case some driver tries to access this from
	   the release() callback. */
	vdev->cdev = NULL;

	/* Mark device node number as free */
	devnode_clear(vdev);

	mutex_unlock(&videodev_lock);

#if defined(CONFIG_MEDIA_CONTROLLER)
	if (v4l2_dev->mdev) {
		/* Remove interfaces and interface links */
		media_devnode_remove(vdev->intf_devnode);
		if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN)
			media_device_unregister_entity(&vdev->entity);
	}
#endif

	/* 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.
	 *
	 * 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;

	/* Release video_device and perform other
	   cleanups as needed. */
	vdev->release(vdev);

	/* Decrease v4l2_device refcount */
	if (v4l2_dev)
		v4l2_device_put(v4l2_dev);
}
Esempio n. 3
0
/* Called when the last user of the video device exits. */
static void v4l2_device_release(struct device *cd)
{
	struct video_device *vdev = to_video_device(cd);
	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;

	mutex_lock(&videodev_lock);
	if (video_device[vdev->minor] != vdev) {
		mutex_unlock(&videodev_lock);
		/* should not happen */
		WARN_ON(1);
		return;
	}

	/* Free up this device for reuse */
	video_device[vdev->minor] = NULL;

	/* Delete the cdev on this minor as well */
	cdev_del(vdev->cdev);
	/* Just in case some driver tries to access this from
	   the release() callback. */
	vdev->cdev = NULL;

	/* Mark device node number as free */
	devnode_clear(vdev);

	mutex_unlock(&videodev_lock);

#if defined(CONFIG_MEDIA_CONTROLLER)
	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
	    vdev->vfl_type != VFL_TYPE_SUBDEV)
		media_device_unregister_entity(&vdev->entity);
#endif

	/* Release video_device and perform other
	   cleanups as needed. */
	vdev->release(vdev);

	/* Decrease v4l2_device refcount */
	if (v4l2_dev)
		v4l2_device_put(v4l2_dev);
}