/*
 * ispqueue.c
 *
 * TI OMAP3 ISP - Video buffers queue handling
 *
 * Copyright (C) 2010 Nokia Corporation
 *
 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 *	     Sakari Ailus <sakari.ailus@iki.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/poll.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

#include "ispqueue.h"

/* -----------------------------------------------------------------------------
 * Video buffers management
 */

/*
 * isp_video_buffer_cache_sync - Keep the buffers coherent between CPU and ISP
 *
 * The typical operation required here is Cache Invalidation across
 * the (user space) buffer address range. And this _must_ be done
 * at QBUF stage (and *only* at QBUF).
 *
 * We try to use optimal cache invalidation function:
 * - dmac_map_area:
 *    - used when the number of pages are _low_.
 *    - it becomes quite slow as the number of pages increase.
 *       - for 648x492 viewfinder (150 pages) it takes 1.3 ms.
 *       - for 5 Mpix buffer (2491 pages) it takes between 25-50 ms.
 *
 * - flush_cache_all:
 *    - used when the number of pages are _high_.
 *    - time taken in the range of 500-900 us.
 *    - has a higher penalty but, as whole dcache + icache is invalidated
 */
/*
 * FIXME: dmac_inv_range crashes randomly on the user space buffer
 *        address. Fall back to flush_cache_all for now.
 */
#define ISP_CACHE_FLUSH_PAGES_MAX       0

static void isp_video_buffer_cache_sync(struct isp_video_buffer *buf)
{
	if (buf->skip_cache)
		return;

	if (buf->vbuf.m.userptr == 0 || buf->npages == 0 ||
	    buf->npages > ISP_CACHE_FLUSH_PAGES_MAX)
		flush_cache_all();
	else {
		dmac_map_area((void *)buf->vbuf.m.userptr, buf->vbuf.length,
			      DMA_FROM_DEVICE);
		outer_inv_range(buf->vbuf.m.userptr,
				buf->vbuf.m.userptr + buf->vbuf.length);
	}
}

/*
 * isp_video_buffer_lock_vma - Prevent VMAs from being unmapped
 *
 * Lock the VMAs underlying the given buffer into memory. This avoids the
 * userspace buffer mapping from being swapped out, making VIPT cache handling
 * easier.
 *
 * Note that the pages will not be freed as the buffers have been locked to
 * memory using by a call to get_user_pages(), but the userspace mapping could
 * still disappear if the VMAs are not locked. This is caused by the memory
 * management code trying to be as lock-less as possible, which results in the
 * userspace mapping manager not finding out that the pages are locked under
 * some conditions.
 */
static int isp_video_buffer_lock_vma(struct isp_video_buffer *buf, int lock)
{
	struct vm_area_struct *vma;
	unsigned long start;
	unsigned long end;
	int ret = 0;

	if (buf->vbuf.memory == V4L2_MEMORY_MMAP)
		return 0;

	/* We can be called from workqueue context if the current task dies to
	 * unlock the VMAs. In that case there's no current memory management
	 * context so unlocking can't be performed, but the VMAs have been or
	 * are getting destroyed anyway so it doesn't really matter.
	 */
	if (!current || !current->mm)
		return lock ? -EINVAL : 0;

	start = buf->vbuf.m.userptr;
	end = buf->vbuf.m.userptr + buf->vbuf.length - 1;

	down_write(&current->mm->mmap_sem);
	spin_lock(&current->mm->page_table_lock);

	do {
		vma = find_vma(current->mm, start);
		if (vma == NULL) {
			ret = -EFAULT;
			goto out;
		}

		if (lock)
			vma->vm_flags |= VM_LOCKED;
		else
			vma->vm_flags &= ~VM_LOCKED;

		start = vma->vm_end + 1;
	} while (vma->vm_end < end);

	if (lock)
		buf->vm_flags |= VM_LOCKED;
	else
		buf->vm_flags &= ~VM_LOCKED;

out:
	spin_unlock(&current->mm->page_table_lock);
	up_write(&current->mm->mmap_sem);
	return ret;
}

/*
 * isp_video_buffer_sglist_kernel - Build a scatter list for a vmalloc'ed buffer
 *
 * Iterate over the vmalloc'ed area and create a scatter list entry for every
 * page.
 */
static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
{
	struct scatterlist *sglist;
	unsigned int npages;
	unsigned int i;
	void *addr;

	addr = buf->vaddr;
	npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;

	sglist = vmalloc(npages * sizeof(*sglist));
	if (sglist == NULL)
		return -ENOMEM;

	sg_init_table(sglist, npages);

	for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
		struct page *page = vmalloc_to_page(addr);

		if (page == NULL || PageHighMem(page)) {
			vfree(sglist);
			return -EINVAL;
		}

		sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
	}

	buf->sglen = npages;
	buf->sglist = sglist;

	return 0;
}

/*
 * isp_video_buffer_sglist_user - Build a scatter list for a userspace buffer
 *
 * Walk the buffer pages list and create a 1:1 mapping to a scatter list.
 */
static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
{
	struct scatterlist *sglist;
	unsigned int offset = buf->offset;
	unsigned int i;

	sglist = vmalloc(buf->npages * sizeof(*sglist));
	if (sglist == NULL)
		return -ENOMEM;

	sg_init_table(sglist, buf->npages);

	for (i = 0; i < buf->npages; ++i) {
		if (PageHighMem(buf->pages[i])) {
			vfree(sglist);
			return -EINVAL;
		}

		sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
			    offset);
		offset = 0;
	}

	buf->sglen = buf->npages;
	buf->sglist = sglist;

	return 0;
}

/*
 * isp_video_buffer_sglist_pfnmap - Build a scatter list for a VM_PFNMAP buffer
 *
 * Create a scatter list of physically contiguous pages starting at the buffer
 * memory physical address.
 */
static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
{
	struct scatterlist *sglist;
	unsigned int offset = buf->offset;
	unsigned long pfn = buf->paddr >> PAGE_SHIFT;
	unsigned int i;

	sglist = vmalloc(buf->npages * sizeof(*sglist));
	if (sglist == NULL)
		return -ENOMEM;

	sg_init_table(sglist, buf->npages);

	for (i = 0; i < buf->npages; ++i, ++pfn) {
		sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
			    offset);
		/* PFNMAP buffers will not get DMA-mapped, set the DMA address
		 * manually.
		 */
		sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
		offset = 0;
	}

	buf->sglen = buf->npages;
	buf->sglist = sglist;

	return 0;
}

/*
 * isp_video_buffer_cleanup - Release pages for a userspace VMA.
 *
 * Release pages locked by a call isp_video_buffer_prepare_user and free the
 * pages table.
 */
static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
{
	enum dma_data_direction direction;
	unsigned int i;

	if (buf->queue->ops->buffer_cleanup)
		buf->queue->ops->buffer_cleanup(buf);

	if (!(buf->vm_flags & VM_PFNMAP)) {
		direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
			  ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
		dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
			     direction);
	}

	vfree(buf->sglist);
	buf->sglist = NULL;
	buf->sglen = 0;

	if (buf->pages != NULL) {
		isp_video_buffer_lock_vma(buf, 0);

		for (i = 0; i < buf->npages; ++i)
			page_cache_release(buf->pages[i]);

		vfree(buf->pages);
		buf->pages = NULL;
	}

	buf->npages = 0;
	buf->skip_cache = false;
}

/*
 * isp_video_buffer_prepare_user - Pin userspace VMA pages to memory.
 *
 * This function creates a list of pages for a userspace VMA. The number of
 * pages is first computed based on the buffer size, and pages are then
 * retrieved by a call to get_user_pages.
 *
 * Pages are pinned to memory by get_user_pages, making them available for DMA
 * transfers. However, due to memory management optimization, it seems the
 * get_user_pages doesn't guarantee that the pinned pages will not be written
 * to swap and removed from the userspace mapping(s). When this happens, a page
 * fault can be generated when accessing those unmapped pages.
 *
 * If the fault is triggered by a page table walk caused by VIPT cache
 * management operations, the page fault handler might oops if the MM semaphore
 * is held, as it can't handle kernel page faults in that case. To fix that, a
 * fixup entry needs to be added to the cache management code, or the userspace
 * VMA must be locked to avoid removing pages from the userspace mapping in the
 * first place.
 *
 * If the number of pages retrieved is smaller than the number required by the
 * buffer size, the function returns -EFAULT.
 */
static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
{
	unsigned long data;
	unsigned int first;
	unsigned int last;
	int ret;

	data = buf->vbuf.m.userptr;
	first = (data & PAGE_MASK) >> PAGE_SHIFT;
	last = ((data + buf->vbuf.length - 1) & PAGE_MASK) >> PAGE_SHIFT;

	buf->offset = data & ~PAGE_MASK;
	buf->npages = last - first + 1;
	buf->pages = vmalloc(buf->npages * sizeof(buf->pages[0]));
	if (buf->pages == NULL)
		return -ENOMEM;

	down_read(&current->mm->mmap_sem);
	ret = get_user_pages(current, current->mm, data & PAGE_MASK,
			     buf->npages,
			     buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
			     buf->pages, NULL);
	up_read(&current->mm->mmap_sem);

	if (ret != buf->npages) {
		buf->npages = ret < 0 ? 0 : ret;
		isp_video_buffer_cleanup(buf);
		return -EFAULT;
	}

	ret = isp_video_buffer_lock_vma(buf, 1);
	if (ret < 0)
		isp_video_buffer_cleanup(buf);

	return ret;
}

/*
 * isp_video_buffer_prepare_pfnmap - Validate a VM_PFNMAP userspace buffer
 *
 * Userspace VM_PFNMAP buffers are supported only if they are contiguous in
 * memory and if they span a single VMA.
 *
 * Return 0 if the buffer is valid, or -EFAULT otherwise.
 */
static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
{
	struct vm_area_struct *vma;
	unsigned long prev_pfn;
	unsigned long this_pfn;
	unsigned long start;
	unsigned long end;
	dma_addr_t pa = 0;
	int ret = -EFAULT;

	start = buf->vbuf.m.userptr;
	end = buf->vbuf.m.userptr + buf->vbuf.length - 1;

	buf->offset = start & ~PAGE_MASK;
	buf->npages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
	buf->pages = NULL;

	down_read(&current->mm->mmap_sem);
	vma = find_vma(current->mm, start);
	if (vma == NULL || vma->vm_end < end)
		goto done;

	for (prev_pfn = 0; start <= end; start += PAGE_SIZE) {
		ret = follow_pfn(vma, start, &this_pfn);
		if (ret)
			goto done;

		if (prev_pfn == 0)
			pa = this_pfn << PAGE_SHIFT;
		else if (this_pfn != prev_pfn + 1) {
			ret = -EFAULT;
			goto done;
		}

		prev_pfn = this_pfn;
	}

	buf->paddr = pa + buf->offset;
	ret = 0;

done:
	up_read(&current->mm->mmap_sem);
	return ret;
}

/*
 * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
 *
 * This function locates the VMAs for the buffer's userspace address and checks
 * that their flags match. The only flag that we need to care for at the moment
 * is VM_PFNMAP.
 *
 * The buffer vm_flags field is set to the first VMA flags.
 *
 * Return -EFAULT if no VMA can be found for part of the buffer, or if the VMAs
 * have incompatible flags.
 */
static int isp_video_buffer_prepare_vm_flags(struct isp_video_buffer *buf)
{
	struct vm_area_struct *vma;
	pgprot_t uninitialized_var(vm_page_prot);
	unsigned long start;
	unsigned long end;
	int ret = -EFAULT;

	start = buf->vbuf.m.userptr;
	end = buf->vbuf.m.userptr + buf->vbuf.length - 1;

	down_read(&current->mm->mmap_sem);

	do {
		vma = find_vma(current->mm, start);
		if (vma == NULL)
			goto done;

		if (start == buf->vbuf.m.userptr) {
			buf->vm_flags = vma->vm_flags;
			vm_page_prot = vma->vm_page_prot;
		}

		if ((buf->vm_flags ^ vma->vm_flags) & VM_PFNMAP)
			goto done;

		if (vm_page_prot != vma->vm_page_prot)
			goto done;

		start = vma->vm_end + 1;
	} while (vma->vm_end < end);

	/* Skip cache management to enhance performances for non-cached or
	 * write-combining buffers.
	 */
	if (vm_page_prot == pgprot_noncached(vm_page_prot) ||
	    vm_page_prot == pgprot_writecombine(vm_page_prot))
		buf->skip_cache = true;

	ret = 0;

done:
	up_read(&current->mm->mmap_sem);
	return ret;
}

/*
 * isp_video_buffer_prepare - Make a buffer ready for operation
 *
 * Preparing a buffer involves:
 *
 * - validating VMAs (userspace buffers only)
 * - locking pages and VMAs into memory (userspace buffers only)
 * - building page and scatter-gather lists
 * - mapping buffers for DMA operation
 * - performing driver-specific preparation
 *
 * The function must be called in userspace context with a valid mm context
 * (this excludes cleanup paths such as sys_close when the userspace process
 * segfaults).
 */
static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
{
	enum dma_data_direction direction;
	int ret;

	switch (buf->vbuf.memory) {
	case V4L2_MEMORY_MMAP:
		ret = isp_video_buffer_sglist_kernel(buf);
		break;

	case V4L2_MEMORY_USERPTR:
		ret = isp_video_buffer_prepare_vm_flags(buf);
		if (ret < 0)
			return ret;

		if (buf->vm_flags & VM_PFNMAP) {
			ret = isp_video_buffer_prepare_pfnmap(buf);
			if (ret < 0)
				return ret;

			ret = isp_video_buffer_sglist_pfnmap(buf);
		} else {
			ret = isp_video_buffer_prepare_user(buf);
			if (ret < 0)
				return ret;

			ret = isp_video_buffer_sglist_user(buf);
		}
		break;

	default:
		return -EINVAL;
	}

	if (ret < 0)
		goto done;

	if (!(buf->vm_flags & VM_PFNMAP)) {
		direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
			  ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
		ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
				 direction);
		if (ret != buf->sglen) {
			ret = -EFAULT;
			goto done;
		}
	}

	if (buf->queue->ops->buffer_prepare)
		ret = buf->queue->ops->buffer_prepare(buf);

done:
	if (ret < 0) {
		isp_video_buffer_cleanup(buf);
		return ret;
	}

	return ret;
}

/*
 * isp_video_queue_query - Query the status of a given buffer
 *
 * Locking: must be called with the queue lock held.
 */
static void isp_video_buffer_query(struct isp_video_buffer *buf,
				   struct v4l2_buffer *vbuf)
{
	memcpy(vbuf, &buf->vbuf, sizeof(*vbuf));

	if (buf->vma_use_count)
		vbuf->flags |= V4L2_BUF_FLAG_MAPPED;

	switch (buf->state) {
	case ISP_BUF_STATE_ERROR:
		vbuf->flags |= V4L2_BUF_FLAG_ERROR;
	case ISP_BUF_STATE_DONE:
		vbuf->flags |= V4L2_BUF_FLAG_DONE;
	case ISP_BUF_STATE_QUEUED:
	case ISP_BUF_STATE_ACTIVE:
		vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
		break;
	case ISP_BUF_STATE_IDLE:
	default:
		break;
	}
}

/*
 * isp_video_buffer_wait - Wait for a buffer to be ready
 *
 * In non-blocking mode, return immediately with 0 if the buffer is ready or
 * -EAGAIN if the buffer is in the QUEUED or ACTIVE state.
 *
 * In blocking mode, wait (interruptibly but with no timeout) on the buffer wait
 * queue using the same condition.
 */
static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
{
	if (nonblocking) {
		return (buf->state != ISP_BUF_STATE_QUEUED &&
			buf->state != ISP_BUF_STATE_ACTIVE)
			? 0 : -EAGAIN;
	}

	return wait_event_interruptible(buf->wait,
		buf->state != ISP_BUF_STATE_QUEUED &&
		buf->state != ISP_BUF_STATE_ACTIVE);
}

/* -----------------------------------------------------------------------------
 * Queue management
 */

/*
 * isp_video_queue_free - Free video buffers memory
 *
 * Buffers can only be freed if the queue isn't streaming and if no buffer is
 * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
 *
 * This function must be called with the queue lock held.
 */
static int isp_video_queue_free(struct isp_video_queue *queue)
{
	unsigned int i;

	if (queue->streaming)
		return -EBUSY;

	for (i = 0; i < queue->count; ++i) {
		if (queue->buffers[i]->vma_use_count != 0)
			return -EBUSY;
	}

	for (i = 0; i < queue->count; ++i) {
		struct isp_video_buffer *buf = queue->buffers[i];

		isp_video_buffer_cleanup(buf);

		vfree(buf->vaddr);
		buf->vaddr = NULL;

		kfree(buf);
		queue->buffers[i] = NULL;
	}

	INIT_LIST_HEAD(&queue->queue);
	queue->count = 0;
	return 0;
}

/*
 * isp_video_queue_alloc - Allocate video buffers memory
 *
 * This function must be called with the queue lock held.
 */
static int isp_video_queue_alloc(struct isp_video_queue *queue,
				 unsigned int nbuffers,
				 unsigned int size, enum v4l2_memory memory)
{
	struct isp_video_buffer *buf;
	unsigned int i;
	void *mem;
	int ret;

	/* Start by freeing the buffers. */
	ret = isp_video_queue_free(queue);
	if (ret < 0)
		return ret;

	/* Bail out if no buffers should be allocated. */
	if (nbuffers == 0)
		return 0;

	/* Initialize the allocated buffers. */
	for (i = 0; i < nbuffers; ++i) {
		buf = kzalloc(queue->bufsize, GFP_KERNEL);
		if (buf == NULL)
			break;

		if (memory == V4L2_MEMORY_MMAP) {
			/* Allocate video buffers memory for mmap mode. Align
			 * the size to the page size.
			 */
			mem = vmalloc_32_user(PAGE_ALIGN(size));
			if (mem == NULL) {
				kfree(buf);
				break;
			}

			buf->vbuf.m.offset = i * PAGE_ALIGN(size);
			buf->vaddr = mem;
		}

		buf->vbuf.index = i;
		buf->vbuf.length = size;
		buf->vbuf.type = queue->type;
		buf->vbuf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
		buf->vbuf.field = V4L2_FIELD_NONE;
		buf->vbuf.memory = memory;

		buf->queue = queue;
		init_waitqueue_head(&buf->wait);

		queue->buffers[i] = buf;
	}

	if (i == 0)
		return -ENOMEM;

	queue->count = i;
	return nbuffers;
}

/**
 * omap3isp_video_queue_cleanup - Clean up the video buffers queue
 * @queue: Video buffers queue
 *
 * Free all allocated resources and clean up the video buffers queue. The queue
 * must not be busy (no ongoing video stream) and buffers must have been
 * unmapped.
 *
 * Return 0 on success or -EBUSY if the queue is busy or buffers haven't been
 * unmapped.
 */
int omap3isp_video_queue_cleanup(struct isp_video_queue *queue)
{
	return isp_video_queue_free(queue);
}

/**
 * omap3isp_video_queue_init - Initialize the video buffers queue
 * @queue: Video buffers queue
 * @type: V4L2 buffer type (capture or output)
 * @ops: Driver-specific queue operations
 * @dev: Device used for DMA operations
 * @bufsize: Size of the driver-specific buffer structure
 *
 * Initialize the video buffers queue with the supplied parameters.
 *
 * The queue type must be one of V4L2_BUF_TYPE_VIDEO_CAPTURE or
 * V4L2_BUF_TYPE_VIDEO_OUTPUT. Other buffer types are not supported yet.
 *
 * Buffer objects will be allocated using the given buffer size to allow room
 * for driver-specific fields. Driver-specific buffer structures must start
 * with a struct isp_video_buffer field. Drivers with no driver-specific buffer
 * structure must pass the size of the isp_video_buffer structure in the bufsize
 * parameter.
 *
 * Return 0 on success.
 */
int omap3isp_video_queue_init(struct isp_video_queue *queue,
			      enum v4l2_buf_type type,
			      const struct isp_video_queue_operations *ops,
			      struct device *dev, unsigned int bufsize)
{
	INIT_LIST_HEAD(&queue->queue);
	mutex_init(&queue->lock);
	spin_lock_init(&queue->irqlock);

	queue->type = type;
	queue->ops = ops;
	queue->dev = dev;
	queue->bufsize = bufsize;

	return 0;
}

/* -----------------------------------------------------------------------------
 * V4L2 operations
 */

/**
 * omap3isp_video_queue_reqbufs - Allocate video buffers memory
 *
 * This function is intended to be used as a VIDIOC_REQBUFS ioctl handler. It
 * allocated video buffer objects and, for MMAP buffers, buffer memory.
 *
 * If the number of buffers is 0, all buffers are freed and the function returns
 * without performing any allocation.
 *
 * If the number of buffers is not 0, currently allocated buffers (if any) are
 * freed and the requested number of buffers are allocated. Depending on
 * driver-specific requirements and on memory availability, a number of buffer
 * smaller or bigger than requested can be allocated. This isn't considered as
 * an error.
 *
 * Return 0 on success or one of the following error codes:
 *
 * -EINVAL if the buffer type or index are invalid
 * -EBUSY if the queue is busy (streaming or buffers mapped)
 * -ENOMEM if the buffers can't be allocated due to an out-of-memory condition
 */
int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
				 struct v4l2_requestbuffers *rb)
{
	unsigned int nbuffers = rb->count;
	unsigned int size;
	int ret;

	if (rb->type != queue->type)
		return -EINVAL;

	queue->ops->queue_prepare(queue, &nbuffers, &size);
	if (size == 0)
		return -EINVAL;

	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;

	rb->count = ret;
	ret = 0;

done:
	mutex_unlock(&queue->lock);
	return ret;
}

/**
 * omap3isp_video_queue_querybuf - Query the status of a buffer in a queue
 *
 * This function is intended to be used as a VIDIOC_QUERYBUF ioctl handler. It
 * returns the status of a given video buffer.
 *
 * Return 0 on success or -EINVAL if the buffer type or index are invalid.
 */
int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
				  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;
	}

	buf = queue->buffers[vbuf->index];
	isp_video_buffer_query(buf, vbuf);

done:
	mutex_unlock(&queue->lock);
	return ret;
}

/**
 * omap3isp_video_queue_qbuf - Queue a buffer
 *
 * This function is intended to be used as a VIDIOC_QBUF ioctl handler.
 *
 * The v4l2_buffer structure passed from userspace is first sanity tested. If
 * sane, the buffer is then processed and added to the main queue and, if the
 * queue is streaming, to the IRQ queue.
 *
 * Before being enqueued, USERPTR buffers are checked for address changes. If
 * the buffer has a different userspace address, the old memory area is unlocked
 * and the new memory area is locked.
 */
int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
			      struct v4l2_buffer *vbuf)
{
	struct isp_video_buffer *buf;
	unsigned long flags;
	int ret = -EINVAL;

	if (vbuf->type != queue->type)
		goto done;

	mutex_lock(&queue->lock);

	if (vbuf->index >= queue->count)
		goto done;

	buf = queue->buffers[vbuf->index];

	if (vbuf->memory != buf->vbuf.memory)
		goto done;

	if (buf->state != ISP_BUF_STATE_IDLE)
		goto done;

	if (vbuf->memory == V4L2_MEMORY_USERPTR &&
	    vbuf->length < buf->vbuf.length)
		goto done;

	if (vbuf->memory == V4L2_MEMORY_USERPTR &&
	    vbuf->m.userptr != buf->vbuf.m.userptr) {
		isp_video_buffer_cleanup(buf);
		buf->vbuf.m.userptr = vbuf->m.userptr;
		buf->prepared = 0;
	}

	if (!buf->prepared) {
		ret = isp_video_buffer_prepare(buf);
		if (ret < 0)
			goto done;
		buf->prepared = 1;
	}

	isp_video_buffer_cache_sync(buf);

	buf->state = ISP_BUF_STATE_QUEUED;
	list_add_tail(&buf->stream, &queue->queue);

	if (queue->streaming) {
		spin_lock_irqsave(&queue->irqlock, flags);
		queue->ops->buffer_queue(buf);
		spin_unlock_irqrestore(&queue->irqlock, flags);
	}

	ret = 0;

done:
	mutex_unlock(&queue->lock);
	return ret;
}

/**
 * omap3isp_video_queue_dqbuf - Dequeue a buffer
 *
 * This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
 *
 * Wait until a buffer is ready to be dequeued, remove it from the queue and
 * copy its information to the v4l2_buffer structure.
 *
 * If the nonblocking argument is not zero and no buffer is ready, return
 * -EAGAIN immediately instead of waiting.
 *
 * If no buffer has been enqueued, or if the requested buffer type doesn't match
 * the queue type, return -EINVAL.
 */
int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
			       struct v4l2_buffer *vbuf, int nonblocking)
{
	struct isp_video_buffer *buf;
	int ret;

	if (vbuf->type != queue->type)
		return -EINVAL;

	mutex_lock(&queue->lock);

	if (list_empty(&queue->queue)) {
		ret = -EINVAL;
		goto done;
	}

	buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
	ret = isp_video_buffer_wait(buf, nonblocking);
	if (ret < 0)
		goto done;

	list_del(&buf->stream);

	isp_video_buffer_query(buf, vbuf);
	buf->state = ISP_BUF_STATE_IDLE;
	vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;

done:
	mutex_unlock(&queue->lock);
	return ret;
}

/**
 * omap3isp_video_queue_streamon - Start streaming
 *
 * This function is intended to be used as a VIDIOC_STREAMON ioctl handler. It
 * starts streaming on the queue and calls the buffer_queue operation for all
 * queued buffers.
 *
 * Return 0 on success.
 */
int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
{
	struct isp_video_buffer *buf;
	unsigned long flags;

	mutex_lock(&queue->lock);

	if (queue->streaming)
		goto done;

	queue->streaming = 1;

	spin_lock_irqsave(&queue->irqlock, flags);
	list_for_each_entry(buf, &queue->queue, stream)
		queue->ops->buffer_queue(buf);
	spin_unlock_irqrestore(&queue->irqlock, flags);

done:
	mutex_unlock(&queue->lock);
	return 0;
}

/**
 * omap3isp_video_queue_streamoff - Stop streaming
 *
 * This function is intended to be used as a VIDIOC_STREAMOFF ioctl handler. It
 * stops streaming on the queue and wakes up all the buffers.
 *
 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
 * delayed works before calling this function to make sure no buffer will be
 * touched by the driver and/or hardware.
 */
void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
{
	struct isp_video_buffer *buf;
	unsigned long flags;
	unsigned int i;

	mutex_lock(&queue->lock);

	if (!queue->streaming)
		goto done;

	queue->streaming = 0;

	spin_lock_irqsave(&queue->irqlock, flags);
	for (i = 0; i < queue->count; ++i) {
		buf = queue->buffers[i];

		if (buf->state == ISP_BUF_STATE_ACTIVE)
			wake_up(&buf->wait);

		buf->state = ISP_BUF_STATE_IDLE;
	}
	spin_unlock_irqrestore(&queue->irqlock, flags);

	INIT_LIST_HEAD(&queue->queue);

done:
	mutex_unlock(&queue->lock);
}

/**
 * omap3isp_video_queue_discard_done - Discard all buffers marked as DONE
 *
 * This function is intended to be used with suspend/resume operations. It
 * discards all 'done' buffers as they would be too old to be requested after
 * resume.
 *
 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
 * delayed works before calling this function to make sure no buffer will be
 * touched by the driver and/or hardware.
 */
void omap3isp_video_queue_discard_done(struct isp_video_queue *queue)
{
	struct isp_video_buffer *buf;
	unsigned int i;

	mutex_lock(&queue->lock);

	if (!queue->streaming)
		goto done;

	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)
{
	struct isp_video_buffer *buf = vma->vm_private_data;

	buf->vma_use_count++;
}

static void isp_video_queue_vm_close(struct vm_area_struct *vma)
{
	struct isp_video_buffer *buf = vma->vm_private_data;

	buf->vma_use_count--;
}

static const struct vm_operations_struct isp_video_queue_vm_ops = {
	.open = isp_video_queue_vm_open,
	.close = isp_video_queue_vm_close,
};

/**
 * omap3isp_video_queue_mmap - Map buffers to userspace
 *
 * This function is intended to be used as an mmap() file operation handler. It
 * maps a buffer to userspace based on the VMA offset.
 *
 * Only buffers of memory type MMAP are supported.
 */
int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
			 struct vm_area_struct *vma)
{
	struct isp_video_buffer *uninitialized_var(buf);
	unsigned long size;
	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;
	}

	size = vma->vm_end - vma->vm_start;

	if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
	    size != PAGE_ALIGN(buf->vbuf.length)) {
		ret = -EINVAL;
		goto done;
	}

	ret = remap_vmalloc_range(vma, buf->vaddr, 0);
	if (ret < 0)
		goto done;

	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;
}

/**
 * omap3isp_video_queue_poll - Poll video queue state
 *
 * This function is intended to be used as a poll() file operation handler. It
 * polls the state of the video buffer at the front of the queue and returns an
 * events mask.
 *
 * If no buffer is present at the front of the queue, POLLERR is returned.
 */
unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
				       struct file *file, poll_table *wait)
{
	struct isp_video_buffer *buf;
	unsigned int mask = 0;

	mutex_lock(&queue->lock);
	if (list_empty(&queue->queue)) {
		mask |= POLLERR;
		goto done;
	}
	buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);

	poll_wait(file, &buf->wait, wait);
	if (buf->state == ISP_BUF_STATE_DONE ||
	    buf->state == ISP_BUF_STATE_ERROR) {
		if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
			mask |= POLLIN | POLLRDNORM;
		else
			mask |= POLLOUT | POLLWRNORM;
	}

done:
	mutex_unlock(&queue->lock);
	return mask;
}
