diff options
Diffstat (limited to 'drivers/media/pci/cx18/cx18-fileops.c')
-rw-r--r-- | drivers/media/pci/cx18/cx18-fileops.c | 85 |
1 files changed, 16 insertions, 69 deletions
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 4cf5b9ca92e7..7e742733391b 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -584,12 +584,6 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, if (rc) return rc; - if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (id->type == CX18_ENC_STREAM_TYPE_YUV)) { - return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0, - filp->f_flags & O_NONBLOCK); - } - return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); } @@ -618,17 +612,6 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) CX18_DEBUG_FILE("Encoder poll started capture\n"); } - if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (id->type == CX18_ENC_STREAM_TYPE_YUV)) { - __poll_t videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait); - - if (v4l2_event_pending(&id->fh)) - res |= EPOLLPRI; - if (eof && videobuf_poll == EPOLLERR) - return res | EPOLLHUP; - return res | videobuf_poll; - } - /* add stream's waitq to the poll list */ CX18_DEBUG_HI_FILE("Encoder poll\n"); if (v4l2_event_pending(&id->fh)) @@ -643,62 +626,20 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) return res; } -int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); - - if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (id->type == CX18_ENC_STREAM_TYPE_YUV)) { - - /* Start a capture if there is none */ - if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { - int rc; - - mutex_lock(&cx->serialize_lock); - rc = cx18_start_capture(id); - mutex_unlock(&cx->serialize_lock); - if (rc) { - CX18_DEBUG_INFO( - "Could not start capture for %s (%d)\n", - s->name, rc); - return -EINVAL; - } - CX18_DEBUG_FILE("Encoder mmap started capture\n"); - } - - return videobuf_mmap_mapper(&s->vbuf_q, vma); - } - - return -EINVAL; -} - void cx18_vb_timeout(struct timer_list *t) { struct cx18_stream *s = from_timer(s, t, vb_timeout); - struct cx18_videobuf_buffer *buf; - unsigned long flags; - /* Return all of the buffers in error state, so the vbi/vid inode + /* + * Return all of the buffers in error state, so the vbi/vid inode * can return from blocking. */ - spin_lock_irqsave(&s->vb_lock, flags); - while (!list_empty(&s->vb_capture)) { - buf = list_entry(s->vb_capture.next, - struct cx18_videobuf_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - } - spin_unlock_irqrestore(&s->vb_lock, flags); + cx18_clear_queue(s, VB2_BUF_STATE_ERROR); } -void cx18_stop_capture(struct cx18_open_id *id, int gop_end) +void cx18_stop_capture(struct cx18_stream *s, int gop_end) { - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; + struct cx18 *cx = s->cx; struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; @@ -709,7 +650,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end) /* Stop capturing */ if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) { CX18_DEBUG_INFO("close stopping capture\n"); - if (id->type == CX18_ENC_STREAM_TYPE_MPG) { + if (s->type == CX18_ENC_STREAM_TYPE_MPG) { /* Stop internal use associated VBI and IDX streams */ if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { @@ -721,7 +662,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end) cx18_stop_v4l2_encode_stream(s_idx, 0); } } - if (id->type == CX18_ENC_STREAM_TYPE_VBI && + if (s->type == CX18_ENC_STREAM_TYPE_VBI && test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) /* Also used internally, don't stop capturing */ s->id = -1; @@ -741,13 +682,14 @@ int cx18_v4l2_close(struct file *filp) struct cx18_open_id *id = fh2id(fh); struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; + struct video_device *vdev = &s->video_dev; CX18_DEBUG_IOCTL("close() of %s\n", s->name); mutex_lock(&cx->serialize_lock); /* Stop radio */ if (id->type == CX18_ENC_STREAM_TYPE_RAD && - v4l2_fh_is_singular_file(filp)) { + v4l2_fh_is_singular_file(filp)) { /* Closing radio device, return to TV mode */ cx18_mute(cx); /* Mark that the radio is no longer in use */ @@ -766,12 +708,17 @@ int cx18_v4l2_close(struct file *filp) cx18_unmute(cx); } + if (id->type == CX18_ENC_STREAM_TYPE_YUV && + filp->private_data == vdev->queue->owner) { + vb2_queue_release(vdev->queue); + vdev->queue->owner = NULL; + } v4l2_fh_del(fh); v4l2_fh_exit(fh); /* 'Unclaim' this stream */ - if (s->id == id->open_id) - cx18_stop_capture(id, 0); + if (id->type != CX18_ENC_STREAM_TYPE_YUV && s->id == id->open_id) + cx18_stop_capture(s, 0); kfree(id); mutex_unlock(&cx->serialize_lock); return 0; |