Commit b1a873a3 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] v4l2: use new flag to enable core priority handling

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2f82441a
...@@ -577,6 +577,10 @@ You should also set these fields: ...@@ -577,6 +577,10 @@ You should also set these fields:
(cx8802). Since the v4l2_device cannot be associated with a particular (cx8802). Since the v4l2_device cannot be associated with a particular
PCI device it is setup without a parent device. But when the struct 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. 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 If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
in your v4l2_file_operations struct. in your v4l2_file_operations struct.
...@@ -775,7 +779,8 @@ struct v4l2_fh ...@@ -775,7 +779,8 @@ struct v4l2_fh
struct v4l2_fh provides a way to easily keep file handle specific data 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 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 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 whether a driver uses v4l2_fh as its file->private_data pointer by
......
...@@ -207,6 +207,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) ...@@ -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->fops = &cx18_v4l2_enc_fops;
s->video_dev->release = video_device_release; s->video_dev->release = video_device_release;
s->video_dev->tvnorms = V4L2_STD_ALL; s->video_dev->tvnorms = V4L2_STD_ALL;
set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
cx18_set_funcs(s->video_dev); cx18_set_funcs(s->video_dev);
return 0; return 0;
} }
......
...@@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ...@@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->vdev->fops = ivtv_stream_info[type].fops; s->vdev->fops = ivtv_stream_info[type].fops;
s->vdev->release = video_device_release; s->vdev->release = video_device_release;
s->vdev->tvnorms = V4L2_STD_ALL; s->vdev->tvnorms = V4L2_STD_ALL;
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
ivtv_set_funcs(s->vdev); ivtv_set_funcs(s->vdev);
return 0; return 0;
} }
......
...@@ -578,11 +578,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr, ...@@ -578,11 +578,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
vdev->parent = vdev->v4l2_dev->dev; vdev->parent = vdev->v4l2_dev->dev;
if (vdev->ctrl_handler == NULL) if (vdev->ctrl_handler == NULL)
vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler; vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
/* If the prio state pointer is NULL, and if the driver doesn't /* If the prio state pointer is NULL, then use the v4l2_device
handle priorities itself, then use the v4l2_device prio prio state. */
state. */ if (vdev->prio == NULL)
if (vdev->prio == NULL && vdev->ioctl_ops &&
vdev->ioctl_ops->vidioc_s_priority == NULL)
vdev->prio = &vdev->v4l2_dev->prio; vdev->prio = &vdev->v4l2_dev->prio;
} }
......
...@@ -35,7 +35,6 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) ...@@ -35,7 +35,6 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
INIT_LIST_HEAD(&fh->list); INIT_LIST_HEAD(&fh->list);
set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
fh->prio = V4L2_PRIORITY_UNSET; fh->prio = V4L2_PRIORITY_UNSET;
BUG_ON(vdev->prio == NULL);
/* /*
* fh->events only needs to be initialized if the driver * fh->events only needs to be initialized if the driver
...@@ -54,7 +53,8 @@ void v4l2_fh_add(struct v4l2_fh *fh) ...@@ -54,7 +53,8 @@ void v4l2_fh_add(struct v4l2_fh *fh)
{ {
unsigned long flags; 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); spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_add(&fh->list, &fh->vdev->fh_list); list_add(&fh->list, &fh->vdev->fh_list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
...@@ -82,7 +82,8 @@ void v4l2_fh_del(struct v4l2_fh *fh) ...@@ -82,7 +82,8 @@ void v4l2_fh_del(struct v4l2_fh *fh)
spin_lock_irqsave(&fh->vdev->fh_lock, flags); spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_del_init(&fh->list); list_del_init(&fh->list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 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); EXPORT_SYMBOL_GPL(v4l2_fh_del);
......
...@@ -541,6 +541,7 @@ static long __video_do_ioctl(struct file *file, ...@@ -541,6 +541,7 @@ static long __video_do_ioctl(struct file *file,
void *fh = file->private_data; void *fh = file->private_data;
struct v4l2_fh *vfh = NULL; struct v4l2_fh *vfh = NULL;
struct v4l2_format f_copy; struct v4l2_format f_copy;
int use_fh_prio = 0;
long ret = -EINVAL; long ret = -EINVAL;
if (ops == NULL) { if (ops == NULL) {
...@@ -555,10 +556,12 @@ static long __video_do_ioctl(struct file *file, ...@@ -555,10 +556,12 @@ static long __video_do_ioctl(struct file *file,
printk(KERN_CONT "\n"); 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; 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) { switch (cmd) {
case VIDIOC_S_CTRL: case VIDIOC_S_CTRL:
case VIDIOC_S_STD: case VIDIOC_S_STD:
...@@ -620,7 +623,7 @@ static long __video_do_ioctl(struct file *file, ...@@ -620,7 +623,7 @@ static long __video_do_ioctl(struct file *file,
if (ops->vidioc_g_priority) { if (ops->vidioc_g_priority) {
ret = ops->vidioc_g_priority(file, fh, p); ret = ops->vidioc_g_priority(file, fh, p);
} else if (vfh) { } else if (use_fh_prio) {
*p = v4l2_prio_max(&vfd->v4l2_dev->prio); *p = v4l2_prio_max(&vfd->v4l2_dev->prio);
ret = 0; ret = 0;
} }
...@@ -632,7 +635,7 @@ static long __video_do_ioctl(struct file *file, ...@@ -632,7 +635,7 @@ static long __video_do_ioctl(struct file *file,
{ {
enum v4l2_priority *p = arg; enum v4l2_priority *p = arg;
if (!ops->vidioc_s_priority && vfh == NULL) if (!ops->vidioc_s_priority && !use_fh_prio)
break; break;
dbgarg(cmd, "setting priority to %d\n", *p); dbgarg(cmd, "setting priority to %d\n", *p);
if (ops->vidioc_s_priority) if (ops->vidioc_s_priority)
...@@ -2187,7 +2190,7 @@ static long __video_do_ioctl(struct file *file, ...@@ -2187,7 +2190,7 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_default) if (!ops->vidioc_default)
break; break;
if (vfh && !ops->vidioc_s_priority) if (use_fh_prio)
valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0; valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0;
ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg); ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg);
break; break;
......
...@@ -1254,6 +1254,7 @@ static int __init vivi_create_instance(int inst) ...@@ -1254,6 +1254,7 @@ static int __init vivi_create_instance(int inst)
*vfd = vivi_template; *vfd = vivi_template;
vfd->debug = debug; vfd->debug = debug;
vfd->v4l2_dev = &dev->v4l2_dev; 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 * Provide a mutex to v4l2 core. It will be used to protect
......
...@@ -35,7 +35,10 @@ struct v4l2_ctrl_handler; ...@@ -35,7 +35,10 @@ struct v4l2_ctrl_handler;
Drivers can clear this flag if they want to block all future Drivers can clear this flag if they want to block all future
device access. It is cleared by video_unregister_device. */ device access. It is cleared by video_unregister_device. */
#define V4L2_FL_REGISTERED (0) #define V4L2_FL_REGISTERED (0)
/* file->private_data points to struct v4l2_fh */
#define V4L2_FL_USES_V4L2_FH (1) #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 */ /* Priority helper functions */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment