static irqreturn_t flite_irq_handler(int irq, void *priv)
{
	struct flite_dev *flite = priv;
	u32 int_src = 0;

	flite_hw_get_int_src(flite, &int_src);
	flite_hw_clear_irq(flite);

	spin_lock(&flite->slock);

	switch (int_src & FLITE_REG_CISTATUS_IRQ_MASK) {
	case FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW:
		flite_dbg("overflow generated");
		break;
	case FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND:
		flite_hw_set_last_capture_end_clear(flite);
		flite_dbg("last capture end");
		clear_bit(FLITE_ST_STREAMING, &flite->state);
		wake_up(&flite->irq_queue);
		break;
	case FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART:
		flite_dbg("frame start");
		break;
	case FLITE_REG_CISTATUS_IRQ_SRC_FRMEND:
		flite_dbg("frame end");
		break;
	}

	spin_unlock(&flite->slock);

	return IRQ_HANDLED;
}
void flite_hw_set_output_addr(struct flite_dev *dev,
			     struct flite_addr *addr, int index)
{
	flite_dbg("dst_buf[%d]: 0x%X", index, addr->y);

	writel(addr->y, dev->regs + FLITE_REG_CIOSA);
}
static int flite_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
	struct flite_dev *flite = to_flite_dev(sd);
	struct flite_fmt const *f_fmt = find_flite_format(mf);
	struct flite_frame *f_frame = &flite->source_frame;

	flite_dbg("w: %d, h: %d", mf->width, mf->height);

	if (unlikely(!f_fmt)) {
		flite_err("f_fmt is null");
		return -EINVAL;
	}

	flite->mbus_fmt = *mf;

	/*
	 * These are the datas from fimc
	 * If you want to crop the image, you can use s_crop
	 */
	f_frame->o_width = mf->width;
	f_frame->o_height = mf->height;
	f_frame->width = mf->width;
	f_frame->height = mf->height;
	f_frame->offs_h = 0;
	f_frame->offs_v = 0;

	return 0;
}
void flite_hw_set_output_addr(struct flite_dev *dev,
                              struct flite_addr *addr, int index)
{
    flite_dbg("dst_buf[%d]: 0x%X", index, addr->y);

    if (soc_is_exynos5250_rev1) {
        writel(addr->y, dev->regs + FLITE_REG_CIOSA(index));
    } else {
        writel(addr->y, dev->regs + FLITE_REG_CIOSA(0));
    }
}
void flite_hw_set_output_addr(struct flite_dev *dev,
			     struct flite_addr *addr, int index)
{
	u32 cfg = 0;

	flite_dbg("dst_buf[%d]: 0x%X", index, addr->y);

	cfg = readl(dev->regs + FLITE_REG_CIOSA(index));
	if (!cfg) {
		writel(addr->y, dev->regs + FLITE_REG_CIOSA(index));
	} else if (cfg != addr->y) {
		flite_err("address is invalid(%08X != %08X)\n", cfg, addr->y);
		writel(addr->y, dev->regs + FLITE_REG_CIOSA(index));
	}
}
void flite_hw_reset(struct flite_dev *dev)
{
	u32 cfg = 0;
	unsigned long timeo = jiffies + FLITE_MAX_RESET_READY_TIME;

	cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
	cfg |= FLITE_REG_CIGCTRL_SWRST_REQ;
	writel(cfg, dev->regs + FLITE_REG_CIGCTRL);

	do {
		if (cfg & FLITE_REG_CIGCTRL_SWRST_RDY)
			break;
		usleep_range(1000, 5000);
	} while (time_before(jiffies, timeo));

	flite_dbg("wait time : %d ms",
		jiffies_to_msecs(jiffies - timeo + FLITE_MAX_RESET_READY_TIME));

	cfg |= FLITE_REG_CIGCTRL_SWRST;
	writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
}
static int flite_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop)
{
	struct flite_dev *flite = to_flite_dev(sd);
	struct flite_frame *f;

	f = &flite->source_frame;

	if (crop->c.left + crop->c.width > f->o_width)
		return -EINVAL;
	if (crop->c.top + crop->c.height > f->o_height)
		return -EINVAL;

	f->width = crop->c.width;
	f->height = crop->c.height;
	f->offs_h = crop->c.left;
	f->offs_v = crop->c.top;

	flite_dbg("width : %d, height : %d, offs_h : %d, off_v : %dn",
			f->width, f->height, f->offs_h, f->offs_v);

	return 0;
}
static void flite_subdev_unregistered(struct v4l2_subdev *sd)
{
	flite_dbg("");
}
static int flite_subdev_registered(struct v4l2_subdev *sd)
{
	flite_dbg("");
	return 0;
}