/*
 * drivers/media/m2m1shot2.c
 *
 * Copyright (C) 2015 Samsung Electronics Co., Ltd.
 *
 * Contact: Cho KyongHo <pullip.cho@samsung.com>
 *
 * 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.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/compat.h>

#include <linux/ion.h>
#include <linux/exynos_ion.h>
#include <linux/exynos_iovmm.h>

#include <media/m2m1shot2.h>

#include <asm/cacheflush.h>

#define M2M1SHOT2_NEED_CACHEFLUSH_ALL (10 * SZ_1M)
#define M2M1SHOT2_FENCE_MASK (M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE |		\
					M2M1SHOT2_IMGFLAG_RELEASE_FENCE)

static void m2m1shot2_fence_callback(struct sync_fence *fence,
					struct sync_fence_waiter *waiter);

static void m2m1shot2_timeout_handler(unsigned long arg);

/*
 * STATE TRANSITION of m2m1shot2_context:
 * - PROCESSING:
 *     # set in m2m1shot2_start_processing() after the context is moved to
 *       active_contexts.
 *     # clear in __m2m1shot2_finish_context() inside m2m1shot2_finish_context()
 *       that is called by the client driver when IRQ occurs.
 * - PENDING:
 *     # set in m2m1shot2_start_context() along with PROCESSING.
 *     # clear in m2m1shot2_schedule() before calling .device_run().
 * - WAITING:
 *     # set at the entry of m2m1shot2_wait_process()
 *     # clear in m2m1shot2_ioctl() before returning to user
 * - PROCESSED:
 *     # set in __m2m1shot2_finish_context() along with clearing PROCESSING.
 *     # clear in m2m1shot2_ioctl() before returning to user
 * - ERROR:
 *     # set in __m2m1shot2_finish_context() on an error
 *     # clear in m2m1shot2_ioctl() before returning to user
 */
static int m2m1shot2_open(struct inode *inode, struct file *filp)
{
	struct m2m1shot2_device *m21dev = container_of(filp->private_data,
						struct m2m1shot2_device, misc);
	struct m2m1shot2_context *ctx;
	unsigned long flags;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->timeline = sw_sync_timeline_create(dev_name(m21dev->dev));
	if (!ctx->timeline) {
		dev_err(m21dev->dev, "Failed to create timeline\n");
		ret = -ENOMEM;
		goto err_timeline;
	}

	INIT_LIST_HEAD(&ctx->node);

	spin_lock_irqsave(&m21dev->lock_ctx, flags);
	list_add_tail(&ctx->node, &m21dev->contexts);
	spin_unlock_irqrestore(&m21dev->lock_ctx, flags);

	ctx->m21dev = m21dev;
	mutex_init(&ctx->mutex);
	init_completion(&ctx->complete);
	complete_all(&ctx->complete); /* prevent to wait for completion */

	filp->private_data = ctx;

	for (ret = 0; ret < M2M1SHOT2_MAX_IMAGES; ret++) {
		ctx->source[ret].img.index = ret;
		sync_fence_waiter_init(&ctx->source[ret].img.waiter,
					m2m1shot2_fence_callback);
	}
	ctx->target.index = M2M1SHOT2_MAX_IMAGES;
	sync_fence_waiter_init(&ctx->target.waiter, m2m1shot2_fence_callback);

	ret = m21dev->ops->init_context(ctx);
	if (ret)
		goto err_init;

	spin_lock(&m21dev->lock_priority);
	ctx->priority = M2M1SHOT2_DEFAULT_PRIORITY;
	m21dev->prior_stats[ctx->priority] += 1;
	spin_unlock(&m21dev->lock_priority);

	spin_lock_init(&ctx->fence_timeout_lock);

	setup_timer(&ctx->timer, m2m1shot2_timeout_handler,
						(unsigned long)ctx);

	return 0;
err_init:
	sync_timeline_destroy(&ctx->timeline->obj);
err_timeline:
	kfree(ctx);
	return ret;

}

/*
 * m2m1shot2_current_context - get the current m2m1shot2_context
 *
 * return the current context pointer.
 * This function should not be called other places than the function that
 * finishes the current context.
 */
struct m2m1shot2_context *m2m1shot2_current_context(
				const struct m2m1shot2_device *m21dev)
{
	return m21dev->current_ctx;
}

static void m2m1shot2_put_userptr(struct device *dev,
				 struct m2m1shot2_dma_buffer *plane)
{
	struct vm_area_struct *vma = plane->userptr.vma;
	struct mm_struct *mm;

	BUG_ON((vma == NULL) || (plane->userptr.addr == 0));

	mm = vma->vm_mm;

	exynos_iovmm_unmap_userptr(dev, plane->dma_addr);

	down_read(&mm->mmap_sem);

	while (vma) {
		struct vm_area_struct *tvma;

		if (vma->vm_ops && vma->vm_ops->close)
			vma->vm_ops->close(vma);

		if (vma->vm_file)
			fput(vma->vm_file);

		tvma = vma;
		vma = vma->vm_next;

		kfree(tvma);
	}

	up_read(&mm->mmap_sem);

	mmput(mm);

	plane->userptr.vma = NULL;
	plane->userptr.addr = 0;
}

static void m2m1shot2_put_dmabuf(struct m2m1shot2_dma_buffer *plane)
{
	ion_iovmm_unmap(plane->dmabuf.attachment,
			plane->dma_addr - plane->dmabuf.offset);
	dma_buf_detach(plane->dmabuf.dmabuf, plane->dmabuf.attachment);
	dma_buf_put(plane->dmabuf.dmabuf);
	plane->dmabuf.dmabuf = NULL;
	plane->dmabuf.attachment = NULL;
}

static void m2m1shot2_put_buffer(struct m2m1shot2_context *ctx, u32 memory,
				 struct m2m1shot2_dma_buffer plane[],
				 unsigned int num_planes)
{
	unsigned int i;

	if (memory == M2M1SHOT2_BUFTYPE_DMABUF) {
		for (i = 0; i < num_planes; i++)
			m2m1shot2_put_dmabuf(&plane[i]);
	} else if (memory == M2M1SHOT2_BUFTYPE_USERPTR) {
		for (i = 0; i < num_planes; i++)
			m2m1shot2_put_userptr(ctx->m21dev->dev, &plane[i]);
	}
}

static void m2m1shot2_put_image(struct m2m1shot2_context *ctx,
				struct m2m1shot2_context_image *img)
{
	if (!!(img->flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE)) {
		/*
		 * confirm the fence callback is not called after img->fence is
		 * cleared by the deferred behavior of sync_fence_put().
		 */
		sync_fence_cancel_async(img->fence, &img->waiter);
		sync_fence_put(img->fence);
		img->flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
	}

	m2m1shot2_put_buffer(ctx, img->memory, img->plane, img->num_planes);

	img->memory = M2M1SHOT2_BUFTYPE_NONE;
}

static void m2m1shot2_put_source_images(struct m2m1shot2_context *ctx)
{
	unsigned int i;

	for (i = 0; i < ctx->num_sources; i++)
		m2m1shot2_put_image(ctx, &ctx->source[i].img);

	ctx->num_sources = 0;
}

static void m2m1shot2_put_images(struct m2m1shot2_context *ctx)
{
	m2m1shot2_put_source_images(ctx);
	m2m1shot2_put_image(ctx, &ctx->target);
}

static void __m2m1shot2_finish_context(struct m2m1shot2_context *ctx,
					bool success)
{
	struct m2m1shot2_device *m21dev = ctx->m21dev;
	unsigned long flags;

	sw_sync_timeline_inc(ctx->timeline, 1);

	spin_lock_irqsave(&m21dev->lock_ctx, flags);

	/* effective only to the current processing context */
	if (WARN_ON(ctx != m21dev->current_ctx)) {
		spin_unlock_irqrestore(&m21dev->lock_ctx, flags);
		return;
	}

	m21dev->current_ctx = NULL;
	list_add_tail(&ctx->node, &m21dev->contexts);

	spin_unlock_irqrestore(&m21dev->lock_ctx, flags);

	if (!success)
		set_bit(M2M1S2_CTXSTATE_ERROR, &ctx->state);

	set_bit(M2M1S2_CTXSTATE_PROCESSED, &ctx->state);
	clear_bit(M2M1S2_CTXSTATE_PROCESSING, &ctx->state);

	complete_all(&ctx->complete);
}

/**
 * __m2m1shot2_schedule() - pick a context to process
 *
 * pick a context that is at the front of m2m1shot2_device.active_contexts
 * and provide it to the client to process that context.
 * If the client returns error then pick the next context.
 */
static void __m2m1shot2_schedule(struct m2m1shot2_device *m21dev)
{
	struct m2m1shot2_context *ctx;
	unsigned long flags;

retry:
	spin_lock_irqsave(&m21dev->lock_ctx, flags);

	if (m21dev->current_ctx != NULL) {
		/* the client is currently processing a context */
		spin_unlock_irqrestore(&m21dev->lock_ctx, flags);
		return;
	}

	if (list_empty(&m21dev->active_contexts)) {
		/* no context to process */
		spin_unlock_irqrestore(&m21dev->lock_ctx, flags);
		return;
	}

	ctx = list_first_entry(&m21dev->active_contexts,
				struct m2m1shot2_context, node);
	m21dev->current_ctx = ctx;
	list_del_init(&ctx->node);

	spin_unlock_irqrestore(&m21dev->lock_ctx, flags);

	clear_bit(M2M1S2_CTXSTATE_PENDING, &ctx->state);

	if (m21dev->ops->device_run(ctx) < 0) {
		__m2m1shot2_finish_context(ctx, false);
		goto retry;
	}
}

#define is_vma_cached(vma)						      \
	((pgprot_noncached((vma)->vm_page_prot) != (vma)->vm_page_prot) &&    \
	   (pgprot_writecombine((vma)->vm_page_prot) != (vma)->vm_page_prot))

static void m2m1shot2_unmap_image(struct m2m1shot2_device *m21dev,
				struct m2m1shot2_context_image *img,
				enum dma_data_direction dir,
				bool skip_inv)
{
	bool inv = !skip_inv && !(img->flags & M2M1SHOT2_IMGFLAG_NO_CACHEINV) &&
			!(m21dev->attr & M2M1SHOT2_DEVATTR_COHERENT);
	unsigned int i;

	/* dma_buf_map_attachment() is not called */
	if (img->plane[0].sgt == NULL)
		return;

	if (img->memory == M2M1SHOT2_BUFTYPE_USERPTR) {
		for (i = 0; i < img->num_planes; i++)
			if (is_vma_cached(img->plane[i].userptr.vma) && inv)
				exynos_iommu_sync_for_cpu(m21dev->dev,
						img->plane[i].dma_addr,
						img->plane[i].payload, dir);
	} else if (img->memory == M2M1SHOT2_BUFTYPE_DMABUF) {
		for (i = 0; i < img->num_planes; i++) {
			if (inv)
				exynos_ion_sync_dmabuf_for_cpu(m21dev->dev,
						img->plane[i].dmabuf.dmabuf,
						img->plane[i].payload, dir);
			dma_buf_unmap_attachment(
					img->plane[i].dmabuf.attachment,
					img->plane[i].sgt, dir);
			/* not to call unmap again */
			img->plane[i].sgt = NULL;
		}
	}
}

static void m2m1shot2_unmap_images(struct m2m1shot2_context *ctx)
{
	bool flush_all = test_bit(M2M1S2_CTXSTATE_CACHEINVALALL, &ctx->state);
	unsigned int i;

	for (i = 0; i < ctx->num_sources; i++)
		m2m1shot2_unmap_image(ctx->m21dev,
				&ctx->source[i].img, DMA_TO_DEVICE, flush_all);

	m2m1shot2_unmap_image(ctx->m21dev,
				&ctx->target, DMA_FROM_DEVICE, flush_all);

	if (flush_all && !(ctx->m21dev->attr & M2M1SHOT2_DEVATTR_COHERENT))
		flush_all_cpu_caches();
}

static int m2m1shot2_map_image(struct m2m1shot2_device *m21dev,
				struct m2m1shot2_context_image *img,
				enum dma_data_direction dir)
{
	unsigned int i;

	/* nothing to do for userptr and empty buffer types */
	if (img->memory != M2M1SHOT2_BUFTYPE_DMABUF)
		return 0;

	for (i = 0; i < img->num_planes; i++) {
		img->plane[i].sgt = dma_buf_map_attachment(
					img->plane[i].dmabuf.attachment, dir);
		if (IS_ERR(img->plane[i].sgt)) {
			int ret = PTR_ERR(img->plane[i].sgt);

			dev_err(m21dev->dev, "failed to map dmabuf-attachment");
			img->plane[i].sgt = NULL;
			while (i-- > 0) {
				dma_buf_unmap_attachment(
						img->plane[i].dmabuf.attachment,
						img->plane[i].sgt, dir);
				img->plane[i].sgt = NULL;
			}
			return ret;
		}
	}

	return 0;
}

static bool m2m1shot2_need_shareable_flush(struct dma_buf *dmabuf, bool clear)
{
	return dma_buf_get_privflag(dmabuf, clear) &&
				ion_may_hwrender_dmabuf(dmabuf);

}

static void m2m1shot2_cachesync_image(struct m2m1shot2_context *ctx,
				      struct m2m1shot2_context_image *img,
				      enum dma_data_direction dir)
{
	int i;

	if (!!(img->flags & M2M1SHOT2_IMGFLAG_NO_CACHECLEAN))
		return;

	if (img->memory == M2M1SHOT2_BUFTYPE_USERPTR) {
		for (i = 0; i < img->num_planes; i++) {
			if (is_vma_cached(img->plane[i].userptr.vma))
				exynos_iommu_sync_for_device(ctx->m21dev->dev,
						img->plane[i].dma_addr,
						img->plane[i].payload, dir);
		}

		return;
	}

	if (img->memory != M2M1SHOT2_BUFTYPE_DMABUF)
		return;

	for (i = 0; i < img->num_planes; i++) {
		if (m2m1shot2_need_shareable_flush(
					img->plane[i].dmabuf.dmabuf, true))
			exynos_ion_flush_dmabuf_for_device(ctx->m21dev->dev,
				img->plane[i].dmabuf.dmabuf,
				img->plane[i].payload);
		else
			exynos_ion_sync_dmabuf_for_device(ctx->m21dev->dev,
				img->plane[i].dmabuf.dmabuf,
				img->plane[i].payload, dir);
	}
}

static void m2m1shot2_cachesync_images(struct m2m1shot2_context *ctx)
{
	int i;

	if (!!(ctx->m21dev->attr & M2M1SHOT2_DEVATTR_COHERENT) &&
			!test_bit(M2M1S2_CTXSTATE_CACHEFLUSH, &ctx->state))
		return;

	if (test_bit(M2M1S2_CTXSTATE_CACHECLEANALL, &ctx->state) ||
			test_bit(M2M1S2_CTXSTATE_CACHEFLUSHALL, &ctx->state)) {
		flush_all_cpu_caches();
		return;
	}

	for (i = 0; i < ctx->num_sources; i++)
		m2m1shot2_cachesync_image(ctx,
					  &ctx->source[i].img, DMA_TO_DEVICE);

	m2m1shot2_cachesync_image(ctx, &ctx->target, DMA_FROM_DEVICE);
}

static int m2m1shot2_map_images(struct m2m1shot2_context *ctx)
{
	unsigned int i;
	int ret;

	for (i = 0; i < ctx->num_sources; i++) {
		ret = m2m1shot2_map_image(ctx->m21dev,
					  &ctx->source[i].img, DMA_TO_DEVICE);
		if (ret) {
			while (i-- > 0)
				m2m1shot2_unmap_image(ctx->m21dev,
					&ctx->source[i].img, DMA_TO_DEVICE,
					true);
			return ret;
		}
	}

	ret = m2m1shot2_map_image(ctx->m21dev, &ctx->target, DMA_FROM_DEVICE);
	if (ret) {
		for (i = 0; i < ctx->num_sources; i++)
			m2m1shot2_unmap_image(ctx->m21dev,
				&ctx->source[i].img, DMA_TO_DEVICE, true);
	}

	return ret;
}

/*
 * m2m1shot2_wait_process() - wait until processing the context is finished
 *
 * This function should be called under ctx->mutex held.
 */
static bool m2m1shot2_wait_process(struct m2m1shot2_device *m21dev,
				   struct m2m1shot2_context *ctx)
{
	bool success = true;

	set_bit(M2M1S2_CTXSTATE_WAITING, &ctx->state);

	wait_for_completion(&ctx->complete);

	clear_bit(M2M1S2_CTXSTATE_WAITING, &ctx->state);

	if ((ctx->state & ((1 << M2M1S2_CTXSTATE_PENDING) |
				 (1 << M2M1S2_CTXSTATE_PROCESSING)))) {
		pr_err("m2m1shot finish state : %lx\n", ctx->state);
		BUG();
	}

	clear_bit(M2M1S2_CTXSTATE_PROCESSED, &ctx->state);

	if (test_bit(M2M1S2_CTXSTATE_ERROR, &ctx->state)) {
		success = false;
		clear_bit(M2M1S2_CTXSTATE_ERROR, &ctx->state);
	}

	m2m1shot2_unmap_images(ctx);

	return success;
}

static void m2m1shot2_schedule_context(struct m2m1shot2_context *ctx)
{
	struct m2m1shot2_device *m21dev = ctx->m21dev;
	unsigned long flags;

	del_timer(&ctx->timer);

	m2m1shot2_cachesync_images(ctx);

	spin_lock_irqsave(&ctx->m21dev->lock_ctx, flags);

	BUG_ON(list_empty(&ctx->node));

	/* move ctx from m21dev->contexts to m21dev->active_contexts */
	list_move_tail(&ctx->node, &ctx->m21dev->active_contexts);

	set_bit(M2M1S2_CTXSTATE_PROCESSING, &ctx->state);

	spin_unlock_irqrestore(&ctx->m21dev->lock_ctx, flags);

	__m2m1shot2_schedule(m21dev);
}

static void m2m1shot2_context_schedule_work(struct work_struct *work)
{
	m2m1shot2_schedule_context(
			container_of(work, struct m2m1shot2_context, work));
}

static void m2m1shot2_context_schedule_start(struct kref *kref)
{
	m2m1shot2_schedule_context(
			container_of(kref, struct m2m1shot2_context, starter));
}

static void m2m1shot2_schedule_queuework(struct kref *kref)
{
	struct m2m1shot2_context *ctx =
			container_of(kref, struct m2m1shot2_context, starter);
	bool failed;

	failed = !queue_work(ctx->m21dev->schedule_workqueue, &ctx->work);

	BUG_ON(failed);
}

/* NOTE that this function is called under irq disabled context */
static void m2m1shot2_fence_callback(struct sync_fence *fence,
					struct sync_fence_waiter *waiter)
{
	struct m2m1shot2_context_image *img =
		container_of(waiter, struct m2m1shot2_context_image, waiter);
	unsigned long ptr = (unsigned long)img;
	struct m2m1shot2_context *ctx;
	unsigned long flags;

	BUG_ON(img->index > M2M1SHOT2_MAX_IMAGES);

	ptr -= sizeof(struct m2m1shot2_source_image) * img->index;
	ptr -= offsetof(struct m2m1shot2_context, source);
	ctx = (struct m2m1shot2_context *)ptr;

	spin_lock_irqsave(&ctx->fence_timeout_lock, flags);

	/*
	 * m2m1shot2_timeout_handler() cancels waiters of all acquire fences and
	 * releases the fences. It should be avoided to release fences that are
	 * alreayd released in the timeout handler.
	 */
	if (!(img->flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE)) {
		spin_unlock_irqrestore(&ctx->fence_timeout_lock, flags);
		return;
	}

	img->flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
	sync_fence_put(img->fence);

	kref_put(&ctx->starter, m2m1shot2_schedule_queuework);

	spin_unlock_irqrestore(&ctx->fence_timeout_lock, flags);
}

static void m2m1shot2_timeout_handler(unsigned long arg)
{
	struct m2m1shot2_context *ctx = (struct m2m1shot2_context *)arg;
	struct m2m1shot2_source_image *image = ctx->source;
	struct m2m1shot2_context_image *timeout_image[M2M1SHOT2_MAX_IMAGES + 1];
	unsigned long flags;
	char name[32];
	int i, j = 0;

	pr_err("%s: %d Fence(s) timed out after %d msec.\n", __func__,
		atomic_read(&ctx->starter.refcount), M2M1S2_TIMEOUT_INTERVAL);

	for (i = 0; i < ctx->num_sources; i++) {
		if (image[i].img.fence) {
			memcpy(name, image[i].img.fence->name, sizeof(name));
			name[sizeof(name) - 1] = '\0';
			pr_err("%s:    SOURCE[%d]: [%p] %s\n",
				__func__, i, image[i].img.fence, name);
		}
	}

	if (ctx->target.fence) {
		memcpy(name, ctx->target.fence->name,  sizeof(name));
		name[sizeof(name) - 1] = '\0';
		pr_err("%s:    TARGET:    [%p] %s\n",
			__func__, ctx->target.fence, name);
	}

	if (ctx->release_fence)
		pr_err("%s:    Pending release fence: %p\n",
			__func__, ctx->release_fence);

	sync_dump();

	/*
	 * Give up waiting the acquire fences that are not currently signaled
	 * and force pushing this pending task to the H/W to avoid indefinite
	 * wait for the fences to be signaled.
	 * The spinlock is required to prevent racing about releasing the
	 * acqure fences between this time handler and the fence callback.
	 */
	spin_lock_irqsave(&ctx->fence_timeout_lock, flags);

	/*
	 * Make sure if there is really a unsigned fences. ctx->starter is
	 * decremented under fence_timeout_lock held if it is done by fence
	 * signal.
	*/
	if (atomic_read(&ctx->starter.refcount) == 0) {
		spin_unlock_irqrestore(&ctx->fence_timeout_lock, flags);
		pr_err("All fences have been signaled. (work_busy? %d)\n",
			work_busy(&ctx->work));
		/* If this happens, there is racing between
		 * m2m1shot2_timeout_handler() and m2m1shot2_schedule_queuework.
		 * Once m2m1shot2_schedule_queuework is invoked,
		 * it is guaranteed that the context is to be schduled to H/W.
		 */
		return;
	}

	for (i = 0; i < ctx->num_sources; i++) {
		if (image[i].img.flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE) {
			image[i].img.flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
			timeout_image[j++] = &image[i].img;
		}
	}

	if (!!(ctx->target.flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE)) {
		ctx->target.flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
		timeout_image[j++] = &ctx->target;
	}

	/* Increase reference to prevent running the workqueue in callback */
	kref_get(&ctx->starter);

	spin_unlock_irqrestore(&ctx->fence_timeout_lock, flags);
	
	while (j-- > 0) {
		sync_fence_cancel_async(timeout_image[j]->fence,
					&timeout_image[j]->waiter);
		sync_fence_put(timeout_image[j]->fence);
	}

	m2m1shot2_schedule_queuework(&ctx->starter);
};

/**
 * m2m1shot2_start_context() - add a context to the queue
 *
 * Given a valid context ready for processing, add it to
 * m2m1shot2_device.active_list that is the queue of ready contexts.
 * The state of the given context becomes PROCESSING|PENDING.
 * Then pick the next context to process from the queue. If there was no context
 * in the queue before this function call, the given context will be pick for
 * the context to process.
 */
static void m2m1shot2_start_context(struct m2m1shot2_device *m21dev,
				    struct m2m1shot2_context *ctx)
{
	int refcount;

	m2m1shot2_map_images(ctx);

	INIT_WORK(&ctx->work, m2m1shot2_context_schedule_work);

	reinit_completion(&ctx->complete);

	clear_bit(M2M1S2_CTXSTATE_PROCESSED, &ctx->state);
	set_bit(M2M1S2_CTXSTATE_PENDING, &ctx->state);
	/*
	 * if there is no fence to wait for, workqueue is not used to push a
	 * task
	 */
	refcount = atomic_read(&ctx->starter.refcount);
	if (refcount > 1)
		mod_timer(&ctx->timer,
			jiffies + msecs_to_jiffies(M2M1S2_TIMEOUT_INTERVAL));

	kref_put(&ctx->starter, m2m1shot2_schedule_queuework);
}

void m2m1shot2_finish_context(struct m2m1shot2_context *ctx, bool success)
{
	__m2m1shot2_finish_context(ctx, success);
}

void m2m1shot2_schedule(struct m2m1shot2_device *m21dev)
{
	__m2m1shot2_schedule(m21dev);
}

static void m2m1shot2_cancel_context(struct m2m1shot2_context *ctx)
{
	unsigned long flags;

	/*
	 * wait until the H/W finishes the processing about the context if
	 * the context is being serviced by H/W. This should be the only waiter
	 * for the context. If nothing is to be waited for,
	 * m2m1shot2_wait_process() returns immediately.
	 */
	m2m1shot2_wait_process(ctx->m21dev, ctx);

	/*
	 * this context is added to m2m1shot2_device.contexts by
	 * m2m1shot2_finish_context() called by the client device driver
	 */
	spin_lock_irqsave(&ctx->m21dev->lock_ctx, flags);
	BUG_ON(list_empty(&ctx->node));
	list_del_init(&ctx->node);
	spin_unlock_irqrestore(&ctx->m21dev->lock_ctx, flags);

	/* signal all possible release fences */
	sw_sync_timeline_inc(ctx->timeline, 1);

	/* to confirm if no reference to a resource exists */
	if (!!(ctx->flags & M2M1SHOT2_FLAG_NONBLOCK))
		m2m1shot2_put_images(ctx);

	WARN(!M2M1S2_CTXSTATE_IDLE(ctx),
		"state should be IDLE but %#lx\n", ctx->state);
}

static void m2m1shot2_destroy_context(struct work_struct *work)
{
	struct m2m1shot2_context *ctx =
		container_of(work, struct m2m1shot2_context, dwork);

	mutex_lock(&ctx->mutex);

	m2m1shot2_cancel_context(ctx);

	sync_timeline_destroy(&ctx->timeline->obj);

	spin_lock(&ctx->m21dev->lock_priority);
	ctx->m21dev->prior_stats[ctx->priority] -= 1;
	spin_unlock(&ctx->m21dev->lock_priority);

	if (ctx->m21dev->ops->prepare_perf)
		ctx->m21dev->ops->prepare_perf(ctx, NULL);

	ctx->m21dev->ops->free_context(ctx);

	mutex_unlock(&ctx->mutex);

	kfree(ctx);
}

/*
 * m2m1shot2_release() may be called during the context to be destroyed is ready
 * for processing or currently waiting for completion of processing due to the
 * non-blocking interface. Therefore it should remove the context from
 * m2m1shot2_device.active_contexts if the context is in the list. If it is
 * currently being processed by H/W, this function should wait until the H/W
 * finishes.
 */
static int m2m1shot2_release(struct inode *inode, struct file *filp)
{
	struct m2m1shot2_context *ctx = filp->private_data;

	INIT_WORK(&ctx->dwork, m2m1shot2_destroy_context);
	/* always success */
	queue_work(ctx->m21dev->destroy_workqueue, &ctx->dwork);

	return 0;
}

static int m2m1shot2_get_userptr(struct m2m1shot2_device *m21dev,
				 struct m2m1shot2_dma_buffer *plane,
				 unsigned long addr, u32 length,
				 enum dma_data_direction dir)
{
	unsigned long end = addr + length;
	struct vm_area_struct *vma;
	struct vm_area_struct *tvma;
	struct mm_struct *mm;
	int ret = -EINVAL;
	int prot = IOMMU_READ;

	/*
	 * release the previous buffer whatever the userptr is previously used.
	 * the pages mapped to the given user addr can be different even though
	 * the user addr is the same if the addr is mmapped again.
	 */
	if (plane->userptr.vma != NULL)
		m2m1shot2_put_userptr(m21dev->dev, plane);

	mm = get_task_mm(current);

	down_read(&mm->mmap_sem);

	vma = find_vma(mm, addr);
	if (!vma || (addr < vma->vm_start)) {
		dev_err(m21dev->dev,
			"%s: invalid address %#lx\n", __func__, addr);
		goto err_novma;
	}

	tvma = kmemdup(vma, sizeof(*vma), GFP_KERNEL);
	if (!tvma) {
		dev_err(m21dev->dev, "%s: failed to allocate vma\n", __func__);
		ret = -ENOMEM;
		goto err_novma;
	}

	if (dir != DMA_TO_DEVICE)
		prot |= IOMMU_WRITE;
	if (is_vma_cached(vma) && !!(m21dev->attr & M2M1SHOT2_DEVATTR_COHERENT))
		prot |= IOMMU_CACHE;

	plane->userptr.vma = tvma;

	tvma->vm_next = NULL;
	tvma->vm_prev = NULL;
	tvma->vm_mm = mm;

	while (end > vma->vm_end) {
		if (!!(vma->vm_flags & VM_PFNMAP)) {
			dev_err(m21dev->dev,
				"%s: non-linear pfnmap is not supported\n",
				__func__);
			goto err_vma;
		}

		if ((vma->vm_next == NULL) ||
				(vma->vm_end != vma->vm_next->vm_start)) {
			dev_err(m21dev->dev, "%s: invalid size %u\n",
					__func__, length);
			goto err_vma;
		}

		vma = vma->vm_next;
		tvma->vm_next = kmemdup(vma, sizeof(*vma), GFP_KERNEL);
		if (tvma->vm_next == NULL) {
			dev_err(m21dev->dev, "%s: failed to allocate vma\n",
				__func__);
			ret = -ENOMEM;
			goto err_vma;
		}
		tvma->vm_next->vm_prev = tvma;
		tvma->vm_next->vm_next = NULL;
		tvma = tvma->vm_next;
	}

	for (vma = plane->userptr.vma; vma != NULL; vma = vma->vm_next) {
		if (vma->vm_file)
			get_file(vma->vm_file);
		if (vma->vm_ops && vma->vm_ops->open)
			vma->vm_ops->open(vma);
	}

	plane->dma_addr = exynos_iovmm_map_userptr(
				m21dev->dev, addr, length, prot);
	if (IS_ERR_VALUE(plane->dma_addr))
		goto err_map;

	up_read(&mm->mmap_sem);

	plane->userptr.addr = addr;
	plane->userptr.length = length;

	return 0;
err_map:
	plane->dma_addr = 0;

	for (vma = plane->userptr.vma; vma != NULL; vma = vma->vm_next) {
		if (vma->vm_file)
			fput(vma->vm_file);
		if (vma->vm_ops && vma->vm_ops->close)
			vma->vm_ops->close(vma);
	}
err_vma:
	while (tvma) {
		vma = tvma;
		tvma = tvma->vm_prev;
		kfree(vma);
	}

	plane->userptr.vma = NULL;
err_novma:
	up_read(&mm->mmap_sem);

	mmput(mm);

	return ret;
}

static int m2m1shot2_get_dmabuf(struct m2m1shot2_device *m21dev,
				struct m2m1shot2_dma_buffer *plane,
				int fd, u32 off, size_t payload,
				enum dma_data_direction dir)
{
	struct dma_buf *dmabuf = dma_buf_get(fd);
	int ret = -EINVAL;
	int prot = IOMMU_READ;

	if (IS_ERR(dmabuf)) {
		dev_err(m21dev->dev, "%s: failed to get dmabuf from fd %d\n",
			__func__, fd);
		return PTR_ERR(dmabuf);
	}

	if (dmabuf->size < off) {
		dev_err(m21dev->dev,
			"%s: too large offset %u for dmabuf of %zu\n",
			__func__, off, dmabuf->size);
		goto err;
	}

	if ((dmabuf->size - off) < payload) {
		dev_err(m21dev->dev,
			"%s: too small dmabuf %zu/%u but reqiured %zu\n",
			__func__, dmabuf->size, off, payload);
		goto err;
	}

	if ((dmabuf == plane->dmabuf.dmabuf) &&
			(dmabuf->size == plane->dmabuf.dmabuf->size) &&
				(dmabuf->file == plane->dmabuf.dmabuf->file)) {
		/* do not attach dmabuf again for the same buffer */
		dma_buf_put(dmabuf);
		return 0;
	}

	if (dir != DMA_TO_DEVICE)
		prot |= IOMMU_WRITE;
	if (!!(m21dev->attr & M2M1SHOT2_DEVATTR_COHERENT))
		prot |= IOMMU_CACHE;

	/* release the previous buffer */
	if (plane->dmabuf.dmabuf != NULL)
		m2m1shot2_put_dmabuf(plane);

	plane->dmabuf.attachment = dma_buf_attach(dmabuf, m21dev->dev);
	if (IS_ERR(plane->dmabuf.attachment)) {
		dev_err(m21dev->dev,
			"%s: failed to attach to dmabuf\n", __func__);
		ret = PTR_ERR(plane->dmabuf.attachment);
		goto err;
	}

	/* NOTE: ion_iovmm_map() ignores offset in the second argument */
	plane->dma_addr = ion_iovmm_map(plane->dmabuf.attachment,
					0, payload, dir, prot);
	if (IS_ERR_VALUE(plane->dma_addr))
		goto err_map;

	plane->dmabuf.dmabuf = dmabuf;
	plane->dma_addr += off;

	return 0;
err_map:
	dma_buf_detach(dmabuf, plane->dmabuf.attachment);
	plane->dma_addr = 0;
	plane->dmabuf.attachment = NULL;
err:
	dma_buf_put(dmabuf);
	return ret;
}

static int m2m1shot2_get_buffer(struct m2m1shot2_context *ctx,
				struct m2m1shot2_context_image *img,
				struct m2m1shot2_image *src,
				size_t payload[],
				enum dma_data_direction dir)
{
	unsigned int num_planes = src->num_planes;
	int ret = 0;
	unsigned int i;

	if (src->memory != img->memory)
		m2m1shot2_put_buffer(ctx, img->memory,
					img->plane, img->num_planes);

	img->memory = M2M1SHOT2_BUFTYPE_NONE;

	if (src->memory == M2M1SHOT2_BUFTYPE_DMABUF) {
		for (i = 0; i < src->num_planes; i++) {
			ret = m2m1shot2_get_dmabuf(ctx->m21dev,
					&img->plane[i], src->plane[i].fd,
					src->plane[i].offset, payload[i], dir);
			if (ret) {
				while (i-- > 0)
					m2m1shot2_put_dmabuf(&img->plane[i]);
				return ret;
			}

			img->plane[i].payload = payload[i];

			if (!(img->flags & M2M1SHOT2_IMGFLAG_NO_CACHECLEAN) &&
				ion_cached_needsync_dmabuf(
					img->plane[i].dmabuf.dmabuf) > 0)
				ctx->ctx_private += img->plane[i].payload;
			if (m2m1shot2_need_shareable_flush(
						img->plane[i].dmabuf.dmabuf, false))
				ctx->ctx_private2 += img->plane[i].payload;
		}
	} else if (src->memory == M2M1SHOT2_BUFTYPE_USERPTR) {
		for (i = 0; i < src->num_planes; i++) {
			if (src->plane[i].offset != 0) {
				dev_err(ctx->m21dev->dev,
					"%s: offset should be 0 with userptr\n",
					__func__);
				ret = -EINVAL;
			} else {
				ret = m2m1shot2_get_userptr(ctx->m21dev,
					&img->plane[i], src->plane[i].userptr,
					src->plane[i].length, dir);
			}

			if (ret) {
				while (i-- > 0)
					m2m1shot2_put_userptr(ctx->m21dev->dev,
								&img->plane[i]);
				return ret;
			}

			img->plane[i].payload = payload[i];

			if (!(img->flags & M2M1SHOT2_IMGFLAG_NO_CACHECLEAN) &&
				is_vma_cached(img->plane[i].userptr.vma))
				ctx->ctx_private += img->plane[i].payload;
		}
	} else {
		dev_err(ctx->m21dev->dev,
			"%s: invalid memory type %d\n", __func__, src->memory);
		return -EINVAL;
	}

	img->num_planes = num_planes;
	img->memory = src->memory;

	return 0;
}

/*
 * check fence_count fences configured in the previous images in the same
 * context. If it does not find the same fence with the given, register the
 * fence waiter.
 * If registering the fence waiter for an unique fence fails, it releases it
 * immediately. The caller should handle the case.
 *
 */
static bool m2m1shot2_check_fence_wait(struct m2m1shot2_context *ctx,
					unsigned int fence_count,
					struct sync_fence *fence,
					struct sync_fence_waiter *waiter)
{
	unsigned int i;
	int ret;

	for (i = 0; i < fence_count; i++) {
		if (ctx->source[i].img.fence == fence)
			return false;
	}

	/*
	 * Always increase ctx->starter before sync_fence_wait_async().
	 * If waiter registration is failed (ret < 0)
	 * or already signaled (ret == 1). it will be just decreased.
	 */
	kref_get(&ctx->starter);
	ret = sync_fence_wait_async(fence, waiter);
	if (ret < 0 || ret == 1) {
		if (ret < 0)
			dev_err(ctx->m21dev->dev,
					"Error occurred in an acquire fence\n");
		kref_put(&ctx->starter, m2m1shot2_context_schedule_start);
		sync_fence_put(fence);
		return false;
	}

	return true;
}

static int m2m1shot2_get_source(struct m2m1shot2_context *ctx,
				unsigned int index,
				struct m2m1shot2_source_image *img,
				struct m2m1shot2_image *src)
{
	struct device *dev = ctx->m21dev->dev;
	size_t payload[M2M1SHOT2_MAX_PLANES];
	unsigned int i, num_planes;
	int ret;

	if (!M2M1SHOT2_BUFTYPE_VALID(src->memory)) {
		dev_err(dev,
			"%s: invalid memory type %u specified for image %u\n",
			__func__, src->memory, index);
		return -EINVAL;
	}

	img->img.fmt.fmt = src->fmt;
	img->img.flags = src->flags;
	img->ext = src->ext;
	img->img.fmt.colorspace = src->colorspace;

	ret = ctx->m21dev->ops->prepare_format(&img->img.fmt, index,
				DMA_TO_DEVICE, payload, &num_planes);
	if (ret) {
		dev_err(dev, "%s: invalid format specified for image %u\n",
			__func__, index);
		return ret;
	}

	if (src->memory == M2M1SHOT2_BUFTYPE_EMPTY) {
		m2m1shot2_put_image(ctx, &img->img);
		img->img.memory = src->memory;
		img->img.num_planes = 0;
		/* no buffer, no fence */
		img->img.flags &= ~(M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE |
					M2M1SHOT2_IMGFLAG_RELEASE_FENCE);
		return 0;
	}

	BUG_ON((num_planes < 1) || (num_planes > M2M1SHOT2_MAX_PLANES));

	if (num_planes != src->num_planes) {
		dev_err(dev, "%s: wrong number of planes %u of image %u.\n",
			__func__, src->num_planes, index);
		return -EINVAL;
	}

	for (i = 0; i < num_planes; i++) {
		if (src->plane[i].length < payload[i]) {
			dev_err(dev,
				"%s: too small size %u (plane %u / image %u)\n",
				__func__, src->plane[i].length, i, index);
			return -EINVAL;
		}
	}

	return m2m1shot2_get_buffer(ctx, &img->img,
				    src, payload, DMA_TO_DEVICE);
}

static int m2m1shot2_get_sources(struct m2m1shot2_context *ctx,
				 struct m2m1shot2_image __user *usersrc,
				 bool blocking)
{
	struct device *dev = ctx->m21dev->dev;
	struct m2m1shot2_source_image *image = ctx->source;
	unsigned int i;
	int ret;

	for (i = 0; i < ctx->num_sources; i++, usersrc++) {
		struct m2m1shot2_image source;

		if (copy_from_user(&source, usersrc, sizeof(source))) {
			dev_err(dev,
				"%s: Failed to read source[%u] image data\n",
				__func__, i);
			ret = -EFAULT;
			goto err;
		}

		/* blocking mode does not allow fences */
		if (blocking && !!(source.flags & M2M1SHOT2_FENCE_MASK)) {
			dev_err(dev, "%s: fence set for blocking mode\n",
				__func__);
			ret = -EINVAL;
			goto err;
		}

		ret = m2m1shot2_get_source(ctx, i, &image[i], &source);
		if (ret)
			goto err;

		ret = ctx->m21dev->ops->prepare_source(ctx, i, &image[i]);
		if (ret) {
			m2m1shot2_put_image(ctx, &image[i].img);
			goto err;
		}

		image[i].img.fence = NULL;

		if (!!(image[i].img.flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE)) {
			image[i].img.fence = sync_fence_fdget(source.fence);
			if (image[i].img.fence == NULL) {
				dev_err(dev, "%s: invalid acquire fence %d\n",
					__func__, source.fence);
				ret = -EINVAL;
				image[i].img.flags &=
					~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
				m2m1shot2_put_image(ctx, &image[i].img);
				goto err;
			}

			if (!m2m1shot2_check_fence_wait(ctx, i,
						image[i].img.fence,
						&image[i].img.waiter))
				image[i].img.flags &=
					~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
		}
	}

	return 0;
err:
	while (i-- > 0)
		m2m1shot2_put_image(ctx, &ctx->source[i].img);

	ctx->num_sources = 0;

	return ret;

}

static struct sync_fence *m2m1shot2_create_fence(struct m2m1shot2_context *ctx)
{
	struct device *dev = ctx->m21dev->dev;
	struct sync_fence *fence;
	struct sync_pt *pt;

	pt = sw_sync_pt_create(ctx->timeline, ctx->timeline_max + 1);
	if (!pt) {
		dev_err(dev,
			"%s: failed to create sync_pt\n", __func__);
		return NULL;
	}

	fence = sync_fence_create("m2m1shot2", pt);
	if (!fence) {
		dev_err(dev, "%s: failed to create fence\n", __func__);
		sync_pt_free(pt);
	}

	return fence;
}

static int m2m1shot2_get_target(struct m2m1shot2_context *ctx,
				struct m2m1shot2_image *dst)
{
	struct device *dev = ctx->m21dev->dev;
	struct m2m1shot2_context_image *img = &ctx->target;
	size_t payload[M2M1SHOT2_MAX_PLANES];
	unsigned int i, num_planes;
	int ret;

	if (!M2M1SHOT2_BUFTYPE_VALID(dst->memory)) {
		dev_err(dev,
			"%s: invalid memory type %u specified for target\n",
			__func__, dst->memory);
		return -EINVAL;
	}

	if (dst->memory == M2M1SHOT2_BUFTYPE_EMPTY) {
		dev_err(dev,
			"%s: M2M1SHOT2_BUFTYPE_EMPTY is not valid for target\n",
			__func__);
		return -EINVAL;
	}

	img->fmt.fmt = dst->fmt;
	img->fmt.colorspace = dst->colorspace;

	/*
	 * The client driver may configure 0 to payload if it is not able to
	 * determine the payload before image processing especially when the
	 * result is a compressed data
	 */
	ret = ctx->m21dev->ops->prepare_format(&img->fmt, 0,
				DMA_FROM_DEVICE, payload, &num_planes);
	if (ret) {
		dev_err(dev, "%s: invalid format specified for target\n",
			__func__);
		return ret;
	}

	BUG_ON((num_planes < 1) || (num_planes > M2M1SHOT2_MAX_PLANES));

	if (num_planes != dst->num_planes) {
		dev_err(dev, "%s: wrong number of planes %u for target\n",
			__func__, dst->num_planes);
		return -EINVAL;
	}

	for (i = 0; i < num_planes; i++) {
		if ((payload[i] != 0) && (dst->plane[i].length < payload[i])) {
			dev_err(dev,
				"%s: too small size %u (plane %u)\n",
				__func__, dst->plane[i].length, i);
			return -EINVAL;
		}
	}

	ret = m2m1shot2_get_buffer(ctx, img, dst, payload, DMA_FROM_DEVICE);
	if (ret)
		return ret;

	img->flags = dst->flags;
	img->fence = NULL;

	if (!!(img->flags & M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE)) {
		img->fence = sync_fence_fdget(dst->fence);
		if (img->fence == NULL) {
			dev_err(dev, "%s: invalid acquire fence %d\n",
				__func__, dst->fence);
			img->flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
			m2m1shot2_put_buffer(ctx, dst->memory,
						img->plane, img->num_planes);
			return -EINVAL;
		}

		if (!m2m1shot2_check_fence_wait(ctx, ctx->num_sources,
					   img->fence, &img->waiter))
			img->flags &= ~M2M1SHOT2_IMGFLAG_ACQUIRE_FENCE;
	}

	return 0;
}

static int m2m1shot2_get_userdata(struct m2m1shot2_context *ctx,
				  struct m2m1shot2 *data)
{
	struct device *dev = ctx->m21dev->dev;
	struct m2m1shot2_image __user *usersrc = data->sources;
	unsigned int len_src, len_dst;
	bool blocking;
	int ret;

	if ((data->num_sources < 1) ||
			(data->num_sources > M2M1SHOT2_MAX_IMAGES)) {
		dev_err(dev, "%s: Invalid number of source images %u\n",
			__func__, data->num_sources);
		return -EINVAL;
	}

	blocking = !(data->flags & M2M1SHOT2_FLAG_NONBLOCK);

	while (ctx->num_sources > data->num_sources) {
		ctx->num_sources--;
		m2m1shot2_put_image(ctx, &ctx->source[ctx->num_sources].img);
	}

	ctx->ctx_private = 0;
	ctx->ctx_private2 = 0;
	ctx->num_sources = data->num_sources;
	ctx->flags = data->flags;

	ret = m2m1shot2_get_sources(ctx, usersrc, blocking);
	if (ret)
		return ret;

	if (blocking && !!(data->target.flags & M2M1SHOT2_FENCE_MASK)) {
		dev_err(dev, "%s: fence set for blocking mode\n", __func__);
		ret = -EINVAL;
		goto err;
	}

	len_src = ctx->ctx_private;

	ret = m2m1shot2_get_target(ctx, &data->target);
	if (ret)
		goto err;

	ret = ctx->m21dev->ops->prepare_target(ctx, &ctx->target);
	if (ret)
		goto err;

	len_dst = ctx->ctx_private - len_src;

	if (ctx->ctx_private < M2M1SHOT2_NEED_CACHEFLUSH_ALL)
		clear_bit(M2M1S2_CTXSTATE_CACHECLEANALL, &ctx->state);
	else
		set_bit(M2M1S2_CTXSTATE_CACHECLEANALL, &ctx->state);

	if (ctx->ctx_private2 > 0)
		set_bit(M2M1S2_CTXSTATE_CACHEFLUSH, &ctx->state);
	else
		clear_bit(M2M1S2_CTXSTATE_CACHEFLUSH, &ctx->state);

	if (ctx->ctx_private2 < M2M1SHOT2_NEED_CACHEFLUSH_ALL)
		clear_bit(M2M1S2_CTXSTATE_CACHEFLUSHALL, &ctx->state);
	else
		set_bit(M2M1S2_CTXSTATE_CACHEFLUSHALL, &ctx->state);

	if (!(ctx->target.flags & M2M1SHOT2_IMGFLAG_NO_CACHEINV) &&
				(len_dst < M2M1SHOT2_NEED_CACHEFLUSH_ALL))
		clear_bit(M2M1S2_CTXSTATE_CACHEINVALALL, &ctx->state);
	else
		set_bit(M2M1S2_CTXSTATE_CACHEINVALALL, &ctx->state);

	return 0;
err:
	m2m1shot2_put_source_images(ctx);
	return ret;
}

static int m2m1shot2_install_fence(struct m2m1shot2_context *ctx,
				   struct sync_fence *fence,
				   s32 __user *pfd)
{
	int fd = get_unused_fd_flags(O_CLOEXEC);

	if (fd < 0) {
		dev_err(ctx->m21dev->dev, "%s: failed to allocated unused fd\n",
			__func__);
		return fd;
	}

	if (put_user(fd, pfd)) {
		dev_err(ctx->m21dev->dev,
			"%s: failed to put release fence to user\n", __func__);
		put_unused_fd(fd);
		return -EFAULT;
	}

	sync_fence_install(fence, fd);

	return fd;
}

static int m2m1shot2_create_release_fence(struct m2m1shot2_context *ctx,
					struct m2m1shot2_image __user *usertgt,
					struct m2m1shot2_image __user usersrc[],
					unsigned int num_sources)
{
	struct sync_fence *fence = NULL;
	struct m2m1shot2_context_image *img;
	unsigned int i, ifd = 0;
	int fds[M2M1SHOT2_MAX_IMAGES + 1];
	unsigned int num_fences = 0;
	int ret = 0;

	if (!!(ctx->target.flags & M2M1SHOT2_IMGFLAG_RELEASE_FENCE))
		num_fences++;

	for (i = 0; i < ctx->num_sources; i++) {
		if (!!(ctx->source[i].img.flags &
					M2M1SHOT2_IMGFLAG_RELEASE_FENCE))
			num_fences++;
	}

	if (num_fences == 0)
		return 0;

	fence = m2m1shot2_create_fence(ctx);
	if (!fence)
		return -ENOMEM;

	for (i = 0; i < ctx->num_sources; i++) {
		img = &ctx->source[i].img;
		if (!!(img->flags & M2M1SHOT2_IMGFLAG_RELEASE_FENCE)) {
			ret = m2m1shot2_install_fence(ctx,
					fence, &usersrc[i].fence);
			if (ret < 0)
				goto err;

			get_file(fence->file);
			fds[ifd++] = ret;
		}
	}

	img = &ctx->target;
	if (!!(ctx->target.flags & M2M1SHOT2_IMGFLAG_RELEASE_FENCE)) {
		ret = m2m1shot2_install_fence(ctx, fence,
						&usertgt->fence);
		if (ret < 0)
			goto err;

		get_file(fence->file);
		fds[ifd++] = ret;
	}

	/* release a reference of the fence that is increased on creation */
	sync_fence_put(fence);

	ctx->timeline_max++;
	ctx->release_fence = fence;

	return 0;
err:
	while (ifd-- > 0) {
		put_unused_fd(fds[ifd]);
		sync_fence_put(fence);
	}

	sync_fence_put(fence);

	return ret;
}

static int m2m1shot2_wait_put_user(struct m2m1shot2_context *ctx,
				   struct m2m1shot2 __user *uptr, u32 userflag)
{
	int ret = 0;

	if (!m2m1shot2_wait_process(ctx->m21dev, ctx)) {
		userflag |= M2M1SHOT2_FLAG_ERROR;
		ret = put_user(userflag, &uptr->flags);
	} else {
		unsigned int i;

		for (i = 0; i < ctx->target.num_planes; i++)
			ret = put_user(ctx->target.plane[i].payload,
					&uptr->target.plane[i].payload);
		put_user(ctx->work_delay_in_nsec, &uptr->work_delay_in_nsec);
	}

	return ret;
}

/*
 * find the previous requested context which has lower priority.
 * if it find that context, we have to return error to avoid
 * for the higher context to wait finishing the lower context job
 */
static int m2m1shot2_prepare_priority_context(struct m2m1shot2_context *ctx)
{
	struct m2m1shot2_device *m21dev = ctx->m21dev;
	struct m2m1shot2_context *pctx;
	unsigned long flags;
	int cond = ctx->priority;

	spin_lock_irqsave(&m21dev->lock_ctx, flags);
	list_for_each_entry(pctx, &m21dev->active_contexts, node) {
		if (pctx->priority < cond)
			goto err_busy;
	}

	list_for_each_entry(pctx, &m21dev->contexts, node) {
		if ((pctx->priority < cond) && M2M1S2_CTXSTATE_BUSY(pctx))
			goto err_busy;
	}

	pctx = m2m1shot2_current_context(m21dev);
	if (pctx && (pctx->priority < cond))
		goto err_busy;

	spin_unlock_irqrestore(&m21dev->lock_ctx, flags);

	return 0;

err_busy:
	spin_unlock_irqrestore(&m21dev->lock_ctx, flags);

	return -EBUSY;
}

static long m2m1shot2_ioctl(struct file *filp,
			    unsigned int cmd, unsigned long arg)
{
	struct m2m1shot2_context *ctx = filp->private_data;
	struct m2m1shot2_device *m21dev = ctx->m21dev;
	int ret = 0;

	mutex_lock(&ctx->mutex);

	switch (cmd) {
	case M2M1SHOT2_IOC_REQUEST_PERF:
	{
		struct m2m1shot2_performance_data data;
		int i;

		if (!ctx->m21dev->ops->prepare_perf) {
			dev_err(ctx->m21dev->dev,
				"%s: it doesn't exist the prepare performance\n", __func__);
			ret = -ENOTTY;
			break;
		}

		if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
			dev_err(ctx->m21dev->dev,
				"%s: Failed to performance data\n", __func__);
			ret = -EFAULT;
			break;
		}

		if (data.num_frames >= M2M1SHOT2_PERF_MAX_FRAMES) {
			ret = -EINVAL;
			break;
		}

		for (i = 0; i < data.num_frames; i++) {
			if (data.frame[i].num_layers >= M2M1SHOT2_MAX_IMAGES) {
				ret = -EINVAL;
				break;
			}
		}
		if (!ret)
			ret = ctx->m21dev->ops->prepare_perf(ctx, &data);

		break;
	}
	case M2M1SHOT2_IOC_SET_PRIORITY:
	{
		enum m2m1shot2_priority data;

		get_user(data, (enum m2m1shot2_priority __user *)arg);

		if ((data < M2M1SHOT2_LOW_PRIORITY) ||
					(data >= M2M1SHOT2_PRIORITY_END)) {
			dev_err(m21dev->dev,
				"%s: m2m1shot2 does not allow %d priority\n",
				__func__, data);
			ret = -EINVAL;
			break;
		}

		/* update current priority */
		if (data != ctx->priority) {
			spin_lock(&m21dev->lock_priority);
			m21dev->prior_stats[ctx->priority] -= 1;
			m21dev->prior_stats[data] += 1;
			ctx->priority = data;
			spin_unlock(&m21dev->lock_priority);
		}

		ret = m2m1shot2_prepare_priority_context(ctx);
		if (ret < 0)
			break;

		break;
	}
	case M2M1SHOT2_IOC_PROCESS:
	{
		struct m2m1shot2 __user *uptr = (struct m2m1shot2 __user *)arg;
		struct m2m1shot2 data;
		int i;

		if (copy_from_user(&data, uptr, sizeof(data))) {
			dev_err(ctx->m21dev->dev,
				"%s: Failed to read userdata\n", __func__);
			ret = -EFAULT;
			break;
		}

		/* wait for completion of the previous task */
		if (!M2M1S2_CTXSTATE_IDLE(ctx))
			m2m1shot2_wait_process(m21dev, ctx);

		/*
		 * A new process request with the lower priority than the
		 * heighest priority currently configured is not allowed
		 * to be executed and m2m1shot2 simply returns -EBUSY
		 */
		spin_lock(&m21dev->lock_priority);
		for (i = ctx->priority + 1; i < M2M1SHOT2_PRIORITY_END; i++) {
			if (m21dev->prior_stats[i] > 0)
				break;
		}
		spin_unlock(&m21dev->lock_priority);

		if (i < M2M1SHOT2_PRIORITY_END) {
			ret = -EBUSY;
			break;
		}

		kref_init(&ctx->starter);

		ret = m2m1shot2_get_userdata(ctx, &data);
		if (ret < 0)
			break;

		ctx->release_fence = NULL;
		if (!!(data.flags & M2M1SHOT2_FLAG_NONBLOCK)) {
			ret = m2m1shot2_create_release_fence(ctx, &uptr->target,
						data.sources, data.num_sources);
			if (ret < 0) {
				m2m1shot2_put_images(ctx);
				break;
			}
		}

		m2m1shot2_start_context(ctx->m21dev, ctx);

		if (!(data.flags & M2M1SHOT2_FLAG_NONBLOCK)) {
			ret = m2m1shot2_wait_put_user(ctx, uptr, data.flags);
			m2m1shot2_put_images(ctx);
		}

		break;
	}
	case M2M1SHOT2_IOC_WAIT_PROCESS:
	{
		struct m2m1shot2 __user *uptr = (void __user *)arg;
		struct m2m1shot2 data;

		if (M2M1S2_CTXSTATE_IDLE(ctx)) {
			ret = -EAGAIN;
			break;
		}

		if (copy_from_user(&data, uptr, sizeof(data))) {
			dev_err(ctx->m21dev->dev,
				"%s: Failed to read userdata\n", __func__);
			ret = -EFAULT;
			break;
		}

		ret = m2m1shot2_wait_put_user(ctx, uptr, data.flags);

		break;
	}
	case M2M1SHOT2_IOC_CUSTOM:
	{
		struct m2m1shot2_custom_data data;

		if (!ctx->m21dev->ops->custom_ioctl) {
			dev_err(ctx->m21dev->dev,
				"%s: it doesn't exist the custom ioctl\n", __func__);
			ret = -ENOTTY;
			break;
		}
		if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
			dev_err(ctx->m21dev->dev,
				"%s: Failed to read userdata\n", __func__);
			ret = -EFAULT;
			break;
		}
		ret = ctx->m21dev->ops->custom_ioctl(ctx, data.cmd, data.arg);
		break;
	}
	default:
	{
		dev_err(ctx->m21dev->dev,
			"%s: unknown ioctl command %#x\n", __func__, cmd);
		ret = -EINVAL;
		break;
	}
	} /* switch */

	mutex_unlock(&ctx->mutex);

	return ret;
}

#ifdef CONFIG_COMPAT
struct compat_m2m1shot2_buffer {
	union {
		compat_ulong_t	userptr;
		__s32		fd;
	};
	__u32		offset;
	__u32		length;
	__u32		payload;
	compat_ulong_t	reserved;
};

struct compat_m2m1shot2_image {
	__u32				flags;
	__s32				fence;
	__u8				memory;
	__u8				num_planes;
	struct compat_m2m1shot2_buffer	plane[M2M1SHOT2_MAX_PLANES];
	struct m2m1shot2_format		fmt;
	struct m2m1shot2_extra		ext;
	__u32				reserved[4];
};

struct compat_m2m1shot2 {
	compat_uptr_t			sources;
	struct compat_m2m1shot2_image	target;
	__u8				num_sources;
	__u32				flags;
	__u32				reserved1;
	__u32				reserved2;
	compat_ulong_t			work_delay_in_nsec;
	compat_ulong_t			reserved4;
};

#define COMPAT_M2M1SHOT2_IOC_PROCESS	  _IOWR('M', 4, struct compat_m2m1shot2)
#define COMPAT_M2M1SHOT2_IOC_WAIT_PROCESS _IOR('M', 5, struct compat_m2m1shot2)

static int m2m1shot2_compat_get_imagedata(struct device *dev,
				struct m2m1shot2_image __user *img,
				struct compat_m2m1shot2_image __user *cimg)
{
	__u32 uw;
	__s32 sw;
	__u8 b;
	compat_ulong_t l;
	unsigned int i;
	int ret;

	ret =  get_user(uw, &cimg->flags);
	ret |= put_user(uw, &img->flags);
	ret |= get_user(sw, &cimg->fence);
	ret |= put_user(sw, &img->fence);
	ret |= get_user(b, &cimg->memory);
	ret |= put_user(b, &img->memory);
	ret |= get_user(b, &cimg->num_planes);
	ret |= put_user(b, &img->num_planes);
	if (b > M2M1SHOT2_MAX_PLANES) {
		dev_err(dev, "%s: too many plane count %u\n", __func__, b);
		return -EINVAL;
	}
	for (i = 0; i < b; i++) { /* b contains num_planes */
		/* userptr is not smaller than fd */
		ret |= get_user(l, &cimg->plane[i].userptr);
		ret |= put_user(l, &img->plane[i].userptr);
		ret |= get_user(uw, &cimg->plane[i].offset);
		ret |= put_user(uw, &img->plane[i].offset);
		ret |= get_user(uw, &cimg->plane[i].length);
		ret |= put_user(uw, &img->plane[i].length);
		ret |= get_user(uw, &cimg->plane[i].payload);
		ret |= put_user(uw, &img->plane[i].payload);
		ret |= get_user(l, &cimg->plane[i].reserved);
		ret |= put_user(l, &img->plane[i].reserved);
	}

	ret |= copy_in_user(&img->fmt, &cimg->fmt,
			sizeof(struct m2m1shot2_format) +
			sizeof(struct m2m1shot2_extra) + sizeof(__u32) * 4);

	return ret ? -EFAULT : 0;
}

static int m2m1shot2_compat_put_imagedata(struct m2m1shot2_image __user *img,
				struct compat_m2m1shot2_image __user *cimg)
{
	__u32 uw;
	__s32 sw;
	__u8 b;
	compat_ulong_t l;
	unsigned int i;
	int ret;

	ret  = get_user(uw, &img->flags);
	ret |= put_user(uw, &cimg->flags);
	if (!!(uw & M2M1SHOT2_IMGFLAG_RELEASE_FENCE)) {
		ret |= get_user(sw, &img->fence);
		ret |= put_user(sw, &cimg->fence);
	}
	ret |= get_user(b, &img->num_planes);
	for (i = 0; i < b; i++) { /* b contains num_planes */
		ret |= get_user(uw, &img->plane[i].payload);
		ret |= put_user(uw, &cimg->plane[i].payload);
		ret |= get_user(l, &img->plane[i].reserved);
		ret |= put_user(l, &cimg->plane[i].reserved);
	}

	return ret;
}

static int m2m1shot2_compat_put_fence(struct m2m1shot2_image __user *img,
				struct compat_m2m1shot2_image __user *cimg)
{
	__u32 uw = 0;
	__s32 sw;
	int ret;

	ret =  get_user(uw, &img->flags);
	if (!!(uw & M2M1SHOT2_IMGFLAG_RELEASE_FENCE)) {
		ret |= get_user(sw, &img->fence);
		ret |= put_user(sw, &cimg->fence);
	}

	return ret;
}

static long m2m1shot2_compat_ioctl32(struct file *filp,
				unsigned int cmd, unsigned long arg)
{
	struct m2m1shot2_context *ctx = filp->private_data;
	struct device *dev = ctx->m21dev->dev;
	struct compat_m2m1shot2 __user *cdata = compat_ptr(arg);
	struct m2m1shot2 __user *data;
	struct m2m1shot2_image __user *src;
	int ret;
	compat_ulong_t l;
	compat_uptr_t sources;
	__u32 w;
	__u8 num_sources;

	switch (cmd) {
	case COMPAT_M2M1SHOT2_IOC_PROCESS:
		cmd = M2M1SHOT2_IOC_PROCESS;
		break;
	case COMPAT_M2M1SHOT2_IOC_WAIT_PROCESS:
		cmd = M2M1SHOT2_IOC_WAIT_PROCESS;
		break;
	case M2M1SHOT2_IOC_CUSTOM:
	case M2M1SHOT2_IOC_SET_PRIORITY:
	case M2M1SHOT2_IOC_REQUEST_PERF:
		if (!filp->f_op->unlocked_ioctl)
			return -ENOTTY;

		return filp->f_op->unlocked_ioctl(filp, cmd,
						(unsigned long)compat_ptr(arg));
	default:
		dev_err(dev, "%s: unknown ioctl command %#x\n", __func__, cmd);
		return -EINVAL;
	}

	data = compat_alloc_user_space(sizeof(*data));

	ret  = get_user(num_sources, &cdata->num_sources);
	ret |= put_user(num_sources, &data->num_sources);
	ret |= get_user(w, &cdata->flags);
	ret |= put_user(w, &data->flags);
	ret |= get_user(w, &cdata->reserved1);
	ret |= put_user(w, &data->reserved1);
	ret |= get_user(w, &cdata->reserved2);
	ret |= put_user(w, &data->reserved2);
	ret |= get_user(l, &cdata->work_delay_in_nsec);
	ret |= put_user(l, &data->work_delay_in_nsec);
	ret |= get_user(l, &cdata->reserved4);
	ret |= put_user(l, &data->reserved4);
	ret |= get_user(sources, &cdata->sources);
	if (ret) {
		dev_err(dev, "%s: failed to read m2m1shot2 data\n", __func__);
		return -EFAULT;
	}

	ret = m2m1shot2_compat_get_imagedata(
				dev, &data->target, &cdata->target);
	if (ret) {
		dev_err(dev, "%s: failed to read the target image data\n",
			__func__);
		return ret;
	}

	if (cmd == M2M1SHOT2_IOC_PROCESS) {
		struct compat_m2m1shot2_image __user *csc = compat_ptr(sources);

		src = compat_alloc_user_space(
				sizeof(*data) + sizeof(*src) * num_sources);
		if (w > M2M1SHOT2_MAX_IMAGES) {
			dev_err(dev, "%s: too many source images %u\n",
				__func__, w);
			return -EINVAL;
		}

		for (w = 0; w < num_sources; w++) {
			ret = m2m1shot2_compat_get_imagedata(
						dev, &src[w], &csc[w]);
			if (ret) {
				dev_err(dev,
				"%s: failed to read %dth source image data\n",
					__func__, w);
				return ret;
			}
		}


		if (put_user(src, &data->sources)) {
			dev_err(dev, "%s: failed to handle source image data\n",
				__func__);
			return -EFAULT;
		}
	}

	ret = m2m1shot2_ioctl(filp, cmd, (unsigned long)data);
	if (ret)
		return ret;

	ret  = get_user(w, &data->flags);
	ret |= put_user(w, &cdata->flags);
	ret |= get_user(w, &data->reserved1);
	ret |= put_user(w, &cdata->reserved1);
	ret |= get_user(w, &data->reserved2);
	ret |= put_user(w, &cdata->reserved2);
	ret |= get_user(l, &data->work_delay_in_nsec);
	ret |= put_user(l, &cdata->work_delay_in_nsec);
	ret |= get_user(l, &data->reserved4);
	ret |= put_user(l, &cdata->reserved4);
	ret |= m2m1shot2_compat_put_imagedata(&data->target, &cdata->target);

	if (cmd == M2M1SHOT2_IOC_PROCESS) {
		struct compat_m2m1shot2_image __user *csc = compat_ptr(sources);

		for (w = 0; w < num_sources; w++)
			ret |= m2m1shot2_compat_put_fence(&src[w], &csc[w]);
	}

	if (ret)
		dev_err(dev, "%s: failed to write userdata\n", __func__);

	return ret;
}
#endif

static const struct file_operations m2m1shot2_fops = {
	.owner          = THIS_MODULE,
	.open           = m2m1shot2_open,
	.release        = m2m1shot2_release,
	.unlocked_ioctl	= m2m1shot2_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= m2m1shot2_compat_ioctl32,
#endif
};

struct m2m1shot2_device *m2m1shot2_create_device(struct device *dev,
					const struct m2m1shot2_devops *ops,
					const char *nodename, int id,
					unsigned long attr)
{
	struct m2m1shot2_device *m21dev;
	char *name;
	size_t name_size;
	int ret = -ENOMEM;

	if (!ops || !ops->init_context || !ops->free_context ||
			!ops->prepare_format || !ops->device_run) {
		dev_err(dev,
			"%s: m2m1shot2_devops is insufficient\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	if (!nodename) {
		dev_err(dev, "%s: node name is not specified\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	name_size = strlen(nodename) + 1;

	if (id >= 0)
		name_size += 3; /* instance number: maximum 3 digits */

	name = kmalloc(name_size, GFP_KERNEL);
	if (!name)
		return ERR_PTR(-ENOMEM);

	if (id < 0)
		strncpy(name, nodename, name_size);
	else
		scnprintf(name, name_size, "%s%d", nodename, id);

	m21dev = kzalloc(sizeof(*m21dev), GFP_KERNEL);
	if (!m21dev)
		goto err_m21dev;

	m21dev->misc.minor = MISC_DYNAMIC_MINOR;
	m21dev->misc.name = name;
	m21dev->misc.fops = &m2m1shot2_fops;
	ret = misc_register(&m21dev->misc);
	if (ret)
		goto err_misc;

	m21dev->schedule_workqueue =
		create_singlethread_workqueue("m2m1shot2-scheduler");
	if (!m21dev->schedule_workqueue) {
		dev_err(dev, "failed to create workqueue for scheduling\n");
		ret = -ENOMEM;
		goto err_workqueue;
	}

	m21dev->destroy_workqueue =
		create_singlethread_workqueue("m2m1shot2-destructor");
	if (!m21dev->schedule_workqueue) {
		dev_err(dev, "failed to create workqueue for context destruction\n");
		ret = -ENOMEM;
		goto err_workqueue2;
	}

	spin_lock_init(&m21dev->lock_ctx);
	spin_lock_init(&m21dev->lock_priority);
	INIT_LIST_HEAD(&m21dev->contexts);
	INIT_LIST_HEAD(&m21dev->active_contexts);

	m21dev->dev = dev;
	m21dev->ops = ops;
	m21dev->attr = attr;

	dev_info(dev, "registered as m2m1shot2 device");

	return m21dev;
err_workqueue2:
	destroy_workqueue(m21dev->schedule_workqueue);
err_workqueue:
	misc_deregister(&m21dev->misc);
err_misc:
	kfree(m21dev);
err_m21dev:
	kfree(name);

	return ERR_PTR(ret);
}
EXPORT_SYMBOL(m2m1shot2_create_device);

void m2m1shot2_destroy_device(struct m2m1shot2_device *m21dev)
{
	destroy_workqueue(m21dev->destroy_workqueue);
	destroy_workqueue(m21dev->schedule_workqueue);
	misc_deregister(&m21dev->misc);
	kfree(m21dev->misc.name);
	kfree(m21dev);
	/* TODO: something forgot to release? */
}
EXPORT_SYMBOL(m2m1shot2_destroy_device);
