/*
 * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
 *
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 *
 * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
 *          Younghwan Joo <yhwan.joo@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.
 */
#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__

#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-contiguous.h>
#include <linux/errno.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <media/videobuf2-dma-contig.h>

#include "media-dev.h"
#include "fimc-is.h"
#include "fimc-is-command.h"
#include "fimc-is-errno.h"
#include "fimc-is-i2c.h"
#include "fimc-is-param.h"
#include "fimc-is-regs.h"


static char *fimc_is_clocks[ISS_CLKS_MAX] = {
	[ISS_CLK_PPMUISPX]		= "ppmuispx",
	[ISS_CLK_PPMUISPMX]		= "ppmuispmx",
	[ISS_CLK_LITE0]			= "lite0",
	[ISS_CLK_LITE1]			= "lite1",
	[ISS_CLK_MPLL]			= "mpll",
	[ISS_CLK_ISP]			= "isp",
	[ISS_CLK_DRC]			= "drc",
	[ISS_CLK_FD]			= "fd",
	[ISS_CLK_MCUISP]		= "mcuisp",
	[ISS_CLK_UART]			= "uart",
	[ISS_CLK_ISP_DIV0]		= "ispdiv0",
	[ISS_CLK_ISP_DIV1]		= "ispdiv1",
	[ISS_CLK_MCUISP_DIV0]		= "mcuispdiv0",
	[ISS_CLK_MCUISP_DIV1]		= "mcuispdiv1",
	[ISS_CLK_ACLK200]		= "aclk200",
	[ISS_CLK_ACLK200_DIV]		= "div_aclk200",
	[ISS_CLK_ACLK400MCUISP]		= "aclk400mcuisp",
	[ISS_CLK_ACLK400MCUISP_DIV]	= "div_aclk400mcuisp",
};

static void fimc_is_put_clocks(struct fimc_is *is)
{
	int i;

	for (i = 0; i < ISS_CLKS_MAX; i++) {
		if (IS_ERR(is->clocks[i]))
			continue;
		clk_put(is->clocks[i]);
		is->clocks[i] = ERR_PTR(-EINVAL);
	}
}

static int fimc_is_get_clocks(struct fimc_is *is)
{
	int i, ret;

	for (i = 0; i < ISS_CLKS_MAX; i++)
		is->clocks[i] = ERR_PTR(-EINVAL);

	for (i = 0; i < ISS_CLKS_MAX; i++) {
		is->clocks[i] = clk_get(&is->pdev->dev, fimc_is_clocks[i]);
		if (IS_ERR(is->clocks[i])) {
			ret = PTR_ERR(is->clocks[i]);
			goto err;
		}
	}

	return 0;
err:
	fimc_is_put_clocks(is);
	dev_err(&is->pdev->dev, "failed to get clock: %s\n",
		fimc_is_clocks[i]);
	return ret;
}

static int fimc_is_setup_clocks(struct fimc_is *is)
{
	int ret;

	ret = clk_set_parent(is->clocks[ISS_CLK_ACLK200],
					is->clocks[ISS_CLK_ACLK200_DIV]);
	if (ret < 0)
		return ret;

	ret = clk_set_parent(is->clocks[ISS_CLK_ACLK400MCUISP],
					is->clocks[ISS_CLK_ACLK400MCUISP_DIV]);
	if (ret < 0)
		return ret;

	ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV0], ACLK_AXI_FREQUENCY);
	if (ret < 0)
		return ret;

	ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV1], ACLK_AXI_FREQUENCY);
	if (ret < 0)
		return ret;

	ret = clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV0],
					ATCLK_MCUISP_FREQUENCY);
	if (ret < 0)
		return ret;

	return clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV1],
					ATCLK_MCUISP_FREQUENCY);
}

static int fimc_is_enable_clocks(struct fimc_is *is)
{
	int i, ret;

	for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
		if (IS_ERR(is->clocks[i]))
			continue;
		ret = clk_prepare_enable(is->clocks[i]);
		if (ret < 0) {
			dev_err(&is->pdev->dev, "clock %s enable failed\n",
				fimc_is_clocks[i]);
			for (--i; i >= 0; i--)
				clk_disable(is->clocks[i]);
			return ret;
		}
		pr_debug("enabled clock: %s\n", fimc_is_clocks[i]);
	}
	return 0;
}

static void fimc_is_disable_clocks(struct fimc_is *is)
{
	int i;

	for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
		if (!IS_ERR(is->clocks[i])) {
			clk_disable_unprepare(is->clocks[i]);
			pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
		}
	}
}

static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
						struct device_node *node)
{
	struct fimc_is_sensor *sensor = &is->sensor[index];
	u32 tmp = 0;
	int ret;

	sensor->drvdata = fimc_is_sensor_get_drvdata(node);
	if (!sensor->drvdata) {
		dev_err(&is->pdev->dev, "no driver data found for: %s\n",
							 node->full_name);
		return -EINVAL;
	}

	node = of_graph_get_next_endpoint(node, NULL);
	if (!node)
		return -ENXIO;

	node = of_graph_get_remote_port(node);
	if (!node)
		return -ENXIO;

	/* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */
	ret = of_property_read_u32(node, "reg", &tmp);
	if (ret < 0) {
		dev_err(&is->pdev->dev, "reg property not found at: %s\n",
							 node->full_name);
		return ret;
	}

	sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
	return 0;
}

static int fimc_is_register_subdevs(struct fimc_is *is)
{
	struct device_node *i2c_bus, *child;
	int ret, index = 0;

	ret = fimc_isp_subdev_create(&is->isp);
	if (ret < 0)
		return ret;

	/* Initialize memory allocator context for the ISP DMA. */
	is->isp.alloc_ctx = is->alloc_ctx;

	for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {
		for_each_available_child_of_node(i2c_bus, child) {
			ret = fimc_is_parse_sensor_config(is, index, child);

			if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
				of_node_put(child);
				return ret;
			}
			index++;
		}
	}
	return 0;
}

static int fimc_is_unregister_subdevs(struct fimc_is *is)
{
	fimc_isp_subdev_destroy(&is->isp);
	return 0;
}

static int fimc_is_load_setfile(struct fimc_is *is, char *file_name)
{
	const struct firmware *fw;
	void *buf;
	int ret;

	ret = request_firmware(&fw, file_name, &is->pdev->dev);
	if (ret < 0) {
		dev_err(&is->pdev->dev, "firmware request failed (%d)\n", ret);
		return ret;
	}
	buf = is->memory.vaddr + is->setfile.base;
	memcpy(buf, fw->data, fw->size);
	fimc_is_mem_barrier();
	is->setfile.size = fw->size;

	pr_debug("mem vaddr: %p, setfile buf: %p\n", is->memory.vaddr, buf);

	memcpy(is->fw.setfile_info,
		fw->data + fw->size - FIMC_IS_SETFILE_INFO_LEN,
		FIMC_IS_SETFILE_INFO_LEN - 1);

	is->fw.setfile_info[FIMC_IS_SETFILE_INFO_LEN - 1] = '\0';
	is->setfile.state = 1;

	pr_debug("FIMC-IS setfile loaded: base: %#x, size: %zu B\n",
		 is->setfile.base, fw->size);

	release_firmware(fw);
	return ret;
}

int fimc_is_cpu_set_power(struct fimc_is *is, int on)
{
	unsigned int timeout = FIMC_IS_POWER_ON_TIMEOUT;

	if (on) {
		/* Disable watchdog */
		mcuctl_write(0, is, REG_WDT_ISP);

		/* Cortex-A5 start address setting */
		mcuctl_write(is->memory.paddr, is, MCUCTL_REG_BBOAR);

		/* Enable and start Cortex-A5 */
		pmuisp_write(0x18000, is, REG_PMU_ISP_ARM_OPTION);
		pmuisp_write(0x1, is, REG_PMU_ISP_ARM_CONFIGURATION);
	} else {
		/* A5 power off */
		pmuisp_write(0x10000, is, REG_PMU_ISP_ARM_OPTION);
		pmuisp_write(0x0, is, REG_PMU_ISP_ARM_CONFIGURATION);

		while (pmuisp_read(is, REG_PMU_ISP_ARM_STATUS) & 1) {
			if (timeout == 0)
				return -ETIME;
			timeout--;
			udelay(1);
		}
	}

	return 0;
}

/* Wait until @bit of @is->state is set to @state in the interrupt handler. */
int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,
		       unsigned int state, unsigned int timeout)
{

	int ret = wait_event_timeout(is->irq_queue,
				     !state ^ test_bit(bit, &is->state),
				     timeout);
	if (ret == 0) {
		dev_WARN(&is->pdev->dev, "%s() timed out\n", __func__);
		return -ETIME;
	}
	return 0;
}

int fimc_is_start_firmware(struct fimc_is *is)
{
	struct device *dev = &is->pdev->dev;
	int ret;

	if (is->fw.f_w == NULL) {
		dev_err(dev, "firmware is not loaded\n");
		return -EINVAL;
	}

	memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size);
	wmb();

	ret = fimc_is_cpu_set_power(is, 1);
	if (ret < 0)
		return ret;

	ret = fimc_is_wait_event(is, IS_ST_A5_PWR_ON, 1,
				 msecs_to_jiffies(FIMC_IS_FW_LOAD_TIMEOUT));
	if (ret < 0)
		dev_err(dev, "FIMC-IS CPU power on failed\n");

	return ret;
}

/* Allocate working memory for the FIMC-IS CPU. */
static int fimc_is_alloc_cpu_memory(struct fimc_is *is)
{
	struct device *dev = &is->pdev->dev;

	is->memory.vaddr = dma_alloc_coherent(dev, FIMC_IS_CPU_MEM_SIZE,
					      &is->memory.paddr, GFP_KERNEL);
	if (is->memory.vaddr == NULL)
		return -ENOMEM;

	is->memory.size = FIMC_IS_CPU_MEM_SIZE;
	memset(is->memory.vaddr, 0, is->memory.size);

	dev_info(dev, "FIMC-IS CPU memory base: %#x\n", (u32)is->memory.paddr);

	if (((u32)is->memory.paddr) & FIMC_IS_FW_ADDR_MASK) {
		dev_err(dev, "invalid firmware memory alignment: %#x\n",
			(u32)is->memory.paddr);
		dma_free_coherent(dev, is->memory.size, is->memory.vaddr,
				  is->memory.paddr);
		return -EIO;
	}

	is->is_p_region = (struct is_region *)(is->memory.vaddr +
				FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE);

	is->is_dma_p_region = is->memory.paddr +
				FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE;

	is->is_shared_region = (struct is_share_region *)(is->memory.vaddr +
				FIMC_IS_SHARED_REGION_OFFSET);
	return 0;
}

static void fimc_is_free_cpu_memory(struct fimc_is *is)
{
	struct device *dev = &is->pdev->dev;

	dma_free_coherent(dev, is->memory.size, is->memory.vaddr,
			  is->memory.paddr);
}

static void fimc_is_load_firmware(const struct firmware *fw, void *context)
{
	struct fimc_is *is = context;
	struct device *dev = &is->pdev->dev;
	void *buf;
	int ret;

	if (fw == NULL) {
		dev_err(dev, "firmware request failed\n");
		return;
	}
	mutex_lock(&is->lock);

	if (fw->size < FIMC_IS_FW_SIZE_MIN || fw->size > FIMC_IS_FW_SIZE_MAX) {
		dev_err(dev, "wrong firmware size: %d\n", fw->size);
		goto done;
	}

	is->fw.size = fw->size;

	ret = fimc_is_alloc_cpu_memory(is);
	if (ret < 0) {
		dev_err(dev, "failed to allocate FIMC-IS CPU memory\n");
		goto done;
	}

	memcpy(is->memory.vaddr, fw->data, fw->size);
	wmb();

	/* Read firmware description. */
	buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_DESC_LEN);
	memcpy(&is->fw.info, buf, FIMC_IS_FW_INFO_LEN);
	is->fw.info[FIMC_IS_FW_INFO_LEN] = 0;

	buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_VER_LEN);
	memcpy(&is->fw.version, buf, FIMC_IS_FW_VER_LEN);
	is->fw.version[FIMC_IS_FW_VER_LEN - 1] = 0;

	is->fw.state = 1;

	dev_info(dev, "loaded firmware: %s, rev. %s\n",
		 is->fw.info, is->fw.version);
	dev_dbg(dev, "FW size: %d, paddr: %#x\n", fw->size, is->memory.paddr);

	is->is_shared_region->chip_id = 0xe4412;
	is->is_shared_region->chip_rev_no = 1;

	fimc_is_mem_barrier();

	/*
	 * FIXME: The firmware is not being released for now, as it is
	 * needed around for copying to the IS working memory every
	 * time before the Cortex-A5 is restarted.
	 */
	if (is->fw.f_w)
		release_firmware(is->fw.f_w);
	is->fw.f_w = fw;
done:
	mutex_unlock(&is->lock);
}

static int fimc_is_request_firmware(struct fimc_is *is, const char *fw_name)
{
	return request_firmware_nowait(THIS_MODULE,
				FW_ACTION_HOTPLUG, fw_name, &is->pdev->dev,
				GFP_KERNEL, is, fimc_is_load_firmware);
}

/* General IS interrupt handler */
static void fimc_is_general_irq_handler(struct fimc_is *is)
{
	is->i2h_cmd.cmd = mcuctl_read(is, MCUCTL_REG_ISSR(10));

	switch (is->i2h_cmd.cmd) {
	case IHC_GET_SENSOR_NUM:
		fimc_is_hw_get_params(is, 1);
		fimc_is_hw_wait_intmsr0_intmsd0(is);
		fimc_is_hw_set_sensor_num(is);
		pr_debug("ISP FW version: %#x\n", is->i2h_cmd.args[0]);
		break;
	case IHC_SET_FACE_MARK:
	case IHC_FRAME_DONE:
		fimc_is_hw_get_params(is, 2);
		break;
	case IHC_SET_SHOT_MARK:
	case IHC_AA_DONE:
	case IH_REPLY_DONE:
		fimc_is_hw_get_params(is, 3);
		break;
	case IH_REPLY_NOT_DONE:
		fimc_is_hw_get_params(is, 4);
		break;
	case IHC_NOT_READY:
		break;
	default:
		pr_info("unknown command: %#x\n", is->i2h_cmd.cmd);
	}

	fimc_is_fw_clear_irq1(is, FIMC_IS_INT_GENERAL);

	switch (is->i2h_cmd.cmd) {
	case IHC_GET_SENSOR_NUM:
		fimc_is_hw_set_intgr0_gd0(is);
		set_bit(IS_ST_A5_PWR_ON, &is->state);
		break;

	case IHC_SET_SHOT_MARK:
		break;

	case IHC_SET_FACE_MARK:
		is->fd_header.count = is->i2h_cmd.args[0];
		is->fd_header.index = is->i2h_cmd.args[1];
		is->fd_header.offset = 0;
		break;

	case IHC_FRAME_DONE:
		break;

	case IHC_AA_DONE:
		pr_debug("AA_DONE - %d, %d, %d\n", is->i2h_cmd.args[0],
			 is->i2h_cmd.args[1], is->i2h_cmd.args[2]);
		break;

	case IH_REPLY_DONE:
		pr_debug("ISR_DONE: args[0]: %#x\n", is->i2h_cmd.args[0]);

		switch (is->i2h_cmd.args[0]) {
		case HIC_PREVIEW_STILL...HIC_CAPTURE_VIDEO:
			/* Get CAC margin */
			set_bit(IS_ST_CHANGE_MODE, &is->state);
			is->isp.cac_margin_x = is->i2h_cmd.args[1];
			is->isp.cac_margin_y = is->i2h_cmd.args[2];
			pr_debug("CAC margin (x,y): (%d,%d)\n",
				 is->isp.cac_margin_x, is->isp.cac_margin_y);
			break;

		case HIC_STREAM_ON:
			clear_bit(IS_ST_STREAM_OFF, &is->state);
			set_bit(IS_ST_STREAM_ON, &is->state);
			break;

		case HIC_STREAM_OFF:
			clear_bit(IS_ST_STREAM_ON, &is->state);
			set_bit(IS_ST_STREAM_OFF, &is->state);
			break;

		case HIC_SET_PARAMETER:
			is->config[is->config_index].p_region_index[0] = 0;
			is->config[is->config_index].p_region_index[1] = 0;
			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
			pr_debug("HIC_SET_PARAMETER\n");
			break;

		case HIC_GET_PARAMETER:
			break;

		case HIC_SET_TUNE:
			break;

		case HIC_GET_STATUS:
			break;

		case HIC_OPEN_SENSOR:
			set_bit(IS_ST_OPEN_SENSOR, &is->state);
			pr_debug("data lanes: %d, settle line: %d\n",
				 is->i2h_cmd.args[2], is->i2h_cmd.args[1]);
			break;

		case HIC_CLOSE_SENSOR:
			clear_bit(IS_ST_OPEN_SENSOR, &is->state);
			is->sensor_index = 0;
			break;

		case HIC_MSG_TEST:
			pr_debug("config MSG level completed\n");
			break;

		case HIC_POWER_DOWN:
			clear_bit(IS_ST_PWR_SUBIP_ON, &is->state);
			break;

		case HIC_GET_SET_FILE_ADDR:
			is->setfile.base = is->i2h_cmd.args[1];
			set_bit(IS_ST_SETFILE_LOADED, &is->state);
			break;

		case HIC_LOAD_SET_FILE:
			set_bit(IS_ST_SETFILE_LOADED, &is->state);
			break;
		}
		break;

	case IH_REPLY_NOT_DONE:
		pr_err("ISR_NDONE: %d: %#x, %s\n", is->i2h_cmd.args[0],
		       is->i2h_cmd.args[1],
		       fimc_is_strerr(is->i2h_cmd.args[1]));

		if (is->i2h_cmd.args[1] & IS_ERROR_TIME_OUT_FLAG)
			pr_err("IS_ERROR_TIME_OUT\n");

		switch (is->i2h_cmd.args[1]) {
		case IS_ERROR_SET_PARAMETER:
			fimc_is_mem_barrier();
		}

		switch (is->i2h_cmd.args[0]) {
		case HIC_SET_PARAMETER:
			is->config[is->config_index].p_region_index[0] = 0;
			is->config[is->config_index].p_region_index[1] = 0;
			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
			break;
		}
		break;

	case IHC_NOT_READY:
		pr_err("IS control sequence error: Not Ready\n");
		break;
	}

	wake_up(&is->irq_queue);
}

static irqreturn_t fimc_is_irq_handler(int irq, void *priv)
{
	struct fimc_is *is = priv;
	unsigned long flags;
	u32 status;

	spin_lock_irqsave(&is->slock, flags);
	status = mcuctl_read(is, MCUCTL_REG_INTSR1);

	if (status & (1UL << FIMC_IS_INT_GENERAL))
		fimc_is_general_irq_handler(is);

	if (status & (1UL << FIMC_IS_INT_FRAME_DONE_ISP))
		fimc_isp_irq_handler(is);

	spin_unlock_irqrestore(&is->slock, flags);
	return IRQ_HANDLED;
}

static int fimc_is_hw_open_sensor(struct fimc_is *is,
				  struct fimc_is_sensor *sensor)
{
	struct sensor_open_extended *soe = (void *)&is->is_p_region->shared;

	fimc_is_hw_wait_intmsr0_intmsd0(is);

	soe->self_calibration_mode = 1;
	soe->actuator_type = 0;
	soe->mipi_lane_num = 0;
	soe->mclk = 0;
	soe->mipi_speed	= 0;
	soe->fast_open_sensor = 0;
	soe->i2c_sclk = 88000000;

	fimc_is_mem_barrier();

	mcuctl_write(HIC_OPEN_SENSOR, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(sensor->drvdata->id, is, MCUCTL_REG_ISSR(2));
	mcuctl_write(sensor->i2c_bus, is, MCUCTL_REG_ISSR(3));
	mcuctl_write(is->is_dma_p_region, is, MCUCTL_REG_ISSR(4));

	fimc_is_hw_set_intgr0_gd0(is);

	return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,
				  sensor->drvdata->open_timeout);
}


int fimc_is_hw_initialize(struct fimc_is *is)
{
	const int config_ids[] = {
		IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO,
		IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO
	};
	struct device *dev = &is->pdev->dev;
	u32 prev_id;
	int i, ret;

	/* Sensor initialization. Only one sensor is currently supported. */
	ret = fimc_is_hw_open_sensor(is, &is->sensor[0]);
	if (ret < 0)
		return ret;

	/* Get the setfile address. */
	fimc_is_hw_get_setfile_addr(is);

	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "get setfile address timed out\n");
		return ret;
	}
	pr_debug("setfile.base: %#x\n", is->setfile.base);

	/* Load the setfile. */
	fimc_is_load_setfile(is, FIMC_IS_SETFILE_6A3);
	clear_bit(IS_ST_SETFILE_LOADED, &is->state);
	fimc_is_hw_load_setfile(is);
	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "loading setfile timed out\n");
		return ret;
	}

	pr_debug("setfile: base: %#x, size: %d\n",
		 is->setfile.base, is->setfile.size);
	pr_info("FIMC-IS Setfile info: %s\n", is->fw.setfile_info);

	/* Check magic number. */
	if (is->is_p_region->shared[MAX_SHARED_COUNT - 1] !=
	    FIMC_IS_MAGIC_NUMBER) {
		dev_err(dev, "magic number error!\n");
		return -EIO;
	}

	pr_debug("shared region: %#x, parameter region: %#x\n",
		 is->memory.paddr + FIMC_IS_SHARED_REGION_OFFSET,
		 is->is_dma_p_region);

	is->setfile.sub_index = 0;

	/* Stream off. */
	fimc_is_hw_stream_off(is);
	ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "stream off timeout\n");
		return ret;
	}

	/* Preserve previous mode. */
	prev_id = is->config_index;

	/* Set initial parameter values. */
	for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
		is->config_index = config_ids[i];
		fimc_is_set_initial_params(is);
		ret = fimc_is_itf_s_param(is, true);
		if (ret < 0) {
			is->config_index = prev_id;
			return ret;
		}
	}
	is->config_index = prev_id;

	set_bit(IS_ST_INIT_DONE, &is->state);
	dev_info(dev, "initialization sequence completed (%d)\n",
						is->config_index);
	return 0;
}

static int fimc_is_log_show(struct seq_file *s, void *data)
{
	struct fimc_is *is = s->private;
	const u8 *buf = is->memory.vaddr + FIMC_IS_DEBUG_REGION_OFFSET;

	if (is->memory.vaddr == NULL) {
		dev_err(&is->pdev->dev, "firmware memory is not initialized\n");
		return -EIO;
	}

	seq_printf(s, "%s\n", buf);
	return 0;
}

static int fimc_is_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, fimc_is_log_show, inode->i_private);
}

static const struct file_operations fimc_is_debugfs_fops = {
	.open		= fimc_is_debugfs_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void fimc_is_debugfs_remove(struct fimc_is *is)
{
	debugfs_remove_recursive(is->debugfs_entry);
	is->debugfs_entry = NULL;
}

static int fimc_is_debugfs_create(struct fimc_is *is)
{
	struct dentry *dentry;

	is->debugfs_entry = debugfs_create_dir("fimc_is", NULL);

	dentry = debugfs_create_file("fw_log", S_IRUGO, is->debugfs_entry,
				     is, &fimc_is_debugfs_fops);
	if (!dentry)
		fimc_is_debugfs_remove(is);

	return is->debugfs_entry == NULL ? -EIO : 0;
}

static int fimc_is_runtime_resume(struct device *dev);
static int fimc_is_runtime_suspend(struct device *dev);

static int fimc_is_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct fimc_is *is;
	struct resource res;
	struct device_node *node;
	int ret;

	is = devm_kzalloc(&pdev->dev, sizeof(*is), GFP_KERNEL);
	if (!is)
		return -ENOMEM;

	is->pdev = pdev;
	is->isp.pdev = pdev;

	init_waitqueue_head(&is->irq_queue);
	spin_lock_init(&is->slock);
	mutex_init(&is->lock);

	ret = of_address_to_resource(dev->of_node, 0, &res);
	if (ret < 0)
		return ret;

	is->regs = devm_ioremap_resource(dev, &res);
	if (IS_ERR(is->regs))
		return PTR_ERR(is->regs);

	node = of_get_child_by_name(dev->of_node, "pmu");
	if (!node)
		return -ENODEV;

	is->pmu_regs = of_iomap(node, 0);
	if (!is->pmu_regs)
		return -ENOMEM;

	is->irq = irq_of_parse_and_map(dev->of_node, 0);
	if (is->irq < 0) {
		dev_err(dev, "no irq found\n");
		return is->irq;
	}

	ret = fimc_is_get_clocks(is);
	if (ret < 0)
		return ret;

	platform_set_drvdata(pdev, is);

	ret = request_irq(is->irq, fimc_is_irq_handler, 0, dev_name(dev), is);
	if (ret < 0) {
		dev_err(dev, "irq request failed\n");
		goto err_clk;
	}
	pm_runtime_enable(dev);

	if (!pm_runtime_enabled(dev)) {
		ret = fimc_is_runtime_resume(dev);
		if (ret < 0)
			goto err_irq;
	}

	ret = pm_runtime_get_sync(dev);
	if (ret < 0)
		goto err_pm;

	is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
	if (IS_ERR(is->alloc_ctx)) {
		ret = PTR_ERR(is->alloc_ctx);
		goto err_pm;
	}
	/*
	 * Register FIMC-IS V4L2 subdevs to this driver. The video nodes
	 * will be created within the subdev's registered() callback.
	 */
	ret = fimc_is_register_subdevs(is);
	if (ret < 0)
		goto err_vb;

	ret = fimc_is_debugfs_create(is);
	if (ret < 0)
		goto err_sd;

	ret = fimc_is_request_firmware(is, FIMC_IS_FW_FILENAME);
	if (ret < 0)
		goto err_dfs;

	pm_runtime_put_sync(dev);

	dev_dbg(dev, "FIMC-IS registered successfully\n");
	return 0;

err_dfs:
	fimc_is_debugfs_remove(is);
err_sd:
	fimc_is_unregister_subdevs(is);
err_vb:
	vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
err_pm:
	if (!pm_runtime_enabled(dev))
		fimc_is_runtime_suspend(dev);
err_irq:
	free_irq(is->irq, is);
err_clk:
	fimc_is_put_clocks(is);
	return ret;
}

static int fimc_is_runtime_resume(struct device *dev)
{
	struct fimc_is *is = dev_get_drvdata(dev);
	int ret;

	ret = fimc_is_setup_clocks(is);
	if (ret)
		return ret;

	return fimc_is_enable_clocks(is);
}

static int fimc_is_runtime_suspend(struct device *dev)
{
	struct fimc_is *is = dev_get_drvdata(dev);

	fimc_is_disable_clocks(is);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int fimc_is_resume(struct device *dev)
{
	/* TODO: */
	return 0;
}

static int fimc_is_suspend(struct device *dev)
{
	struct fimc_is *is = dev_get_drvdata(dev);

	/* TODO: */
	if (test_bit(IS_ST_A5_PWR_ON, &is->state))
		return -EBUSY;

	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static int fimc_is_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct fimc_is *is = dev_get_drvdata(dev);

	pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	if (!pm_runtime_status_suspended(dev))
		fimc_is_runtime_suspend(dev);
	free_irq(is->irq, is);
	fimc_is_unregister_subdevs(is);
	vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
	fimc_is_put_clocks(is);
	fimc_is_debugfs_remove(is);
	if (is->fw.f_w)
		release_firmware(is->fw.f_w);
	fimc_is_free_cpu_memory(is);

	return 0;
}

static const struct of_device_id fimc_is_of_match[] = {
	{ .compatible = "samsung,exynos4212-fimc-is" },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, fimc_is_of_match);

static const struct dev_pm_ops fimc_is_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(fimc_is_suspend, fimc_is_resume)
	SET_RUNTIME_PM_OPS(fimc_is_runtime_suspend, fimc_is_runtime_resume,
			   NULL)
};

static struct platform_driver fimc_is_driver = {
	.probe		= fimc_is_probe,
	.remove		= fimc_is_remove,
	.driver = {
		.of_match_table	= fimc_is_of_match,
		.name		= FIMC_IS_DRV_NAME,
		.owner		= THIS_MODULE,
		.pm		= &fimc_is_pm_ops,
	}
};

static int fimc_is_module_init(void)
{
	int ret;

	ret = fimc_is_register_i2c_driver();
	if (ret < 0)
		return ret;

	ret = platform_driver_register(&fimc_is_driver);

	if (ret < 0)
		fimc_is_unregister_i2c_driver();

	return ret;
}

static void fimc_is_module_exit(void)
{
	fimc_is_unregister_i2c_driver();
	platform_driver_unregister(&fimc_is_driver);
}

module_init(fimc_is_module_init);
module_exit(fimc_is_module_exit);

MODULE_ALIAS("platform:" FIMC_IS_DRV_NAME);
MODULE_AUTHOR("Younghwan Joo <yhwan.joo@samsung.com>");
MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
MODULE_LICENSE("GPL v2");
