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) {
        /* 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 = {
        if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
                printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
                        name_base, nr, video_device_node_name(vdev));
+
+       /* Increase v4l2_device refcount */
+       if (vdev->v4l2_dev)
+               v4l2_device_get(vdev->v4l2_dev);
+
 #if defined(CONFIG_MEDIA_CONTROLLER)
        /* Part 5: Register the entity. */
        if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
 
        spin_lock_init(&v4l2_dev->lock);
        mutex_init(&v4l2_dev->ioctl_lock);
        v4l2_prio_init(&v4l2_dev->prio);
+       kref_init(&v4l2_dev->ref);
        v4l2_dev->dev = dev;
        if (dev == NULL) {
                /* If dev == NULL, then name must be filled in by the caller */
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register);
 
+static void v4l2_device_release(struct kref *ref)
+{
+       struct v4l2_device *v4l2_dev =
+               container_of(ref, struct v4l2_device, ref);
+
+       if (v4l2_dev->release)
+               v4l2_dev->release(v4l2_dev);
+}
+
+int v4l2_device_put(struct v4l2_device *v4l2_dev)
+{
+       return kref_put(&v4l2_dev->ref, v4l2_device_release);
+}
+EXPORT_SYMBOL_GPL(v4l2_device_put);
+
 int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
                                                atomic_t *instance)
 {
 
        struct v4l2_prio_state prio;
        /* BKL replacement mutex. Temporary solution only. */
        struct mutex ioctl_lock;
+       /* Keep track of the references to this struct. */
+       struct kref ref;
+       /* Release function that is called when the ref count goes to 0. */
+       void (*release)(struct v4l2_device *v4l2_dev);
 };
 
+static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
+{
+       kref_get(&v4l2_dev->ref);
+}
+
+int v4l2_device_put(struct v4l2_device *v4l2_dev);
+
 /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
    dev may be NULL in rare cases (ISA devices). In that case you
    must fill in the v4l2_dev->name field before calling this function. */