/*
 * Copyright (C) STMicroelectronics SA 2014
 * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>

#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>

#include "bdisp.h"

#define BDISP_MAX_CTRL_NUM      10

#define BDISP_WORK_TIMEOUT      ((100 * HZ) / 1000)

/* User configuration change */
#define BDISP_PARAMS            BIT(0) /* Config updated */
#define BDISP_SRC_FMT           BIT(1) /* Source set */
#define BDISP_DST_FMT           BIT(2) /* Destination set */
#define BDISP_CTX_STOP_REQ      BIT(3) /* Stop request */
#define BDISP_CTX_ABORT         BIT(4) /* Abort while device run */

#define BDISP_MIN_W             1
#define BDISP_MAX_W             8191
#define BDISP_MIN_H             1
#define BDISP_MAX_H             8191

#define fh_to_ctx(__fh) container_of(__fh, struct bdisp_ctx, fh)

enum bdisp_dev_flags {
	ST_M2M_OPEN,            /* Driver opened */
	ST_M2M_RUNNING,         /* HW device running */
	ST_M2M_SUSPENDED,       /* Driver suspended */
	ST_M2M_SUSPENDING,      /* Driver being suspended */
};

static const struct bdisp_fmt bdisp_formats[] = {
	/* ARGB888. [31:0] A:R:G:B 8:8:8:8 little endian */
	{
		.pixelformat    = V4L2_PIX_FMT_ABGR32, /* is actually ARGB */
		.nb_planes      = 1,
		.bpp            = 32,
		.bpp_plane0     = 32,
		.w_align        = 1,
		.h_align        = 1
	},
	/* XRGB888. [31:0] x:R:G:B 8:8:8:8 little endian */
	{
		.pixelformat    = V4L2_PIX_FMT_XBGR32, /* is actually xRGB */
		.nb_planes      = 1,
		.bpp            = 32,
		.bpp_plane0     = 32,
		.w_align        = 1,
		.h_align        = 1
	},
	/* RGB565. [15:0] R:G:B 5:6:5 little endian */
	{
		.pixelformat    = V4L2_PIX_FMT_RGB565,
		.nb_planes      = 1,
		.bpp            = 16,
		.bpp_plane0     = 16,
		.w_align        = 1,
		.h_align        = 1
	},
	/* NV12. YUV420SP - 1 plane for Y + 1 plane for (CbCr) */
	{
		.pixelformat    = V4L2_PIX_FMT_NV12,
		.nb_planes      = 2,
		.bpp            = 12,
		.bpp_plane0     = 8,
		.w_align        = 2,
		.h_align        = 2
	},
	/* RGB888. [23:0] B:G:R 8:8:8 little endian */
	{
		.pixelformat    = V4L2_PIX_FMT_RGB24,
		.nb_planes      = 1,
		.bpp            = 24,
		.bpp_plane0     = 24,
		.w_align        = 1,
		.h_align        = 1
	},
	/* YU12. YUV420P - 1 plane for Y + 1 plane for Cb + 1 plane for Cr
	 * To keep as the LAST element of this table (no support on capture)
	 */
	{
		.pixelformat    = V4L2_PIX_FMT_YUV420,
		.nb_planes      = 3,
		.bpp            = 12,
		.bpp_plane0     = 8,
		.w_align        = 2,
		.h_align        = 2
	}
};

/* Default format : HD ARGB32*/
#define BDISP_DEF_WIDTH         1920
#define BDISP_DEF_HEIGHT        1080

static const struct bdisp_frame bdisp_dflt_fmt = {
		.width          = BDISP_DEF_WIDTH,
		.height         = BDISP_DEF_HEIGHT,
		.fmt            = &bdisp_formats[0],
		.field          = V4L2_FIELD_NONE,
		.bytesperline   = BDISP_DEF_WIDTH * 4,
		.sizeimage      = BDISP_DEF_WIDTH * BDISP_DEF_HEIGHT * 4,
		.colorspace     = V4L2_COLORSPACE_REC709,
		.crop           = {0, 0, BDISP_DEF_WIDTH, BDISP_DEF_HEIGHT},
		.paddr          = {0, 0, 0, 0}
};

static inline void bdisp_ctx_state_lock_set(u32 state, struct bdisp_ctx *ctx)
{
	unsigned long flags;

	spin_lock_irqsave(&ctx->bdisp_dev->slock, flags);
	ctx->state |= state;
	spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags);
}

static inline void bdisp_ctx_state_lock_clear(u32 state, struct bdisp_ctx *ctx)
{
	unsigned long flags;

	spin_lock_irqsave(&ctx->bdisp_dev->slock, flags);
	ctx->state &= ~state;
	spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags);
}

static inline bool bdisp_ctx_state_is_set(u32 mask, struct bdisp_ctx *ctx)
{
	unsigned long flags;
	bool ret;

	spin_lock_irqsave(&ctx->bdisp_dev->slock, flags);
	ret = (ctx->state & mask) == mask;
	spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags);

	return ret;
}

static const struct bdisp_fmt *bdisp_find_fmt(u32 pixelformat)
{
	const struct bdisp_fmt *fmt;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(bdisp_formats); i++) {
		fmt = &bdisp_formats[i];
		if (fmt->pixelformat == pixelformat)
			return fmt;
	}

	return NULL;
}

static struct bdisp_frame *ctx_get_frame(struct bdisp_ctx *ctx,
					 enum v4l2_buf_type type)
{
	switch (type) {
	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
		return &ctx->src;
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		return &ctx->dst;
	default:
		dev_err(ctx->bdisp_dev->dev,
			"Wrong buffer/video queue type (%d)\n", type);
		break;
	}

	return ERR_PTR(-EINVAL);
}

static void bdisp_job_finish(struct bdisp_ctx *ctx, int vb_state)
{
	struct vb2_v4l2_buffer *src_vb, *dst_vb;

	if (WARN(!ctx || !ctx->fh.m2m_ctx, "Null hardware context\n"))
		return;

	dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__);

	src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
	dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);

	if (src_vb && dst_vb) {
		dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
		dst_vb->timecode = src_vb->timecode;
		dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
		dst_vb->flags |= src_vb->flags &
					  V4L2_BUF_FLAG_TSTAMP_SRC_MASK;

		v4l2_m2m_buf_done(src_vb, vb_state);
		v4l2_m2m_buf_done(dst_vb, vb_state);

		v4l2_m2m_job_finish(ctx->bdisp_dev->m2m.m2m_dev,
				    ctx->fh.m2m_ctx);
	}
}

static int bdisp_ctx_stop_req(struct bdisp_ctx *ctx)
{
	struct bdisp_ctx *curr_ctx;
	struct bdisp_dev *bdisp = ctx->bdisp_dev;
	int ret;

	dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__);

	cancel_delayed_work(&bdisp->timeout_work);

	curr_ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev);
	if (!test_bit(ST_M2M_RUNNING, &bdisp->state) || (curr_ctx != ctx))
		return 0;

	bdisp_ctx_state_lock_set(BDISP_CTX_STOP_REQ, ctx);

	ret = wait_event_timeout(bdisp->irq_queue,
			!bdisp_ctx_state_is_set(BDISP_CTX_STOP_REQ, ctx),
			BDISP_WORK_TIMEOUT);

	if (!ret) {
		dev_err(ctx->bdisp_dev->dev, "%s IRQ timeout\n", __func__);
		return -ETIMEDOUT;
	}

	return 0;
}

static void __bdisp_job_abort(struct bdisp_ctx *ctx)
{
	int ret;

	ret = bdisp_ctx_stop_req(ctx);
	if ((ret == -ETIMEDOUT) || (ctx->state & BDISP_CTX_ABORT)) {
		bdisp_ctx_state_lock_clear(BDISP_CTX_STOP_REQ | BDISP_CTX_ABORT,
					   ctx);
		bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR);
	}
}

static void bdisp_job_abort(void *priv)
{
	__bdisp_job_abort((struct bdisp_ctx *)priv);
}

static int bdisp_get_addr(struct bdisp_ctx *ctx, struct vb2_buffer *vb,
			  struct bdisp_frame *frame, dma_addr_t *paddr)
{
	if (!vb || !frame)
		return -EINVAL;

	paddr[0] = vb2_dma_contig_plane_dma_addr(vb, 0);

	if (frame->fmt->nb_planes > 1)
		/* UV (NV12) or U (420P) */
		paddr[1] = (dma_addr_t)(paddr[0] +
				frame->bytesperline * frame->height);

	if (frame->fmt->nb_planes > 2)
		/* V (420P) */
		paddr[2] = (dma_addr_t)(paddr[1] +
				(frame->bytesperline * frame->height) / 4);

	if (frame->fmt->nb_planes > 3)
		dev_dbg(ctx->bdisp_dev->dev, "ignoring some planes\n");

	dev_dbg(ctx->bdisp_dev->dev,
		"%s plane[0]=%pad plane[1]=%pad plane[2]=%pad\n",
		__func__, &paddr[0], &paddr[1], &paddr[2]);

	return 0;
}

static int bdisp_get_bufs(struct bdisp_ctx *ctx)
{
	struct bdisp_frame *src, *dst;
	struct vb2_v4l2_buffer *src_vb, *dst_vb;
	int ret;

	src = &ctx->src;
	dst = &ctx->dst;

	src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
	ret = bdisp_get_addr(ctx, &src_vb->vb2_buf, src, src->paddr);
	if (ret)
		return ret;

	dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
	ret = bdisp_get_addr(ctx, &dst_vb->vb2_buf, dst, dst->paddr);
	if (ret)
		return ret;

	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;

	return 0;
}

static void bdisp_device_run(void *priv)
{
	struct bdisp_ctx *ctx = priv;
	struct bdisp_dev *bdisp;
	unsigned long flags;
	int err = 0;

	if (WARN(!ctx, "Null hardware context\n"))
		return;

	bdisp = ctx->bdisp_dev;
	dev_dbg(bdisp->dev, "%s\n", __func__);
	spin_lock_irqsave(&bdisp->slock, flags);

	if (bdisp->m2m.ctx != ctx) {
		dev_dbg(bdisp->dev, "ctx updated: %p -> %p\n",
			bdisp->m2m.ctx, ctx);
		ctx->state |= BDISP_PARAMS;
		bdisp->m2m.ctx = ctx;
	}

	if (ctx->state & BDISP_CTX_STOP_REQ) {
		ctx->state &= ~BDISP_CTX_STOP_REQ;
		ctx->state |= BDISP_CTX_ABORT;
		wake_up(&bdisp->irq_queue);
		goto out;
	}

	err = bdisp_get_bufs(ctx);
	if (err) {
		dev_err(bdisp->dev, "cannot get address\n");
		goto out;
	}

	bdisp_dbg_perf_begin(bdisp);

	err = bdisp_hw_reset(bdisp);
	if (err) {
		dev_err(bdisp->dev, "could not get HW ready\n");
		goto out;
	}

	err = bdisp_hw_update(ctx);
	if (err) {
		dev_err(bdisp->dev, "could not send HW request\n");
		goto out;
	}

	queue_delayed_work(bdisp->work_queue, &bdisp->timeout_work,
			   BDISP_WORK_TIMEOUT);
	set_bit(ST_M2M_RUNNING, &bdisp->state);
out:
	ctx->state &= ~BDISP_PARAMS;
	spin_unlock_irqrestore(&bdisp->slock, flags);
	if (err)
		bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR);
}

static struct v4l2_m2m_ops bdisp_m2m_ops = {
	.device_run     = bdisp_device_run,
	.job_abort      = bdisp_job_abort,
};

static int __bdisp_s_ctrl(struct bdisp_ctx *ctx, struct v4l2_ctrl *ctrl)
{
	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
		return 0;

	switch (ctrl->id) {
	case V4L2_CID_HFLIP:
		ctx->hflip = ctrl->val;
		break;
	case V4L2_CID_VFLIP:
		ctx->vflip = ctrl->val;
		break;
	default:
		dev_err(ctx->bdisp_dev->dev, "unknown control %d\n", ctrl->id);
		return -EINVAL;
	}

	ctx->state |= BDISP_PARAMS;

	return 0;
}

static int bdisp_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct bdisp_ctx *ctx = container_of(ctrl->handler, struct bdisp_ctx,
						ctrl_handler);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&ctx->bdisp_dev->slock, flags);
	ret = __bdisp_s_ctrl(ctx, ctrl);
	spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags);

	return ret;
}

static const struct v4l2_ctrl_ops bdisp_c_ops = {
	.s_ctrl = bdisp_s_ctrl,
};

static int bdisp_ctrls_create(struct bdisp_ctx *ctx)
{
	if (ctx->ctrls_rdy)
		return 0;

	v4l2_ctrl_handler_init(&ctx->ctrl_handler, BDISP_MAX_CTRL_NUM);

	ctx->bdisp_ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
				&bdisp_c_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
	ctx->bdisp_ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
				&bdisp_c_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);

	if (ctx->ctrl_handler.error) {
		int err = ctx->ctrl_handler.error;

		v4l2_ctrl_handler_free(&ctx->ctrl_handler);
		return err;
	}

	ctx->ctrls_rdy = true;

	return 0;
}

static void bdisp_ctrls_delete(struct bdisp_ctx *ctx)
{
	if (ctx->ctrls_rdy) {
		v4l2_ctrl_handler_free(&ctx->ctrl_handler);
		ctx->ctrls_rdy = false;
	}
}

static int bdisp_queue_setup(struct vb2_queue *vq,
			     unsigned int *nb_buf, unsigned int *nb_planes,
			     unsigned int sizes[], void *allocators[])
{
	struct bdisp_ctx *ctx = vb2_get_drv_priv(vq);
	struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type);

	if (IS_ERR(frame)) {
		dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame);
		return PTR_ERR(frame);
	}

	if (!frame->fmt) {
		dev_err(ctx->bdisp_dev->dev, "Invalid format\n");
		return -EINVAL;
	}
	allocators[0] = ctx->bdisp_dev->alloc_ctx;

	if (*nb_planes)
		return sizes[0] < frame->sizeimage ? -EINVAL : 0;

	*nb_planes = 1;
	sizes[0] = frame->sizeimage;

	return 0;
}

static int bdisp_buf_prepare(struct vb2_buffer *vb)
{
	struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
	struct bdisp_frame *frame = ctx_get_frame(ctx, vb->vb2_queue->type);

	if (IS_ERR(frame)) {
		dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame);
		return PTR_ERR(frame);
	}

	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
		vb2_set_plane_payload(vb, 0, frame->sizeimage);

	return 0;
}

static void bdisp_buf_queue(struct vb2_buffer *vb)
{
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);

	/* return to V4L2 any 0-size buffer so it can be dequeued by user */
	if (!vb2_get_plane_payload(vb, 0)) {
		dev_dbg(ctx->bdisp_dev->dev, "0 data buffer, skip it\n");
		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
		return;
	}

	if (ctx->fh.m2m_ctx)
		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}

static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct bdisp_ctx *ctx = q->drv_priv;
	struct vb2_v4l2_buffer *buf;
	int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev);

	if (ret < 0) {
		dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n");

		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
			while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
				v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
		} else {
			while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
				v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
		}

		return ret;
	}

	return 0;
}

static void bdisp_stop_streaming(struct vb2_queue *q)
{
	struct bdisp_ctx *ctx = q->drv_priv;

	__bdisp_job_abort(ctx);

	pm_runtime_put(ctx->bdisp_dev->dev);
}

static struct vb2_ops bdisp_qops = {
	.queue_setup     = bdisp_queue_setup,
	.buf_prepare     = bdisp_buf_prepare,
	.buf_queue       = bdisp_buf_queue,
	.wait_prepare    = vb2_ops_wait_prepare,
	.wait_finish     = vb2_ops_wait_finish,
	.stop_streaming  = bdisp_stop_streaming,
	.start_streaming = bdisp_start_streaming,
};

static int queue_init(void *priv,
		      struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
{
	struct bdisp_ctx *ctx = priv;
	int ret;

	memset(src_vq, 0, sizeof(*src_vq));
	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
	src_vq->drv_priv = ctx;
	src_vq->ops = &bdisp_qops;
	src_vq->mem_ops = &vb2_dma_contig_memops;
	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
	src_vq->lock = &ctx->bdisp_dev->lock;

	ret = vb2_queue_init(src_vq);
	if (ret)
		return ret;

	memset(dst_vq, 0, sizeof(*dst_vq));
	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
	dst_vq->drv_priv = ctx;
	dst_vq->ops = &bdisp_qops;
	dst_vq->mem_ops = &vb2_dma_contig_memops;
	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
	dst_vq->lock = &ctx->bdisp_dev->lock;

	return vb2_queue_init(dst_vq);
}

static int bdisp_open(struct file *file)
{
	struct bdisp_dev *bdisp = video_drvdata(file);
	struct bdisp_ctx *ctx = NULL;
	int ret;

	if (mutex_lock_interruptible(&bdisp->lock))
		return -ERESTARTSYS;

	/* Allocate memory for both context and node */
	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx) {
		ret = -ENOMEM;
		goto unlock;
	}
	ctx->bdisp_dev = bdisp;

	if (bdisp_hw_alloc_nodes(ctx)) {
		dev_err(bdisp->dev, "no memory for nodes\n");
		ret = -ENOMEM;
		goto mem_ctx;
	}

	v4l2_fh_init(&ctx->fh, bdisp->m2m.vdev);

	ret = bdisp_ctrls_create(ctx);
	if (ret) {
		dev_err(bdisp->dev, "Failed to create control\n");
		goto error_fh;
	}

	/* Use separate control handler per file handle */
	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
	file->private_data = &ctx->fh;
	v4l2_fh_add(&ctx->fh);

	/* Default format */
	ctx->src = bdisp_dflt_fmt;
	ctx->dst = bdisp_dflt_fmt;

	/* Setup the device context for mem2mem mode. */
	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(bdisp->m2m.m2m_dev, ctx,
					    queue_init);
	if (IS_ERR(ctx->fh.m2m_ctx)) {
		dev_err(bdisp->dev, "Failed to initialize m2m context\n");
		ret = PTR_ERR(ctx->fh.m2m_ctx);
		goto error_ctrls;
	}

	bdisp->m2m.refcnt++;
	set_bit(ST_M2M_OPEN, &bdisp->state);

	dev_dbg(bdisp->dev, "driver opened, ctx = 0x%p\n", ctx);

	mutex_unlock(&bdisp->lock);

	return 0;

error_ctrls:
	bdisp_ctrls_delete(ctx);
error_fh:
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	bdisp_hw_free_nodes(ctx);
mem_ctx:
	kfree(ctx);
unlock:
	mutex_unlock(&bdisp->lock);

	return ret;
}

static int bdisp_release(struct file *file)
{
	struct bdisp_ctx *ctx = fh_to_ctx(file->private_data);
	struct bdisp_dev *bdisp = ctx->bdisp_dev;

	dev_dbg(bdisp->dev, "%s\n", __func__);

	if (mutex_lock_interruptible(&bdisp->lock))
		return -ERESTARTSYS;

	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);

	bdisp_ctrls_delete(ctx);

	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);

	if (--bdisp->m2m.refcnt <= 0)
		clear_bit(ST_M2M_OPEN, &bdisp->state);

	bdisp_hw_free_nodes(ctx);

	kfree(ctx);

	mutex_unlock(&bdisp->lock);

	return 0;
}

static const struct v4l2_file_operations bdisp_fops = {
	.owner          = THIS_MODULE,
	.open           = bdisp_open,
	.release        = bdisp_release,
	.poll           = v4l2_m2m_fop_poll,
	.unlocked_ioctl = video_ioctl2,
	.mmap           = v4l2_m2m_fop_mmap,
};

static int bdisp_querycap(struct file *file, void *fh,
			  struct v4l2_capability *cap)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	struct bdisp_dev *bdisp = ctx->bdisp_dev;

	strlcpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver));
	strlcpy(cap->card, bdisp->pdev->name, sizeof(cap->card));
	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d",
		 BDISP_NAME, bdisp->id);

	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;

	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;

	return 0;
}

static int bdisp_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	const struct bdisp_fmt *fmt;

	if (f->index >= ARRAY_SIZE(bdisp_formats))
		return -EINVAL;

	fmt = &bdisp_formats[f->index];

	if ((fmt->pixelformat == V4L2_PIX_FMT_YUV420) &&
	    (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
		dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n");
		return -EINVAL;
	}
	f->pixelformat = fmt->pixelformat;

	return 0;
}

static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	struct v4l2_pix_format *pix = &f->fmt.pix;
	struct bdisp_frame *frame  = ctx_get_frame(ctx, f->type);

	if (IS_ERR(frame)) {
		dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame);
		return PTR_ERR(frame);
	}

	pix = &f->fmt.pix;
	pix->width = frame->width;
	pix->height = frame->height;
	pix->pixelformat = frame->fmt->pixelformat;
	pix->field = frame->field;
	pix->bytesperline = frame->bytesperline;
	pix->sizeimage = frame->sizeimage;
	pix->colorspace = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
				frame->colorspace : bdisp_dflt_fmt.colorspace;

	return 0;
}

static int bdisp_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	struct v4l2_pix_format *pix = &f->fmt.pix;
	const struct bdisp_fmt *format;
	u32 in_w, in_h;

	format = bdisp_find_fmt(pix->pixelformat);
	if (!format) {
		dev_dbg(ctx->bdisp_dev->dev, "Unknown format 0x%x\n",
			pix->pixelformat);
		return -EINVAL;
	}

	/* YUV420P only supported for VIDEO_OUTPUT */
	if ((format->pixelformat == V4L2_PIX_FMT_YUV420) &&
	    (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
		dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n");
		return -EINVAL;
	}

	/* Field (interlaced only supported on OUTPUT) */
	if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
	    (pix->field != V4L2_FIELD_INTERLACED))
		pix->field = V4L2_FIELD_NONE;

	/* Adjust width & height */
	in_w = pix->width;
	in_h = pix->height;
	v4l_bound_align_image(&pix->width,
			      BDISP_MIN_W, BDISP_MAX_W,
			      ffs(format->w_align) - 1,
			      &pix->height,
			      BDISP_MIN_H, BDISP_MAX_H,
			      ffs(format->h_align) - 1,
			      0);
	if ((pix->width != in_w) || (pix->height != in_h))
		dev_dbg(ctx->bdisp_dev->dev,
			"%s size updated: %dx%d -> %dx%d\n", __func__,
			in_w, in_h, pix->width, pix->height);

	pix->bytesperline = (pix->width * format->bpp_plane0) / 8;
	pix->sizeimage = (pix->width * pix->height * format->bpp) / 8;

	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
		pix->colorspace = bdisp_dflt_fmt.colorspace;

	return 0;
}

static int bdisp_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	struct vb2_queue *vq;
	struct bdisp_frame *frame;
	struct v4l2_pix_format *pix;
	int ret;
	u32 state;

	ret = bdisp_try_fmt(file, fh, f);
	if (ret) {
		dev_err(ctx->bdisp_dev->dev, "Cannot set format\n");
		return ret;
	}

	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
	if (vb2_is_streaming(vq)) {
		dev_err(ctx->bdisp_dev->dev, "queue (%d) busy\n", f->type);
		return -EBUSY;
	}

	frame = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
			&ctx->src : &ctx->dst;
	pix = &f->fmt.pix;
	frame->fmt = bdisp_find_fmt(pix->pixelformat);
	if (!frame->fmt) {
		dev_err(ctx->bdisp_dev->dev, "Unknown format 0x%x\n",
			pix->pixelformat);
		return -EINVAL;
	}

	frame->width = pix->width;
	frame->height = pix->height;
	frame->bytesperline = pix->bytesperline;
	frame->sizeimage = pix->sizeimage;
	frame->field = pix->field;
	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
		frame->colorspace = pix->colorspace;

	frame->crop.width = frame->width;
	frame->crop.height = frame->height;
	frame->crop.left = 0;
	frame->crop.top = 0;

	state = BDISP_PARAMS;
	state |= (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
			BDISP_DST_FMT : BDISP_SRC_FMT;
	bdisp_ctx_state_lock_set(state, ctx);

	return 0;
}

static int bdisp_g_selection(struct file *file, void *fh,
			     struct v4l2_selection *s)
{
	struct bdisp_frame *frame;
	struct bdisp_ctx *ctx = fh_to_ctx(fh);

	frame = ctx_get_frame(ctx, s->type);
	if (IS_ERR(frame)) {
		dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame);
		return PTR_ERR(frame);
	}

	switch (s->type) {
	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
		switch (s->target) {
		case V4L2_SEL_TGT_CROP:
			/* cropped frame */
			s->r = frame->crop;
			break;
		case V4L2_SEL_TGT_CROP_DEFAULT:
		case V4L2_SEL_TGT_CROP_BOUNDS:
			/* complete frame */
			s->r.left = 0;
			s->r.top = 0;
			s->r.width = frame->width;
			s->r.height = frame->height;
			break;
		default:
			dev_err(ctx->bdisp_dev->dev, "Invalid target\n");
			return -EINVAL;
		}
		break;

	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		switch (s->target) {
		case V4L2_SEL_TGT_COMPOSE:
		case V4L2_SEL_TGT_COMPOSE_PADDED:
			/* composed (cropped) frame */
			s->r = frame->crop;
			break;
		case V4L2_SEL_TGT_COMPOSE_DEFAULT:
		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
			/* complete frame */
			s->r.left = 0;
			s->r.top = 0;
			s->r.width = frame->width;
			s->r.height = frame->height;
			break;
		default:
			dev_err(ctx->bdisp_dev->dev, "Invalid target\n");
			return -EINVAL;
		}
		break;

	default:
		dev_err(ctx->bdisp_dev->dev, "Invalid type\n");
		return -EINVAL;
	}

	return 0;
}

static int is_rect_enclosed(struct v4l2_rect *a, struct v4l2_rect *b)
{
	/* Return 1 if a is enclosed in b, or 0 otherwise. */

	if (a->left < b->left || a->top < b->top)
		return 0;

	if (a->left + a->width > b->left + b->width)
		return 0;

	if (a->top + a->height > b->top + b->height)
		return 0;

	return 1;
}

static int bdisp_s_selection(struct file *file, void *fh,
			     struct v4l2_selection *s)
{
	struct bdisp_frame *frame;
	struct bdisp_ctx *ctx = fh_to_ctx(fh);
	struct v4l2_rect *in, out;
	bool valid = false;

	if ((s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) &&
	    (s->target == V4L2_SEL_TGT_CROP))
		valid = true;

	if ((s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
	    (s->target == V4L2_SEL_TGT_COMPOSE))
		valid = true;

	if (!valid) {
		dev_err(ctx->bdisp_dev->dev, "Invalid type / target\n");
		return -EINVAL;
	}

	frame = ctx_get_frame(ctx, s->type);
	if (IS_ERR(frame)) {
		dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame);
		return PTR_ERR(frame);
	}

	in = &s->r;
	out = *in;

	/* Align and check origin */
	out.left = ALIGN(in->left, frame->fmt->w_align);
	out.top = ALIGN(in->top, frame->fmt->h_align);

	if ((out.left < 0) || (out.left >= frame->width) ||
	    (out.top < 0) || (out.top >= frame->height)) {
		dev_err(ctx->bdisp_dev->dev,
			"Invalid crop: %dx%d@(%d,%d) vs frame: %dx%d\n",
			out.width, out.height, out.left, out.top,
			frame->width, frame->height);
		return -EINVAL;
	}

	/* Align and check size */
	out.width = ALIGN(in->width, frame->fmt->w_align);
	out.height = ALIGN(in->height, frame->fmt->w_align);

	if (((out.left + out.width) > frame->width) ||
	    ((out.top + out.height) > frame->height)) {
		dev_err(ctx->bdisp_dev->dev,
			"Invalid crop: %dx%d@(%d,%d) vs frame: %dx%d\n",
			out.width, out.height, out.left, out.top,
			frame->width, frame->height);
		return -EINVAL;
	}

	/* Checks adjust constraints flags */
	if (s->flags & V4L2_SEL_FLAG_LE && !is_rect_enclosed(&out, in))
		return -ERANGE;

	if (s->flags & V4L2_SEL_FLAG_GE && !is_rect_enclosed(in, &out))
		return -ERANGE;

	if ((out.left != in->left) || (out.top != in->top) ||
	    (out.width != in->width) || (out.height != in->height)) {
		dev_dbg(ctx->bdisp_dev->dev,
			"%s crop updated: %dx%d@(%d,%d) -> %dx%d@(%d,%d)\n",
			__func__, in->width, in->height, in->left, in->top,
			out.width, out.height, out.left, out.top);
		*in = out;
	}

	frame->crop = out;

	bdisp_ctx_state_lock_set(BDISP_PARAMS, ctx);

	return 0;
}

static int bdisp_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
{
	struct bdisp_ctx *ctx = fh_to_ctx(fh);

	if ((type == V4L2_BUF_TYPE_VIDEO_OUTPUT) &&
	    !bdisp_ctx_state_is_set(BDISP_SRC_FMT, ctx)) {
		dev_err(ctx->bdisp_dev->dev, "src not defined\n");
		return -EINVAL;
	}

	if ((type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
	    !bdisp_ctx_state_is_set(BDISP_DST_FMT, ctx)) {
		dev_err(ctx->bdisp_dev->dev, "dst not defined\n");
		return -EINVAL;
	}

	return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type);
}

static const struct v4l2_ioctl_ops bdisp_ioctl_ops = {
	.vidioc_querycap                = bdisp_querycap,
	.vidioc_enum_fmt_vid_cap        = bdisp_enum_fmt,
	.vidioc_enum_fmt_vid_out        = bdisp_enum_fmt,
	.vidioc_g_fmt_vid_cap           = bdisp_g_fmt,
	.vidioc_g_fmt_vid_out           = bdisp_g_fmt,
	.vidioc_try_fmt_vid_cap         = bdisp_try_fmt,
	.vidioc_try_fmt_vid_out         = bdisp_try_fmt,
	.vidioc_s_fmt_vid_cap           = bdisp_s_fmt,
	.vidioc_s_fmt_vid_out           = bdisp_s_fmt,
	.vidioc_g_selection		= bdisp_g_selection,
	.vidioc_s_selection		= bdisp_s_selection,
	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
	.vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
	.vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
	.vidioc_streamon                = bdisp_streamon,
	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
	.vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
	.vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
};

static int bdisp_register_device(struct bdisp_dev *bdisp)
{
	int ret;

	if (!bdisp)
		return -ENODEV;

	bdisp->vdev.fops        = &bdisp_fops;
	bdisp->vdev.ioctl_ops   = &bdisp_ioctl_ops;
	bdisp->vdev.release     = video_device_release_empty;
	bdisp->vdev.lock        = &bdisp->lock;
	bdisp->vdev.vfl_dir     = VFL_DIR_M2M;
	bdisp->vdev.v4l2_dev    = &bdisp->v4l2_dev;
	snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d",
		 BDISP_NAME, bdisp->id);

	video_set_drvdata(&bdisp->vdev, bdisp);

	bdisp->m2m.vdev = &bdisp->vdev;
	bdisp->m2m.m2m_dev = v4l2_m2m_init(&bdisp_m2m_ops);
	if (IS_ERR(bdisp->m2m.m2m_dev)) {
		dev_err(bdisp->dev, "failed to initialize v4l2-m2m device\n");
		return PTR_ERR(bdisp->m2m.m2m_dev);
	}

	ret = video_register_device(&bdisp->vdev, VFL_TYPE_GRABBER, -1);
	if (ret) {
		dev_err(bdisp->dev,
			"%s(): failed to register video device\n", __func__);
		v4l2_m2m_release(bdisp->m2m.m2m_dev);
		return ret;
	}

	return 0;
}

static void bdisp_unregister_device(struct bdisp_dev *bdisp)
{
	if (!bdisp)
		return;

	if (bdisp->m2m.m2m_dev)
		v4l2_m2m_release(bdisp->m2m.m2m_dev);

	video_unregister_device(bdisp->m2m.vdev);
}

static irqreturn_t bdisp_irq_thread(int irq, void *priv)
{
	struct bdisp_dev *bdisp = priv;
	struct bdisp_ctx *ctx;

	spin_lock(&bdisp->slock);

	bdisp_dbg_perf_end(bdisp);

	cancel_delayed_work(&bdisp->timeout_work);

	if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state))
		goto isr_unlock;

	if (test_and_clear_bit(ST_M2M_SUSPENDING, &bdisp->state)) {
		set_bit(ST_M2M_SUSPENDED, &bdisp->state);
		wake_up(&bdisp->irq_queue);
		goto isr_unlock;
	}

	ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev);
	if (!ctx || !ctx->fh.m2m_ctx)
		goto isr_unlock;

	spin_unlock(&bdisp->slock);

	bdisp_job_finish(ctx, VB2_BUF_STATE_DONE);

	if (bdisp_ctx_state_is_set(BDISP_CTX_STOP_REQ, ctx)) {
		bdisp_ctx_state_lock_clear(BDISP_CTX_STOP_REQ, ctx);
		wake_up(&bdisp->irq_queue);
	}

	return IRQ_HANDLED;

isr_unlock:
	spin_unlock(&bdisp->slock);

	return IRQ_HANDLED;
}

static irqreturn_t bdisp_irq_handler(int irq, void *priv)
{
	if (bdisp_hw_get_and_clear_irq((struct bdisp_dev *)priv))
		return IRQ_NONE;
	else
		return IRQ_WAKE_THREAD;
}

static void bdisp_irq_timeout(struct work_struct *ptr)
{
	struct delayed_work *twork = to_delayed_work(ptr);
	struct bdisp_dev *bdisp = container_of(twork, struct bdisp_dev,
			timeout_work);
	struct bdisp_ctx *ctx;

	ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev);

	dev_err(ctx->bdisp_dev->dev, "Device work timeout\n");

	spin_lock(&bdisp->slock);
	clear_bit(ST_M2M_RUNNING, &bdisp->state);
	spin_unlock(&bdisp->slock);

	bdisp_hw_reset(bdisp);

	bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR);
}

static int bdisp_m2m_suspend(struct bdisp_dev *bdisp)
{
	unsigned long flags;
	int timeout;

	spin_lock_irqsave(&bdisp->slock, flags);
	if (!test_bit(ST_M2M_RUNNING, &bdisp->state)) {
		spin_unlock_irqrestore(&bdisp->slock, flags);
		return 0;
	}
	clear_bit(ST_M2M_SUSPENDED, &bdisp->state);
	set_bit(ST_M2M_SUSPENDING, &bdisp->state);
	spin_unlock_irqrestore(&bdisp->slock, flags);

	timeout = wait_event_timeout(bdisp->irq_queue,
				     test_bit(ST_M2M_SUSPENDED, &bdisp->state),
				     BDISP_WORK_TIMEOUT);

	clear_bit(ST_M2M_SUSPENDING, &bdisp->state);

	if (!timeout) {
		dev_err(bdisp->dev, "%s IRQ timeout\n", __func__);
		return -EAGAIN;
	}

	return 0;
}

static int bdisp_m2m_resume(struct bdisp_dev *bdisp)
{
	struct bdisp_ctx *ctx;
	unsigned long flags;

	spin_lock_irqsave(&bdisp->slock, flags);
	ctx = bdisp->m2m.ctx;
	bdisp->m2m.ctx = NULL;
	spin_unlock_irqrestore(&bdisp->slock, flags);

	if (test_and_clear_bit(ST_M2M_SUSPENDED, &bdisp->state))
		bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR);

	return 0;
}

static int bdisp_runtime_resume(struct device *dev)
{
	struct bdisp_dev *bdisp = dev_get_drvdata(dev);
	int ret = clk_enable(bdisp->clock);

	if (ret)
		return ret;

	return bdisp_m2m_resume(bdisp);
}

static int bdisp_runtime_suspend(struct device *dev)
{
	struct bdisp_dev *bdisp = dev_get_drvdata(dev);
	int ret = bdisp_m2m_suspend(bdisp);

	if (!ret)
		clk_disable(bdisp->clock);

	return ret;
}

static int bdisp_resume(struct device *dev)
{
	struct bdisp_dev *bdisp = dev_get_drvdata(dev);
	unsigned long flags;
	int opened;

	spin_lock_irqsave(&bdisp->slock, flags);
	opened = test_bit(ST_M2M_OPEN, &bdisp->state);
	spin_unlock_irqrestore(&bdisp->slock, flags);

	if (!opened)
		return 0;

	if (!pm_runtime_suspended(dev))
		return bdisp_runtime_resume(dev);

	return 0;
}

static int bdisp_suspend(struct device *dev)
{
	if (!pm_runtime_suspended(dev))
		return bdisp_runtime_suspend(dev);

	return 0;
}

static const struct dev_pm_ops bdisp_pm_ops = {
	.suspend                = bdisp_suspend,
	.resume                 = bdisp_resume,
	.runtime_suspend        = bdisp_runtime_suspend,
	.runtime_resume         = bdisp_runtime_resume,
};

static int bdisp_remove(struct platform_device *pdev)
{
	struct bdisp_dev *bdisp = platform_get_drvdata(pdev);

	bdisp_unregister_device(bdisp);

	bdisp_hw_free_filters(bdisp->dev);

	vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx);

	pm_runtime_disable(&pdev->dev);

	bdisp_debugfs_remove(bdisp);

	v4l2_device_unregister(&bdisp->v4l2_dev);

	if (!IS_ERR(bdisp->clock))
		clk_unprepare(bdisp->clock);

	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);

	return 0;
}

static int bdisp_probe(struct platform_device *pdev)
{
	struct bdisp_dev *bdisp;
	struct resource *res;
	struct device *dev = &pdev->dev;
	int ret;

	dev_dbg(dev, "%s\n", __func__);

	bdisp = devm_kzalloc(dev, sizeof(struct bdisp_dev), GFP_KERNEL);
	if (!bdisp)
		return -ENOMEM;

	bdisp->pdev = pdev;
	bdisp->dev = dev;
	platform_set_drvdata(pdev, bdisp);

	if (dev->of_node)
		bdisp->id = of_alias_get_id(pdev->dev.of_node, BDISP_NAME);
	else
		bdisp->id = pdev->id;

	init_waitqueue_head(&bdisp->irq_queue);
	INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout);
	bdisp->work_queue = create_workqueue(BDISP_NAME);

	spin_lock_init(&bdisp->slock);
	mutex_init(&bdisp->lock);

	/* get resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	bdisp->regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(bdisp->regs)) {
		dev_err(dev, "failed to get regs\n");
		return PTR_ERR(bdisp->regs);
	}

	bdisp->clock = devm_clk_get(dev, BDISP_NAME);
	if (IS_ERR(bdisp->clock)) {
		dev_err(dev, "failed to get clock\n");
		return PTR_ERR(bdisp->clock);
	}

	ret = clk_prepare(bdisp->clock);
	if (ret < 0) {
		dev_err(dev, "clock prepare failed\n");
		bdisp->clock = ERR_PTR(-EINVAL);
		return ret;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(dev, "failed to get IRQ resource\n");
		goto err_clk;
	}

	ret = devm_request_threaded_irq(dev, res->start, bdisp_irq_handler,
					bdisp_irq_thread, IRQF_ONESHOT,
					pdev->name, bdisp);
	if (ret) {
		dev_err(dev, "failed to install irq\n");
		goto err_clk;
	}

	/* v4l2 register */
	ret = v4l2_device_register(dev, &bdisp->v4l2_dev);
	if (ret) {
		dev_err(dev, "failed to register\n");
		goto err_clk;
	}

	/* Debug */
	ret = bdisp_debugfs_create(bdisp);
	if (ret) {
		dev_err(dev, "failed to create debugfs\n");
		goto err_v4l2;
	}

	/* Power management */
	pm_runtime_enable(dev);
	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		dev_err(dev, "failed to set PM\n");
		goto err_dbg;
	}

	/* Continuous memory allocator */
	bdisp->alloc_ctx = vb2_dma_contig_init_ctx(dev);
	if (IS_ERR(bdisp->alloc_ctx)) {
		ret = PTR_ERR(bdisp->alloc_ctx);
		goto err_pm;
	}

	/* Filters */
	if (bdisp_hw_alloc_filters(bdisp->dev)) {
		dev_err(bdisp->dev, "no memory for filters\n");
		ret = -ENOMEM;
		goto err_vb2_dma;
	}

	/* Register */
	ret = bdisp_register_device(bdisp);
	if (ret) {
		dev_err(dev, "failed to register\n");
		goto err_filter;
	}

	dev_info(dev, "%s%d registered as /dev/video%d\n", BDISP_NAME,
		 bdisp->id, bdisp->vdev.num);

	pm_runtime_put(dev);

	return 0;

err_filter:
	bdisp_hw_free_filters(bdisp->dev);
err_vb2_dma:
	vb2_dma_contig_cleanup_ctx(bdisp->alloc_ctx);
err_pm:
	pm_runtime_put(dev);
err_dbg:
	bdisp_debugfs_remove(bdisp);
err_v4l2:
	v4l2_device_unregister(&bdisp->v4l2_dev);
err_clk:
	if (!IS_ERR(bdisp->clock))
		clk_unprepare(bdisp->clock);

	return ret;
}

static const struct of_device_id bdisp_match_types[] = {
	{
		.compatible = "st,stih407-bdisp",
	},
	{ /* end node */ }
};

MODULE_DEVICE_TABLE(of, bdisp_match_types);

static struct platform_driver bdisp_driver = {
	.probe          = bdisp_probe,
	.remove         = bdisp_remove,
	.driver         = {
		.name           = BDISP_NAME,
		.of_match_table = bdisp_match_types,
		.pm             = &bdisp_pm_ops,
	},
};

module_platform_driver(bdisp_driver);

MODULE_DESCRIPTION("2D blitter for STMicroelectronics SoC");
MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
MODULE_LICENSE("GPL");
