struct device *dev, unsigned int bufsize)
{
INIT_LIST_HEAD(&queue->queue);
- mutex_init(&queue->lock);
spin_lock_init(&queue->irqlock);
queue->type = type;
nbuffers = min_t(unsigned int, nbuffers, ISP_VIDEO_MAX_BUFFERS);
- mutex_lock(&queue->lock);
-
ret = isp_video_queue_alloc(queue, nbuffers, size, rb->memory);
if (ret < 0)
- goto done;
+ return ret;
rb->count = ret;
- ret = 0;
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
+ return 0;
}
/**
struct v4l2_buffer *vbuf)
{
struct isp_video_buffer *buf;
- int ret = 0;
if (vbuf->type != queue->type)
return -EINVAL;
- mutex_lock(&queue->lock);
-
- if (vbuf->index >= queue->count) {
- ret = -EINVAL;
- goto done;
- }
+ if (vbuf->index >= queue->count)
+ return -EINVAL;
buf = queue->buffers[vbuf->index];
isp_video_buffer_query(buf, vbuf);
-done:
- mutex_unlock(&queue->lock);
- return ret;
+ return 0;
}
/**
{
struct isp_video_buffer *buf;
unsigned long flags;
- int ret = -EINVAL;
+ int ret;
if (vbuf->type != queue->type)
- goto done;
-
- mutex_lock(&queue->lock);
+ return -EINVAL;
if (vbuf->index >= queue->count)
- goto done;
+ return -EINVAL;
buf = queue->buffers[vbuf->index];
if (vbuf->memory != buf->vbuf.memory)
- goto done;
+ return -EINVAL;
if (buf->state != ISP_BUF_STATE_IDLE)
- goto done;
+ return -EINVAL;
if (vbuf->memory == V4L2_MEMORY_USERPTR &&
vbuf->length < buf->vbuf.length)
- goto done;
+ return -EINVAL;
if (vbuf->memory == V4L2_MEMORY_USERPTR &&
vbuf->m.userptr != buf->vbuf.m.userptr) {
if (!buf->prepared) {
ret = isp_video_buffer_prepare(buf);
if (ret < 0)
- goto done;
+ return ret;
buf->prepared = 1;
}
spin_unlock_irqrestore(&queue->irqlock, flags);
}
- ret = 0;
-
-done:
- mutex_unlock(&queue->lock);
- return ret;
+ return 0;
}
/**
if (vbuf->type != queue->type)
return -EINVAL;
- mutex_lock(&queue->lock);
-
- if (list_empty(&queue->queue)) {
- ret = -EINVAL;
- goto done;
- }
+ if (list_empty(&queue->queue))
+ return -EINVAL;
buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
ret = isp_video_buffer_wait(buf, nonblocking);
if (ret < 0)
- goto done;
+ return ret;
list_del(&buf->stream);
buf->state = ISP_BUF_STATE_IDLE;
vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;
-done:
- mutex_unlock(&queue->lock);
- return ret;
+ return 0;
}
/**
struct isp_video_buffer *buf;
unsigned long flags;
- mutex_lock(&queue->lock);
-
if (queue->streaming)
- goto done;
+ return 0;
queue->streaming = 1;
queue->ops->buffer_queue(buf);
spin_unlock_irqrestore(&queue->irqlock, flags);
-done:
- mutex_unlock(&queue->lock);
return 0;
}
unsigned long flags;
unsigned int i;
- mutex_lock(&queue->lock);
-
if (!queue->streaming)
- goto done;
+ return;
queue->streaming = 0;
spin_unlock_irqrestore(&queue->irqlock, flags);
INIT_LIST_HEAD(&queue->queue);
-
-done:
- mutex_unlock(&queue->lock);
}
/**
struct isp_video_buffer *buf;
unsigned int i;
- mutex_lock(&queue->lock);
-
if (!queue->streaming)
- goto done;
+ return;
for (i = 0; i < queue->count; ++i) {
buf = queue->buffers[i];
if (buf->state == ISP_BUF_STATE_DONE)
buf->state = ISP_BUF_STATE_ERROR;
}
-
-done:
- mutex_unlock(&queue->lock);
}
static void isp_video_queue_vm_open(struct vm_area_struct *vma)
unsigned int i;
int ret = 0;
- mutex_lock(&queue->lock);
-
for (i = 0; i < queue->count; ++i) {
buf = queue->buffers[i];
if ((buf->vbuf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
break;
}
- if (i == queue->count) {
- ret = -EINVAL;
- goto done;
- }
+ if (i == queue->count)
+ return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
- size != PAGE_ALIGN(buf->vbuf.length)) {
- ret = -EINVAL;
- goto done;
- }
+ size != PAGE_ALIGN(buf->vbuf.length))
+ return -EINVAL;
/* dma_mmap_coherent() uses vm_pgoff as an offset inside the buffer
* while we used it to identify the buffer and want to map the whole
ret = dma_mmap_coherent(queue->dev, vma, buf->vaddr, buf->dma, size);
if (ret < 0)
- goto done;
+ return ret;
vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &isp_video_queue_vm_ops;
vma->vm_private_data = buf;
isp_video_queue_vm_open(vma);
-done:
- mutex_unlock(&queue->lock);
- return ret;
+ return 0;
}
/**
struct isp_video_buffer *buf;
unsigned int mask = 0;
- mutex_lock(&queue->lock);
if (list_empty(&queue->queue)) {
mask |= POLLERR;
goto done;
}
done:
- mutex_unlock(&queue->lock);
return mask;
}
{
struct isp_buffer *buf = NULL;
- if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ mutex_lock(&video->queue_lock);
omap3isp_video_queue_discard_done(video->queue);
+ mutex_unlock(&video->queue_lock);
+ }
if (!list_empty(&video->dmaqueue)) {
buf = list_first_entry(&video->dmaqueue,
isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
{
struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video *video = video_drvdata(file);
+ int ret;
+
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_reqbufs(&vfh->queue, rb);
+ mutex_unlock(&video->queue_lock);
- return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
+ return ret;
}
static int
isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video *video = video_drvdata(file);
+ int ret;
- return omap3isp_video_queue_querybuf(&vfh->queue, b);
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_querybuf(&vfh->queue, b);
+ mutex_unlock(&video->queue_lock);
+
+ return ret;
}
static int
isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video *video = video_drvdata(file);
+ int ret;
+
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_qbuf(&vfh->queue, b);
+ mutex_unlock(&video->queue_lock);
- return omap3isp_video_queue_qbuf(&vfh->queue, b);
+ return ret;
}
static int
isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video *video = video_drvdata(file);
+ int ret;
+
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_dqbuf(&vfh->queue, b,
+ file->f_flags & O_NONBLOCK);
+ mutex_unlock(&video->queue_lock);
- return omap3isp_video_queue_dqbuf(&vfh->queue, b,
- file->f_flags & O_NONBLOCK);
+ return ret;
}
static int isp_video_check_external_subdevs(struct isp_video *video,
INIT_LIST_HEAD(&video->dmaqueue);
atomic_set(&pipe->frame_number, -1);
+ mutex_lock(&video->queue_lock);
ret = omap3isp_video_queue_streamon(&vfh->queue);
+ mutex_unlock(&video->queue_lock);
if (ret < 0)
goto err_check_format;
return 0;
err_set_stream:
+ mutex_lock(&video->queue_lock);
omap3isp_video_queue_streamoff(&vfh->queue);
+ mutex_unlock(&video->queue_lock);
err_check_format:
media_entity_pipeline_stop(&video->video.entity);
err_pipeline_start:
mutex_lock(&video->stream_lock);
/* Make sure we're not streaming yet. */
- mutex_lock(&vfh->queue.lock);
+ mutex_lock(&video->queue_lock);
streaming = vfh->queue.streaming;
- mutex_unlock(&vfh->queue.lock);
+ mutex_unlock(&video->queue_lock);
if (!streaming)
goto done;
/* Stop the stream. */
omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
+ mutex_lock(&video->queue_lock);
omap3isp_video_queue_streamoff(&vfh->queue);
+ mutex_unlock(&video->queue_lock);
video->queue = NULL;
video->streaming = 0;
video->error = false;
/* Disable streaming and free the buffers queue resources. */
isp_video_streamoff(file, vfh, video->type);
- mutex_lock(&handle->queue.lock);
+ mutex_lock(&video->queue_lock);
omap3isp_video_queue_cleanup(&handle->queue);
- mutex_unlock(&handle->queue.lock);
+ mutex_unlock(&video->queue_lock);
omap3isp_pipeline_pm_use(&video->video.entity, 0);
static unsigned int isp_video_poll(struct file *file, poll_table *wait)
{
struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
- struct isp_video_queue *queue = &vfh->queue;
+ struct isp_video *video = video_drvdata(file);
+ int ret;
- return omap3isp_video_queue_poll(queue, file, wait);
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_poll(&vfh->queue, file, wait);
+ mutex_unlock(&video->queue_lock);
+
+ return ret;
}
static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
{
struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
+ struct isp_video *video = video_drvdata(file);
+ int ret;
+
+ mutex_lock(&video->queue_lock);
+ ret = omap3isp_video_queue_mmap(&vfh->queue, vma);
+ mutex_unlock(&video->queue_lock);
- return omap3isp_video_queue_mmap(&vfh->queue, vma);
+ return ret;
}
static struct v4l2_file_operations isp_video_fops = {
spin_lock_init(&video->pipe.lock);
mutex_init(&video->stream_lock);
+ mutex_init(&video->queue_lock);
/* Initialize the video device. */
if (video->ops == NULL)
void omap3isp_video_cleanup(struct isp_video *video)
{
media_entity_cleanup(&video->video.entity);
+ mutex_destroy(&video->queue_lock);
mutex_destroy(&video->stream_lock);
mutex_destroy(&video->mutex);
}