*/
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
fh->vdev = vdev;
INIT_LIST_HEAD(&fh->list);
set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
+ fh->prio = V4L2_PRIORITY_UNSET;
/*
* fh->events only needs to be initialized if the driver
{
unsigned long flags;
+ if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
+ v4l2_prio_open(fh->vdev->prio, &fh->prio);
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_add(&fh->list, &fh->vdev->fh_list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
}
EXPORT_SYMBOL_GPL(v4l2_fh_add);
+int v4l2_fh_open(struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+ struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+
+ filp->private_data = fh;
+ if (fh == NULL)
+ return -ENOMEM;
+ v4l2_fh_init(fh, vdev);
+ v4l2_fh_add(fh);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fh_open);
+
void v4l2_fh_del(struct v4l2_fh *fh)
{
unsigned long flags;
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_del_init(&fh->list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
+ if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
+ v4l2_prio_close(fh->vdev->prio, fh->prio);
}
EXPORT_SYMBOL_GPL(v4l2_fh_del);
v4l2_event_free(fh);
}
EXPORT_SYMBOL_GPL(v4l2_fh_exit);
+
+int v4l2_fh_release(struct file *filp)
+{
+ struct v4l2_fh *fh = filp->private_data;
+
+ if (fh) {
+ v4l2_fh_del(fh);
+ v4l2_fh_exit(fh);
+ kfree(fh);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fh_release);
+
+int v4l2_fh_is_singular(struct v4l2_fh *fh)
+{
+ unsigned long flags;
+ int is_singular;
+
+ if (fh == NULL || fh->vdev == NULL)
+ return 0;
+ spin_lock_irqsave(&fh->vdev->fh_lock, flags);
+ is_singular = list_is_singular(&fh->list);
+ spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
+ return is_singular;
+}
+EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);