/*
 * Samsung S5P Multi Format Codec v 5.1
 *
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 * Kamil Debski, <k.debski@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <media/videobuf2-core.h>
#include "regs-mfc.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_dec.h"
#include "s5p_mfc_enc.h"
#include "s5p_mfc_intr.h"
#include "s5p_mfc_opr.h"
#include "s5p_mfc_pm.h"
#include "s5p_mfc_shm.h"

#define S5P_MFC_NAME		"s5p-mfc"
#define S5P_MFC_DEC_NAME	"s5p-mfc-dec"
#define S5P_MFC_ENC_NAME	"s5p-mfc-enc"

int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages");

/* Helper functions for interrupt processing */
/* Remove from hw execution round robin */
static void clear_work_bit(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev = ctx->dev;

	spin_lock(&dev->condlock);
	clear_bit(ctx->num, &dev->ctx_work_bits);
	spin_unlock(&dev->condlock);
}

/* Wake up context wait_queue */
static void wake_up_ctx(struct s5p_mfc_ctx *ctx, unsigned int reason,
			unsigned int err)
{
	ctx->int_cond = 1;
	ctx->int_type = reason;
	ctx->int_err = err;
	wake_up(&ctx->queue);
}

/* Wake up device wait_queue */
static void wake_up_dev(struct s5p_mfc_dev *dev, unsigned int reason,
			unsigned int err)
{
	dev->int_cond = 1;
	dev->int_type = reason;
	dev->int_err = err;
	wake_up(&dev->queue);
}

void s5p_mfc_watchdog(unsigned long arg)
{
	struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg;

	if (test_bit(0, &dev->hw_lock))
		atomic_inc(&dev->watchdog_cnt);
	if (atomic_read(&dev->watchdog_cnt) >= MFC_WATCHDOG_CNT) {
		/* This means that hw is busy and no interrupts were
		 * generated by hw for the Nth time of running this
		 * watchdog timer. This usually means a serious hw
		 * error. Now it is time to kill all instances and
		 * reset the MFC. */
		mfc_err("Time out during waiting for HW\n");
		queue_work(dev->watchdog_workqueue, &dev->watchdog_work);
	}
	dev->watchdog_timer.expires = jiffies +
					msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
	add_timer(&dev->watchdog_timer);
}

static void s5p_mfc_watchdog_worker(struct work_struct *work)
{
	struct s5p_mfc_dev *dev;
	struct s5p_mfc_ctx *ctx;
	unsigned long flags;
	int mutex_locked;
	int i, ret;

	dev = container_of(work, struct s5p_mfc_dev, watchdog_work);

	mfc_err("Driver timeout error handling\n");
	/* Lock the mutex that protects open and release.
	 * This is necessary as they may load and unload firmware. */
	mutex_locked = mutex_trylock(&dev->mfc_mutex);
	if (!mutex_locked)
		mfc_err("Error: some instance may be closing/opening\n");
	spin_lock_irqsave(&dev->irqlock, flags);

	s5p_mfc_clock_off();

	for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
		ctx = dev->ctx[i];
		if (!ctx)
			continue;
		ctx->state = MFCINST_ERROR;
		s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
		s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
		clear_work_bit(ctx);
		wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0);
	}
	clear_bit(0, &dev->hw_lock);
	spin_unlock_irqrestore(&dev->irqlock, flags);
	/* Double check if there is at least one instance running.
	 * If no instance is in memory than no firmware should be present */
	if (dev->num_inst > 0) {
		ret = s5p_mfc_reload_firmware(dev);
		if (ret) {
			mfc_err("Failed to reload FW\n");
			goto unlock;
		}
		s5p_mfc_clock_on();
		ret = s5p_mfc_init_hw(dev);
		if (ret)
			mfc_err("Failed to reinit FW\n");
	}
unlock:
	if (mutex_locked)
		mutex_unlock(&dev->mfc_mutex);
}

static enum s5p_mfc_node_type s5p_mfc_get_node_type(struct file *file)
{
	struct video_device *vdev = video_devdata(file);

	if (!vdev) {
		mfc_err("failed to get video_device");
		return MFCNODE_INVALID;
	}
	if (vdev->index == 0)
		return MFCNODE_DECODER;
	else if (vdev->index == 1)
		return MFCNODE_ENCODER;
	return MFCNODE_INVALID;
}

static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
{
	mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
	mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
	mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
}

static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_buf *dst_buf;

	ctx->state = MFCINST_FINISHED;
	ctx->sequence++;
	while (!list_empty(&ctx->dst_queue)) {
		dst_buf = list_entry(ctx->dst_queue.next,
				     struct s5p_mfc_buf, list);
		mfc_debug(2, "Cleaning up buffer: %d\n",
					  dst_buf->b->v4l2_buf.index);
		vb2_set_plane_payload(dst_buf->b, 0, 0);
		vb2_set_plane_payload(dst_buf->b, 1, 0);
		list_del(&dst_buf->list);
		ctx->dst_queue_cnt--;
		dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);

		if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
			s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
			dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
		else
			dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;

		ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index);
		vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE);
	}
}

static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	struct s5p_mfc_buf  *dst_buf, *src_buf;
	size_t dec_y_addr = s5p_mfc_get_dec_y_adr();
	unsigned int frame_type = s5p_mfc_get_frame_type();

	/* Copy timestamp / timecode from decoded src to dst and set
	   appropraite flags */
	src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
	list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
		if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
			memcpy(&dst_buf->b->v4l2_buf.timecode,
				&src_buf->b->v4l2_buf.timecode,
				sizeof(struct v4l2_timecode));
			memcpy(&dst_buf->b->v4l2_buf.timestamp,
				&src_buf->b->v4l2_buf.timestamp,
				sizeof(struct timeval));
			switch (frame_type) {
			case S5P_FIMV_DECODE_FRAME_I_FRAME:
				dst_buf->b->v4l2_buf.flags |=
						V4L2_BUF_FLAG_KEYFRAME;
				break;
			case S5P_FIMV_DECODE_FRAME_P_FRAME:
				dst_buf->b->v4l2_buf.flags |=
						V4L2_BUF_FLAG_PFRAME;
				break;
			case S5P_FIMV_DECODE_FRAME_B_FRAME:
				dst_buf->b->v4l2_buf.flags |=
						V4L2_BUF_FLAG_BFRAME;
				break;
			}
			break;
		}
	}
}

static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	struct s5p_mfc_buf  *dst_buf;
	size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr();
	unsigned int frame_type = s5p_mfc_get_frame_type();
	unsigned int index;

	/* If frame is same as previous then skip and do not dequeue */
	if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
		if (!ctx->after_packed_pb)
			ctx->sequence++;
		ctx->after_packed_pb = 0;
		return;
	}
	ctx->sequence++;
	/* The MFC returns address of the buffer, now we have to
	 * check which videobuf does it correspond to */
	list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
		/* Check if this is the buffer we're looking for */
		if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dspl_y_addr) {
			list_del(&dst_buf->list);
			ctx->dst_queue_cnt--;
			dst_buf->b->v4l2_buf.sequence = ctx->sequence;
			if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
				s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
				dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
			else
				dst_buf->b->v4l2_buf.field =
							V4L2_FIELD_INTERLACED;
			vb2_set_plane_payload(dst_buf->b, 0, ctx->luma_size);
			vb2_set_plane_payload(dst_buf->b, 1, ctx->chroma_size);
			clear_bit(dst_buf->b->v4l2_buf.index,
							&ctx->dec_dst_flag);

			vb2_buffer_done(dst_buf->b,
				err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);

			index = dst_buf->b->v4l2_buf.index;
			break;
		}
	}
}

/* Handle frame decoding interrupt */
static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
					unsigned int reason, unsigned int err)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	unsigned int dst_frame_status;
	struct s5p_mfc_buf *src_buf;
	unsigned long flags;
	unsigned int res_change;

	unsigned int index;

	dst_frame_status = s5p_mfc_get_dspl_status()
				& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
	res_change = s5p_mfc_get_dspl_status()
				& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
	mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
	if (ctx->state == MFCINST_RES_CHANGE_INIT)
		ctx->state = MFCINST_RES_CHANGE_FLUSH;
	if (res_change) {
		ctx->state = MFCINST_RES_CHANGE_INIT;
		s5p_mfc_clear_int_flags(dev);
		wake_up_ctx(ctx, reason, err);
		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
			BUG();
		s5p_mfc_clock_off();
		s5p_mfc_try_run(dev);
		return;
	}
	if (ctx->dpb_flush_flag)
		ctx->dpb_flush_flag = 0;

	spin_lock_irqsave(&dev->irqlock, flags);
	/* All frames remaining in the buffer have been extracted  */
	if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) {
		if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
			s5p_mfc_handle_frame_all_extracted(ctx);
			ctx->state = MFCINST_RES_CHANGE_END;
			goto leave_handle_frame;
		} else {
			s5p_mfc_handle_frame_all_extracted(ctx);
		}
	}

	if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY ||
		dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY)
		s5p_mfc_handle_frame_copy_time(ctx);

	/* A frame has been decoded and is in the buffer  */
	if (dst_frame_status == S5P_FIMV_DEC_STATUS_DISPLAY_ONLY ||
	    dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) {
		s5p_mfc_handle_frame_new(ctx, err);
	} else {
		mfc_debug(2, "No frame decode\n");
	}
	/* Mark source buffer as complete */
	if (dst_frame_status != S5P_FIMV_DEC_STATUS_DISPLAY_ONLY
		&& !list_empty(&ctx->src_queue)) {
		src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
								list);
		ctx->consumed_stream += s5p_mfc_get_consumed_stream();
		if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC &&
			s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME
					&& ctx->consumed_stream + STUFF_BYTE <
					src_buf->b->v4l2_planes[0].bytesused) {
			/* Run MFC again on the same buffer */
			mfc_debug(2, "Running again the same buffer\n");
			ctx->after_packed_pb = 1;
		} else {
			index = src_buf->b->v4l2_buf.index;
			mfc_debug(2, "MFC needs next buffer\n");
			ctx->consumed_stream = 0;
			list_del(&src_buf->list);
			ctx->src_queue_cnt--;
			if (s5p_mfc_err_dec(err) > 0)
				vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
			else
				vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
		}
	}
leave_handle_frame:
	spin_unlock_irqrestore(&dev->irqlock, flags);
	if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
				    || ctx->dst_queue_cnt < ctx->dpb_count)
		clear_work_bit(ctx);
	s5p_mfc_clear_int_flags(dev);
	wake_up_ctx(ctx, reason, err);
	if (test_and_clear_bit(0, &dev->hw_lock) == 0)
		BUG();
	s5p_mfc_clock_off();
	s5p_mfc_try_run(dev);
}

/* Error handling for interrupt */
static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
				 unsigned int reason, unsigned int err)
{
	struct s5p_mfc_dev *dev;
	unsigned long flags;

	/* If no context is available then all necessary
	 * processing has been done. */
	if (ctx == 0)
		return;

	dev = ctx->dev;
	mfc_err("Interrupt Error: %08x\n", err);
	s5p_mfc_clear_int_flags(dev);
	wake_up_dev(dev, reason, err);

	/* Error recovery is dependent on the state of context */
	switch (ctx->state) {
	case MFCINST_INIT:
		/* This error had to happen while acquireing instance */
	case MFCINST_GOT_INST:
		/* This error had to happen while parsing the header */
	case MFCINST_HEAD_PARSED:
		/* This error had to happen while setting dst buffers */
	case MFCINST_RETURN_INST:
		/* This error had to happen while releasing instance */
		clear_work_bit(ctx);
		wake_up_ctx(ctx, reason, err);
		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
			BUG();
		s5p_mfc_clock_off();
		ctx->state = MFCINST_ERROR;
		break;
	case MFCINST_FINISHING:
	case MFCINST_FINISHED:
	case MFCINST_RUNNING:
		/* It is higly probable that an error occured
		 * while decoding a frame */
		clear_work_bit(ctx);
		ctx->state = MFCINST_ERROR;
		/* Mark all dst buffers as having an error */
		spin_lock_irqsave(&dev->irqlock, flags);
		s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
		/* Mark all src buffers as having an error */
		s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
		spin_unlock_irqrestore(&dev->irqlock, flags);
		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
			BUG();
		s5p_mfc_clock_off();
		break;
	default:
		mfc_err("Encountered an error interrupt which had not been handled\n");
		break;
	}
	return;
}

/* Header parsing interrupt handling */
static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
				 unsigned int reason, unsigned int err)
{
	struct s5p_mfc_dev *dev;
	unsigned int guard_width, guard_height;

	if (ctx == 0)
		return;
	dev = ctx->dev;
	if (ctx->c_ops->post_seq_start) {
		if (ctx->c_ops->post_seq_start(ctx))
			mfc_err("post_seq_start() failed\n");
	} else {
		ctx->img_width = s5p_mfc_get_img_width();
		ctx->img_height = s5p_mfc_get_img_height();

		ctx->buf_width = ALIGN(ctx->img_width,
						S5P_FIMV_NV12MT_HALIGN);
		ctx->buf_height = ALIGN(ctx->img_height,
						S5P_FIMV_NV12MT_VALIGN);
		mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
			"buffer dimensions: %dx%d\n", ctx->img_width,
				ctx->img_height, ctx->buf_width,
						ctx->buf_height);
		if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
			ctx->luma_size = ALIGN(ctx->buf_width *
				ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
			ctx->chroma_size = ALIGN(ctx->buf_width *
					 ALIGN((ctx->img_height >> 1),
					       S5P_FIMV_NV12MT_VALIGN),
					       S5P_FIMV_DEC_BUF_ALIGN);
			ctx->mv_size = ALIGN(ctx->buf_width *
					ALIGN((ctx->buf_height >> 2),
					S5P_FIMV_NV12MT_VALIGN),
					S5P_FIMV_DEC_BUF_ALIGN);
		} else {
			guard_width = ALIGN(ctx->img_width + 24,
					S5P_FIMV_NV12MT_HALIGN);
			guard_height = ALIGN(ctx->img_height + 16,
						S5P_FIMV_NV12MT_VALIGN);
			ctx->luma_size = ALIGN(guard_width *
				guard_height, S5P_FIMV_DEC_BUF_ALIGN);
			guard_width = ALIGN(ctx->img_width + 16,
						S5P_FIMV_NV12MT_HALIGN);
			guard_height = ALIGN((ctx->img_height >> 1) + 4,
						S5P_FIMV_NV12MT_VALIGN);
			ctx->chroma_size = ALIGN(guard_width *
				guard_height, S5P_FIMV_DEC_BUF_ALIGN);
			ctx->mv_size = 0;
		}
		ctx->dpb_count = s5p_mfc_get_dpb_count();
		if (ctx->img_width == 0 || ctx->img_height == 0)
			ctx->state = MFCINST_ERROR;
		else
			ctx->state = MFCINST_HEAD_PARSED;
	}
	s5p_mfc_clear_int_flags(dev);
	clear_work_bit(ctx);
	if (test_and_clear_bit(0, &dev->hw_lock) == 0)
		BUG();
	s5p_mfc_clock_off();
	s5p_mfc_try_run(dev);
	wake_up_ctx(ctx, reason, err);
}

/* Header parsing interrupt handling */
static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
				 unsigned int reason, unsigned int err)
{
	struct s5p_mfc_buf *src_buf;
	struct s5p_mfc_dev *dev;
	unsigned long flags;

	if (ctx == 0)
		return;
	dev = ctx->dev;
	s5p_mfc_clear_int_flags(dev);
	ctx->int_type = reason;
	ctx->int_err = err;
	ctx->int_cond = 1;
	spin_lock(&dev->condlock);
	clear_bit(ctx->num, &dev->ctx_work_bits);
	spin_unlock(&dev->condlock);
	if (err == 0) {
		ctx->state = MFCINST_RUNNING;
		if (!ctx->dpb_flush_flag) {
			spin_lock_irqsave(&dev->irqlock, flags);
			if (!list_empty(&ctx->src_queue)) {
				src_buf = list_entry(ctx->src_queue.next,
					     struct s5p_mfc_buf, list);
				list_del(&src_buf->list);
				ctx->src_queue_cnt--;
				vb2_buffer_done(src_buf->b,
						VB2_BUF_STATE_DONE);
			}
			spin_unlock_irqrestore(&dev->irqlock, flags);
		} else {
			ctx->dpb_flush_flag = 0;
		}
		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
			BUG();

		s5p_mfc_clock_off();

		wake_up(&ctx->queue);
		s5p_mfc_try_run(dev);
	} else {
		if (test_and_clear_bit(0, &dev->hw_lock) == 0)
			BUG();

		s5p_mfc_clock_off();

		wake_up(&ctx->queue);
	}
}

/* Interrupt processing */
static irqreturn_t s5p_mfc_irq(int irq, void *priv)
{
	struct s5p_mfc_dev *dev = priv;
	struct s5p_mfc_ctx *ctx;
	unsigned int reason;
	unsigned int err;

	mfc_debug_enter();
	/* Reset the timeout watchdog */
	atomic_set(&dev->watchdog_cnt, 0);
	ctx = dev->ctx[dev->curr_ctx];
	/* Get the reason of interrupt and the error code */
	reason = s5p_mfc_get_int_reason();
	err = s5p_mfc_get_int_err();
	mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
	switch (reason) {
	case S5P_FIMV_R2H_CMD_ERR_RET:
		/* An error has occured */
		if (ctx->state == MFCINST_RUNNING &&
			s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START)
			s5p_mfc_handle_frame(ctx, reason, err);
		else
			s5p_mfc_handle_error(ctx, reason, err);
		clear_bit(0, &dev->enter_suspend);
		break;

	case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
	case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
		if (ctx->c_ops->post_frame_start) {
			if (ctx->c_ops->post_frame_start(ctx))
				mfc_err("post_frame_start() failed\n");
			s5p_mfc_clear_int_flags(dev);
			wake_up_ctx(ctx, reason, err);
			if (test_and_clear_bit(0, &dev->hw_lock) == 0)
				BUG();
			s5p_mfc_clock_off();
			s5p_mfc_try_run(dev);
		} else {
			s5p_mfc_handle_frame(ctx, reason, err);
		}
		break;

	case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
		s5p_mfc_handle_seq_done(ctx, reason, err);
		break;

	case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
		ctx->inst_no = s5p_mfc_get_inst_no();
		ctx->state = MFCINST_GOT_INST;
		clear_work_bit(ctx);
		wake_up(&ctx->queue);
		goto irq_cleanup_hw;

	case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
		clear_work_bit(ctx);
		ctx->state = MFCINST_FREE;
		wake_up(&ctx->queue);
		goto irq_cleanup_hw;

	case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
	case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
	case S5P_FIMV_R2H_CMD_SLEEP_RET:
	case S5P_FIMV_R2H_CMD_WAKEUP_RET:
		if (ctx)
			clear_work_bit(ctx);
		s5p_mfc_clear_int_flags(dev);
		wake_up_dev(dev, reason, err);
		clear_bit(0, &dev->hw_lock);
		clear_bit(0, &dev->enter_suspend);
		break;

	case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
		s5p_mfc_handle_init_buffers(ctx, reason, err);
		break;
	default:
		mfc_debug(2, "Unknown int reason\n");
		s5p_mfc_clear_int_flags(dev);
	}
	mfc_debug_leave();
	return IRQ_HANDLED;
irq_cleanup_hw:
	s5p_mfc_clear_int_flags(dev);
	ctx->int_type = reason;
	ctx->int_err = err;
	ctx->int_cond = 1;
	if (test_and_clear_bit(0, &dev->hw_lock) == 0)
		mfc_err("Failed to unlock hw\n");

	s5p_mfc_clock_off();

	s5p_mfc_try_run(dev);
	mfc_debug(2, "Exit via irq_cleanup_hw\n");
	return IRQ_HANDLED;
}

/* Open an MFC node */
static int s5p_mfc_open(struct file *file)
{
	struct s5p_mfc_dev *dev = video_drvdata(file);
	struct s5p_mfc_ctx *ctx = NULL;
	struct vb2_queue *q;
	unsigned long flags;
	int ret = 0;

	mfc_debug_enter();
	dev->num_inst++;	/* It is guarded by mfc_mutex in vfd */
	/* Allocate memory for context */
	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx) {
		mfc_err("Not enough memory\n");
		ret = -ENOMEM;
		goto err_alloc;
	}
	v4l2_fh_init(&ctx->fh, video_devdata(file));
	file->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);
	ctx->dev = dev;
	INIT_LIST_HEAD(&ctx->src_queue);
	INIT_LIST_HEAD(&ctx->dst_queue);
	ctx->src_queue_cnt = 0;
	ctx->dst_queue_cnt = 0;
	/* Get context number */
	ctx->num = 0;
	while (dev->ctx[ctx->num]) {
		ctx->num++;
		if (ctx->num >= MFC_NUM_CONTEXTS) {
			mfc_err("Too many open contexts\n");
			ret = -EBUSY;
			goto err_no_ctx;
		}
	}
	/* Mark context as idle */
	spin_lock_irqsave(&dev->condlock, flags);
	clear_bit(ctx->num, &dev->ctx_work_bits);
	spin_unlock_irqrestore(&dev->condlock, flags);
	dev->ctx[ctx->num] = ctx;
	if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
		ctx->type = MFCINST_DECODER;
		ctx->c_ops = get_dec_codec_ops();
		/* Setup ctrl handler */
		ret = s5p_mfc_dec_ctrls_setup(ctx);
		if (ret) {
			mfc_err("Failed to setup mfc controls\n");
			goto err_ctrls_setup;
		}
	} else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
		ctx->type = MFCINST_ENCODER;
		ctx->c_ops = get_enc_codec_ops();
		/* only for encoder */
		INIT_LIST_HEAD(&ctx->ref_queue);
		ctx->ref_queue_cnt = 0;
		/* Setup ctrl handler */
		ret = s5p_mfc_enc_ctrls_setup(ctx);
		if (ret) {
			mfc_err("Failed to setup mfc controls\n");
			goto err_ctrls_setup;
		}
	} else {
		ret = -ENOENT;
		goto err_bad_node;
	}
	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
	ctx->inst_no = -1;
	/* Load firmware if this is the first instance */
	if (dev->num_inst == 1) {
		dev->watchdog_timer.expires = jiffies +
					msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
		add_timer(&dev->watchdog_timer);
		ret = s5p_mfc_power_on();
		if (ret < 0) {
			mfc_err("power on failed\n");
			goto err_pwr_enable;
		}
		s5p_mfc_clock_on();
		ret = s5p_mfc_alloc_and_load_firmware(dev);
		if (ret)
			goto err_alloc_fw;
		/* Init the FW */
		ret = s5p_mfc_init_hw(dev);
		if (ret)
			goto err_init_hw;
		s5p_mfc_clock_off();
	}
	/* Init videobuf2 queue for CAPTURE */
	q = &ctx->vq_dst;
	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	q->drv_priv = &ctx->fh;
	if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
		q->io_modes = VB2_MMAP;
		q->ops = get_dec_queue_ops();
	} else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
		q->io_modes = VB2_MMAP | VB2_USERPTR;
		q->ops = get_enc_queue_ops();
	} else {
		ret = -ENOENT;
		goto err_queue_init;
	}
	q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
	ret = vb2_queue_init(q);
	if (ret) {
		mfc_err("Failed to initialize videobuf2 queue(capture)\n");
		goto err_queue_init;
	}
	/* Init videobuf2 queue for OUTPUT */
	q = &ctx->vq_src;
	q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
	q->io_modes = VB2_MMAP;
	q->drv_priv = &ctx->fh;
	if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
		q->io_modes = VB2_MMAP;
		q->ops = get_dec_queue_ops();
	} else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
		q->io_modes = VB2_MMAP | VB2_USERPTR;
		q->ops = get_enc_queue_ops();
	} else {
		ret = -ENOENT;
		goto err_queue_init;
	}
	q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
	ret = vb2_queue_init(q);
	if (ret) {
		mfc_err("Failed to initialize videobuf2 queue(output)\n");
		goto err_queue_init;
	}
	init_waitqueue_head(&ctx->queue);
	mfc_debug_leave();
	return ret;
	/* Deinit when failure occured */
err_queue_init:
err_init_hw:
	s5p_mfc_release_firmware(dev);
err_alloc_fw:
	dev->ctx[ctx->num] = 0;
	del_timer_sync(&dev->watchdog_timer);
	s5p_mfc_clock_off();
err_pwr_enable:
	if (dev->num_inst == 1) {
		if (s5p_mfc_power_off() < 0)
			mfc_err("power off failed\n");
		s5p_mfc_release_firmware(dev);
	}
err_ctrls_setup:
	s5p_mfc_dec_ctrls_delete(ctx);
err_bad_node:
err_no_ctx:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
err_alloc:
	dev->num_inst--;
	mfc_debug_leave();
	return ret;
}

/* Release MFC context */
static int s5p_mfc_release(struct file *file)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
	struct s5p_mfc_dev *dev = ctx->dev;
	unsigned long flags;

	mfc_debug_enter();
	s5p_mfc_clock_on();
	vb2_queue_release(&ctx->vq_src);
	vb2_queue_release(&ctx->vq_dst);
	/* Mark context as idle */
	spin_lock_irqsave(&dev->condlock, flags);
	clear_bit(ctx->num, &dev->ctx_work_bits);
	spin_unlock_irqrestore(&dev->condlock, flags);
	/* If instance was initialised then
	 * return instance and free reosurces */
	if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
		mfc_debug(2, "Has to free instance\n");
		ctx->state = MFCINST_RETURN_INST;
		spin_lock_irqsave(&dev->condlock, flags);
		set_bit(ctx->num, &dev->ctx_work_bits);
		spin_unlock_irqrestore(&dev->condlock, flags);
		s5p_mfc_clean_ctx_int_flags(ctx);
		s5p_mfc_try_run(dev);
		/* Wait until instance is returned or timeout occured */
		if (s5p_mfc_wait_for_done_ctx
		    (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
			s5p_mfc_clock_off();
			mfc_err("Err returning instance\n");
		}
		mfc_debug(2, "After free instance\n");
		/* Free resources */
		s5p_mfc_release_codec_buffers(ctx);
		s5p_mfc_release_instance_buffer(ctx);
		if (ctx->type == MFCINST_DECODER)
			s5p_mfc_release_dec_desc_buffer(ctx);

		ctx->inst_no = MFC_NO_INSTANCE_SET;
	}
	/* hardware locking scheme */
	if (dev->curr_ctx == ctx->num)
		clear_bit(0, &dev->hw_lock);
	dev->num_inst--;
	if (dev->num_inst == 0) {
		mfc_debug(2, "Last instance - release firmware\n");
		/* reset <-> F/W release */
		s5p_mfc_reset(dev);
		s5p_mfc_release_firmware(dev);
		del_timer_sync(&dev->watchdog_timer);
		if (s5p_mfc_power_off() < 0)
			mfc_err("Power off failed\n");
	}
	mfc_debug(2, "Shutting down clock\n");
	s5p_mfc_clock_off();
	dev->ctx[ctx->num] = 0;
	s5p_mfc_dec_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
	mfc_debug_leave();
	return 0;
}

/* Poll */
static unsigned int s5p_mfc_poll(struct file *file,
				 struct poll_table_struct *wait)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
	struct s5p_mfc_dev *dev = ctx->dev;
	struct vb2_queue *src_q, *dst_q;
	struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
	unsigned int rc = 0;
	unsigned long flags;

	src_q = &ctx->vq_src;
	dst_q = &ctx->vq_dst;
	/*
	 * There has to be at least one buffer queued on each queued_list, which
	 * means either in driver already or waiting for driver to claim it
	 * and start processing.
	 */
	if ((!src_q->streaming || list_empty(&src_q->queued_list))
		&& (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
		rc = POLLERR;
		goto end;
	}
	mutex_unlock(&dev->mfc_mutex);
	poll_wait(file, &src_q->done_wq, wait);
	poll_wait(file, &dst_q->done_wq, wait);
	mutex_lock(&dev->mfc_mutex);
	spin_lock_irqsave(&src_q->done_lock, flags);
	if (!list_empty(&src_q->done_list))
		src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
								done_entry);
	if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
				|| src_vb->state == VB2_BUF_STATE_ERROR))
		rc |= POLLOUT | POLLWRNORM;
	spin_unlock_irqrestore(&src_q->done_lock, flags);
	spin_lock_irqsave(&dst_q->done_lock, flags);
	if (!list_empty(&dst_q->done_list))
		dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
								done_entry);
	if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
				|| dst_vb->state == VB2_BUF_STATE_ERROR))
		rc |= POLLIN | POLLRDNORM;
	spin_unlock_irqrestore(&dst_q->done_lock, flags);
end:
	return rc;
}

/* Mmap */
static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
	int ret;
	if (offset < DST_QUEUE_OFF_BASE) {
		mfc_debug(2, "mmaping source\n");
		ret = vb2_mmap(&ctx->vq_src, vma);
	} else {		/* capture */
		mfc_debug(2, "mmaping destination\n");
		vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
		ret = vb2_mmap(&ctx->vq_dst, vma);
	}
	return ret;
}

/* v4l2 ops */
static const struct v4l2_file_operations s5p_mfc_fops = {
	.owner = THIS_MODULE,
	.open = s5p_mfc_open,
	.release = s5p_mfc_release,
	.poll = s5p_mfc_poll,
	.unlocked_ioctl = video_ioctl2,
	.mmap = s5p_mfc_mmap,
};

static int match_child(struct device *dev, void *data)
{
	if (!dev_name(dev))
		return 0;
	return !strcmp(dev_name(dev), (char *)data);
}

/* MFC probe function */
static int s5p_mfc_probe(struct platform_device *pdev)
{
	struct s5p_mfc_dev *dev;
	struct video_device *vfd;
	struct resource *res;
	int ret;

	pr_debug("%s++\n", __func__);
	dev = kzalloc(sizeof *dev, GFP_KERNEL);
	if (!dev) {
		dev_err(&pdev->dev, "Not enough memory for MFC device\n");
		return -ENOMEM;
	}

	spin_lock_init(&dev->irqlock);
	spin_lock_init(&dev->condlock);
	dev->plat_dev = pdev;
	if (!dev->plat_dev) {
		dev_err(&pdev->dev, "No platform data specified\n");
		ret = -ENODEV;
		goto err_dev;
	}

	ret = s5p_mfc_init_pm(dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to get mfc clock source\n");
		goto err_clk;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "failed to get memory region resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	dev->mfc_mem = request_mem_region(res->start, resource_size(res),
					  pdev->name);
	if (dev->mfc_mem == NULL) {
		dev_err(&pdev->dev, "failed to get memory region\n");
		ret = -ENOENT;
		goto err_mem_reg;
	}
	dev->regs_base = ioremap(dev->mfc_mem->start, resource_size(dev->mfc_mem));
	if (dev->regs_base == NULL) {
		dev_err(&pdev->dev, "failed to ioremap address region\n");
		ret = -ENOENT;
		goto err_ioremap;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "failed to get irq resource\n");
		ret = -ENOENT;
		goto err_get_res;
	}
	dev->irq = res->start;
	ret = request_irq(dev->irq, s5p_mfc_irq, IRQF_DISABLED, pdev->name,
									dev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
		goto err_req_irq;
	}

	dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l",
					   match_child);
	if (!dev->mem_dev_l) {
		mfc_err("Mem child (L) device get failed\n");
		ret = -ENODEV;
		goto err_find_child;
	}
	dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
					   match_child);
	if (!dev->mem_dev_r) {
		mfc_err("Mem child (R) device get failed\n");
		ret = -ENODEV;
		goto err_find_child;
	}

	dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
	if (IS_ERR_OR_NULL(dev->alloc_ctx[0])) {
		ret = PTR_ERR(dev->alloc_ctx[0]);
		goto err_mem_init_ctx_0;
	}
	dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r);
	if (IS_ERR_OR_NULL(dev->alloc_ctx[1])) {
		ret = PTR_ERR(dev->alloc_ctx[1]);
		goto err_mem_init_ctx_1;
	}

	mutex_init(&dev->mfc_mutex);

	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
	if (ret)
		goto err_v4l2_dev_reg;
	init_waitqueue_head(&dev->queue);

	/* decoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_dec_alloc;
	}
	vfd->fops	= &s5p_mfc_fops,
	vfd->ioctl_ops	= get_dec_v4l2_ioctl_ops();
	vfd->release	= video_device_release,
	vfd->lock	= &dev->mfc_mutex;
	vfd->v4l2_dev	= &dev->v4l2_dev;
	snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
	dev->vfd_dec	= vfd;
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
	if (ret) {
		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
		video_device_release(vfd);
		goto err_dec_reg;
	}
	v4l2_info(&dev->v4l2_dev,
		  "decoder registered as /dev/video%d\n", vfd->num);
	video_set_drvdata(vfd, dev);

	/* encoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_enc_alloc;
	}
	vfd->fops	= &s5p_mfc_fops,
	vfd->ioctl_ops	= get_enc_v4l2_ioctl_ops();
	vfd->release	= video_device_release,
	vfd->lock	= &dev->mfc_mutex;
	vfd->v4l2_dev	= &dev->v4l2_dev;
	snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
	dev->vfd_enc	= vfd;
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
	if (ret) {
		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
		video_device_release(vfd);
		goto err_enc_reg;
	}
	v4l2_info(&dev->v4l2_dev,
		  "encoder registered as /dev/video%d\n", vfd->num);
	video_set_drvdata(vfd, dev);
	platform_set_drvdata(pdev, dev);

	dev->hw_lock = 0;
	dev->watchdog_workqueue = create_singlethread_workqueue(S5P_MFC_NAME);
	INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
	atomic_set(&dev->watchdog_cnt, 0);
	init_timer(&dev->watchdog_timer);
	dev->watchdog_timer.data = (unsigned long)dev;
	dev->watchdog_timer.function = s5p_mfc_watchdog;

	pr_debug("%s--\n", __func__);
	return 0;

/* Deinit MFC if probe had failed */
err_enc_reg:
	video_device_release(dev->vfd_enc);
err_enc_alloc:
	video_unregister_device(dev->vfd_dec);
err_dec_reg:
	video_device_release(dev->vfd_dec);
err_dec_alloc:
	v4l2_device_unregister(&dev->v4l2_dev);
err_v4l2_dev_reg:
	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
err_mem_init_ctx_1:
	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
err_mem_init_ctx_0:
err_find_child:
	free_irq(dev->irq, dev);
err_req_irq:
err_get_res:
	iounmap(dev->regs_base);
	dev->regs_base = NULL;
err_ioremap:
	release_resource(dev->mfc_mem);
	kfree(dev->mfc_mem);
err_mem_reg:
err_res:
	s5p_mfc_final_pm(dev);
err_clk:
err_dev:
	kfree(dev);
	pr_debug("%s-- with error\n", __func__);
	return ret;

}

/* Remove the driver */
static int __devexit s5p_mfc_remove(struct platform_device *pdev)
{
	struct s5p_mfc_dev *dev = platform_get_drvdata(pdev);

	v4l2_info(&dev->v4l2_dev, "Removing %s\n", pdev->name);

	del_timer_sync(&dev->watchdog_timer);
	flush_workqueue(dev->watchdog_workqueue);
	destroy_workqueue(dev->watchdog_workqueue);

	video_unregister_device(dev->vfd_enc);
	video_unregister_device(dev->vfd_dec);
	v4l2_device_unregister(&dev->v4l2_dev);
	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);

	free_irq(dev->irq, dev);
	iounmap(dev->regs_base);
	if (dev->mfc_mem) {
		release_resource(dev->mfc_mem);
		kfree(dev->mfc_mem);
		dev->mfc_mem = NULL;
	}
	s5p_mfc_final_pm(dev);
	kfree(dev);
	return 0;
}

#ifdef CONFIG_PM_SLEEP

static int s5p_mfc_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
	int ret;

	if (m_dev->num_inst == 0)
		return 0;
	return s5p_mfc_sleep(m_dev);
	if (test_and_set_bit(0, &m_dev->enter_suspend) != 0) {
		mfc_err("Error: going to suspend for a second time\n");
		return -EIO;
	}

	/* Check if we're processing then wait if it necessary. */
	while (test_and_set_bit(0, &m_dev->hw_lock) != 0) {
		/* Try and lock the HW */
		/* Wait on the interrupt waitqueue */
		ret = wait_event_interruptible_timeout(m_dev->queue,
			m_dev->int_cond || m_dev->ctx[m_dev->curr_ctx]->int_cond,
			msecs_to_jiffies(MFC_INT_TIMEOUT));

		if (ret == 0) {
			mfc_err("Waiting for hardware to finish timed out\n");
			return -EIO;
		}
	}
	return 0;
}

static int s5p_mfc_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);

	if (m_dev->num_inst == 0)
		return 0;
	return s5p_mfc_wakeup(m_dev);
}
#endif

#ifdef CONFIG_PM_RUNTIME
static int s5p_mfc_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);

	atomic_set(&m_dev->pm.power, 0);
	return 0;
}

static int s5p_mfc_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
	int pre_power;

	if (!m_dev->alloc_ctx)
		return 0;
	pre_power = atomic_read(&m_dev->pm.power);
	atomic_set(&m_dev->pm.power, 1);
	return 0;
}
#endif

/* Power management */
static const struct dev_pm_ops s5p_mfc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume)
	SET_RUNTIME_PM_OPS(s5p_mfc_runtime_suspend, s5p_mfc_runtime_resume,
			   NULL)
};

static struct platform_driver s5p_mfc_driver = {
	.probe	= s5p_mfc_probe,
	.remove	= __devexit_p(s5p_mfc_remove),
	.driver	= {
		.name	= S5P_MFC_NAME,
		.owner	= THIS_MODULE,
		.pm	= &s5p_mfc_pm_ops
	},
};

module_platform_driver(s5p_mfc_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
MODULE_DESCRIPTION("Samsung S5P Multi Format Codec V4L2 driver");

