Skip to content

Commit

Permalink
[media] v4l2: use new flag to enable core priority handling
Browse files Browse the repository at this point in the history
Rather than guess which driver supports core priority handling, require drivers
that do to explicitly set the V4L2_FL_USE_FH_PRIO flag in video_device.

Updated the core prio handling accordingly and set the flag in the three
drivers that do.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Mar 22, 2011
1 parent 2f82441 commit b1a873a
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 14 deletions.
7 changes: 6 additions & 1 deletion Documentation/video4linux/v4l2-framework.txt
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,10 @@ You should also set these fields:
(cx8802). Since the v4l2_device cannot be associated with a particular
PCI device it is setup without a parent device. But when the struct
video_device is setup you do know which parent PCI device to use.
- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
v4l2_fh. Eventually this flag will disappear once all drivers use the core
priority handling. But for now it has to be set explicitly.

If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
in your v4l2_file_operations struct.
Expand Down Expand Up @@ -775,7 +779,8 @@ struct v4l2_fh

struct v4l2_fh provides a way to easily keep file handle specific data
that is used by the V4L2 framework. New drivers must use struct v4l2_fh
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY).
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
if the video_device flag V4L2_FL_USE_FH_PRIO is also set.

The users of v4l2_fh (in the V4L2 framework, not the driver) know
whether a driver uses v4l2_fh as its file->private_data pointer by
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/cx18/cx18-streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
s->video_dev->fops = &cx18_v4l2_enc_fops;
s->video_dev->release = video_device_release;
s->video_dev->tvnorms = V4L2_STD_ALL;
set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
cx18_set_funcs(s->video_dev);
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/ivtv/ivtv-streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->vdev->fops = ivtv_stream_info[type].fops;
s->vdev->release = video_device_release;
s->vdev->tvnorms = V4L2_STD_ALL;
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
ivtv_set_funcs(s->vdev);
return 0;
}
Expand Down
8 changes: 3 additions & 5 deletions drivers/media/video/v4l2-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
vdev->parent = vdev->v4l2_dev->dev;
if (vdev->ctrl_handler == NULL)
vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
/* If the prio state pointer is NULL, and if the driver doesn't
handle priorities itself, then use the v4l2_device prio
state. */
if (vdev->prio == NULL && vdev->ioctl_ops &&
vdev->ioctl_ops->vidioc_s_priority == NULL)
/* If the prio state pointer is NULL, then use the v4l2_device
prio state. */
if (vdev->prio == NULL)
vdev->prio = &vdev->v4l2_dev->prio;
}

Expand Down
7 changes: 4 additions & 3 deletions drivers/media/video/v4l2-fh.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
INIT_LIST_HEAD(&fh->list);
set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
fh->prio = V4L2_PRIORITY_UNSET;
BUG_ON(vdev->prio == NULL);

/*
* fh->events only needs to be initialized if the driver
Expand All @@ -54,7 +53,8 @@ void v4l2_fh_add(struct v4l2_fh *fh)
{
unsigned long flags;

v4l2_prio_open(fh->vdev->prio, &fh->prio);
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);
Expand Down Expand Up @@ -82,7 +82,8 @@ void v4l2_fh_del(struct v4l2_fh *fh)
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_del_init(&fh->list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
v4l2_prio_close(fh->vdev->prio, fh->prio);
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);

Expand Down
13 changes: 8 additions & 5 deletions drivers/media/video/v4l2-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ static long __video_do_ioctl(struct file *file,
void *fh = file->private_data;
struct v4l2_fh *vfh = NULL;
struct v4l2_format f_copy;
int use_fh_prio = 0;
long ret = -EINVAL;

if (ops == NULL) {
Expand All @@ -555,10 +556,12 @@ static long __video_do_ioctl(struct file *file,
printk(KERN_CONT "\n");
}

if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
vfh = file->private_data;
use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
}

if (vfh && !ops->vidioc_s_priority) {
if (use_fh_prio) {
switch (cmd) {
case VIDIOC_S_CTRL:
case VIDIOC_S_STD:
Expand Down Expand Up @@ -620,7 +623,7 @@ static long __video_do_ioctl(struct file *file,

if (ops->vidioc_g_priority) {
ret = ops->vidioc_g_priority(file, fh, p);
} else if (vfh) {
} else if (use_fh_prio) {
*p = v4l2_prio_max(&vfd->v4l2_dev->prio);
ret = 0;
}
Expand All @@ -632,7 +635,7 @@ static long __video_do_ioctl(struct file *file,
{
enum v4l2_priority *p = arg;

if (!ops->vidioc_s_priority && vfh == NULL)
if (!ops->vidioc_s_priority && !use_fh_prio)
break;
dbgarg(cmd, "setting priority to %d\n", *p);
if (ops->vidioc_s_priority)
Expand Down Expand Up @@ -2187,7 +2190,7 @@ static long __video_do_ioctl(struct file *file,

if (!ops->vidioc_default)
break;
if (vfh && !ops->vidioc_s_priority)
if (use_fh_prio)
valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0;
ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg);
break;
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/vivi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,7 @@ static int __init vivi_create_instance(int inst)
*vfd = vivi_template;
vfd->debug = debug;
vfd->v4l2_dev = &dev->v4l2_dev;
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);

/*
* Provide a mutex to v4l2 core. It will be used to protect
Expand Down
3 changes: 3 additions & 0 deletions include/media/v4l2-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ struct v4l2_ctrl_handler;
Drivers can clear this flag if they want to block all future
device access. It is cleared by video_unregister_device. */
#define V4L2_FL_REGISTERED (0)
/* file->private_data points to struct v4l2_fh */
#define V4L2_FL_USES_V4L2_FH (1)
/* Use the prio field of v4l2_fh for core priority checking */
#define V4L2_FL_USE_FH_PRIO (2)

/* Priority helper functions */

Expand Down

0 comments on commit b1a873a

Please sign in to comment.