diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-01 11:04:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 14:00:03 -0400 |
commit | 537fa492e084af58d16899f8d0f3f3516a4fbe7c (patch) | |
tree | 73486cf2548394a597c230818c7cb40a2eba7b2c /drivers/media/common/saa7146_fops.c | |
parent | 9bb601935b8495cd4ef8aea389df77233d6be5dd (diff) |
[media] saa7146: support control events and priority handling
Use v4l2_fh which gives you control events and priority handling for free.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common/saa7146_fops.c')
-rw-r--r-- | drivers/media/common/saa7146_fops.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 66f6e79dd97b..dfb396568ab6 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -198,7 +198,6 @@ static int fops_open(struct file *file) | |||
198 | struct saa7146_dev *dev = video_drvdata(file); | 198 | struct saa7146_dev *dev = video_drvdata(file); |
199 | struct saa7146_fh *fh = NULL; | 199 | struct saa7146_fh *fh = NULL; |
200 | int result = 0; | 200 | int result = 0; |
201 | |||
202 | enum v4l2_buf_type type; | 201 | enum v4l2_buf_type type; |
203 | 202 | ||
204 | DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); | 203 | DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); |
@@ -227,7 +226,9 @@ static int fops_open(struct file *file) | |||
227 | goto out; | 226 | goto out; |
228 | } | 227 | } |
229 | 228 | ||
230 | file->private_data = fh; | 229 | v4l2_fh_init(&fh->fh, vdev); |
230 | |||
231 | file->private_data = &fh->fh; | ||
231 | fh->dev = dev; | 232 | fh->dev = dev; |
232 | 233 | ||
233 | if (vdev->vfl_type == VFL_TYPE_VBI) { | 234 | if (vdev->vfl_type == VFL_TYPE_VBI) { |
@@ -251,6 +252,7 @@ static int fops_open(struct file *file) | |||
251 | } | 252 | } |
252 | 253 | ||
253 | result = 0; | 254 | result = 0; |
255 | v4l2_fh_add(&fh->fh); | ||
254 | out: | 256 | out: |
255 | if (fh && result != 0) { | 257 | if (fh && result != 0) { |
256 | kfree(fh); | 258 | kfree(fh); |
@@ -280,6 +282,8 @@ static int fops_release(struct file *file) | |||
280 | saa7146_video_uops.release(dev,file); | 282 | saa7146_video_uops.release(dev,file); |
281 | } | 283 | } |
282 | 284 | ||
285 | v4l2_fh_del(&fh->fh); | ||
286 | v4l2_fh_exit(&fh->fh); | ||
283 | module_put(dev->ext->module); | 287 | module_put(dev->ext->module); |
284 | file->private_data = NULL; | 288 | file->private_data = NULL; |
285 | kfree(fh); | 289 | kfree(fh); |
@@ -322,12 +326,13 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) | |||
322 | struct saa7146_fh *fh = file->private_data; | 326 | struct saa7146_fh *fh = file->private_data; |
323 | struct videobuf_buffer *buf = NULL; | 327 | struct videobuf_buffer *buf = NULL; |
324 | struct videobuf_queue *q; | 328 | struct videobuf_queue *q; |
329 | unsigned int res = v4l2_ctrl_poll(file, wait); | ||
325 | 330 | ||
326 | DEB_EE("file:%p, poll:%p\n", file, wait); | 331 | DEB_EE("file:%p, poll:%p\n", file, wait); |
327 | 332 | ||
328 | if (vdev->vfl_type == VFL_TYPE_VBI) { | 333 | if (vdev->vfl_type == VFL_TYPE_VBI) { |
329 | if( 0 == fh->vbi_q.streaming ) | 334 | if( 0 == fh->vbi_q.streaming ) |
330 | return videobuf_poll_stream(file, &fh->vbi_q, wait); | 335 | return res | videobuf_poll_stream(file, &fh->vbi_q, wait); |
331 | q = &fh->vbi_q; | 336 | q = &fh->vbi_q; |
332 | } else { | 337 | } else { |
333 | DEB_D("using video queue\n"); | 338 | DEB_D("using video queue\n"); |
@@ -339,17 +344,17 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) | |||
339 | 344 | ||
340 | if (!buf) { | 345 | if (!buf) { |
341 | DEB_D("buf == NULL!\n"); | 346 | DEB_D("buf == NULL!\n"); |
342 | return POLLERR; | 347 | return res | POLLERR; |
343 | } | 348 | } |
344 | 349 | ||
345 | poll_wait(file, &buf->done, wait); | 350 | poll_wait(file, &buf->done, wait); |
346 | if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { | 351 | if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { |
347 | DEB_D("poll succeeded!\n"); | 352 | DEB_D("poll succeeded!\n"); |
348 | return POLLIN|POLLRDNORM; | 353 | return res | POLLIN | POLLRDNORM; |
349 | } | 354 | } |
350 | 355 | ||
351 | DEB_D("nothing to poll for, buf->state:%d\n", buf->state); | 356 | DEB_D("nothing to poll for, buf->state:%d\n", buf->state); |
352 | return 0; | 357 | return res; |
353 | } | 358 | } |
354 | 359 | ||
355 | static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | 360 | static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) |
@@ -583,6 +588,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
583 | vfd->lock = &dev->v4l2_lock; | 588 | vfd->lock = &dev->v4l2_lock; |
584 | vfd->v4l2_dev = &dev->v4l2_dev; | 589 | vfd->v4l2_dev = &dev->v4l2_dev; |
585 | vfd->tvnorms = 0; | 590 | vfd->tvnorms = 0; |
591 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
586 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) | 592 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) |
587 | vfd->tvnorms |= dev->ext_vv_data->stds[i].id; | 593 | vfd->tvnorms |= dev->ext_vv_data->stds[i].id; |
588 | strlcpy(vfd->name, name, sizeof(vfd->name)); | 594 | strlcpy(vfd->name, name, sizeof(vfd->name)); |