// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/clk.h>
#include <linux/clk/tegra.h>
#include <linux/device.h>
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

#include <media/v4l2-fwnode.h>

#include "csi.h"
#include "video.h"

#define MHZ			1000000

static inline struct tegra_csi *
host1x_client_to_csi(struct host1x_client *client)
{
	return container_of(client, struct tegra_csi, client);
}

static inline struct tegra_csi_channel *to_csi_chan(struct v4l2_subdev *subdev)
{
	return container_of(subdev, struct tegra_csi_channel, subdev);
}

/*
 * CSI is a separate subdevice which has 6 source pads to generate
 * test pattern. CSI subdevice pad ops are used only for TPG and
 * allows below TPG formats.
 */
static const struct v4l2_mbus_framefmt tegra_csi_tpg_fmts[] = {
	{
		TEGRA_DEF_WIDTH,
		TEGRA_DEF_HEIGHT,
		MEDIA_BUS_FMT_SRGGB10_1X10,
		V4L2_FIELD_NONE,
		V4L2_COLORSPACE_SRGB
	},
	{
		TEGRA_DEF_WIDTH,
		TEGRA_DEF_HEIGHT,
		MEDIA_BUS_FMT_RGB888_1X32_PADHI,
		V4L2_FIELD_NONE,
		V4L2_COLORSPACE_SRGB
	},
};

static const struct v4l2_frmsize_discrete tegra_csi_tpg_sizes[] = {
	{ 1280, 720 },
	{ 1920, 1080 },
	{ 3840, 2160 },
};

/*
 * V4L2 Subdevice Pad Operations
 */
static int csi_enum_bus_code(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_pad_config *cfg,
			     struct v4l2_subdev_mbus_code_enum *code)
{
	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	if (code->index >= ARRAY_SIZE(tegra_csi_tpg_fmts))
		return -EINVAL;

	code->code = tegra_csi_tpg_fmts[code->index].code;

	return 0;
}

static int csi_get_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	fmt->format = csi_chan->format;

	return 0;
}

static int csi_get_frmrate_table_index(struct tegra_csi *csi, u32 code,
				       u32 width, u32 height)
{
	const struct tpg_framerate *frmrate;
	unsigned int i;

	frmrate = csi->soc->tpg_frmrate_table;
	for (i = 0; i < csi->soc->tpg_frmrate_table_size; i++) {
		if (frmrate[i].code == code &&
		    frmrate[i].frmsize.width == width &&
		    frmrate[i].frmsize.height == height) {
			return i;
		}
	}

	return -EINVAL;
}

static void csi_chan_update_blank_intervals(struct tegra_csi_channel *csi_chan,
					    u32 code, u32 width, u32 height)
{
	struct tegra_csi *csi = csi_chan->csi;
	const struct tpg_framerate *frmrate = csi->soc->tpg_frmrate_table;
	int index;

	index = csi_get_frmrate_table_index(csi_chan->csi, code,
					    width, height);
	if (index >= 0) {
		csi_chan->h_blank = frmrate[index].h_blank;
		csi_chan->v_blank = frmrate[index].v_blank;
		csi_chan->framerate = frmrate[index].framerate;
	}
}

static int csi_enum_framesizes(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	unsigned int i;

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	if (fse->index >= ARRAY_SIZE(tegra_csi_tpg_sizes))
		return -EINVAL;

	for (i = 0; i < ARRAY_SIZE(tegra_csi_tpg_fmts); i++)
		if (fse->code == tegra_csi_tpg_fmts[i].code)
			break;

	if (i == ARRAY_SIZE(tegra_csi_tpg_fmts))
		return -EINVAL;

	fse->min_width = tegra_csi_tpg_sizes[fse->index].width;
	fse->max_width = tegra_csi_tpg_sizes[fse->index].width;
	fse->min_height = tegra_csi_tpg_sizes[fse->index].height;
	fse->max_height = tegra_csi_tpg_sizes[fse->index].height;

	return 0;
}

static int csi_enum_frameintervals(struct v4l2_subdev *subdev,
				   struct v4l2_subdev_pad_config *cfg,
				   struct v4l2_subdev_frame_interval_enum *fie)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
	struct tegra_csi *csi = csi_chan->csi;
	const struct tpg_framerate *frmrate = csi->soc->tpg_frmrate_table;
	int index;

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	/* one framerate per format and resolution */
	if (fie->index > 0)
		return -EINVAL;

	index = csi_get_frmrate_table_index(csi_chan->csi, fie->code,
					    fie->width, fie->height);
	if (index < 0)
		return -EINVAL;

	fie->interval.numerator = 1;
	fie->interval.denominator = frmrate[index].framerate;

	return 0;
}

static int csi_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
	struct v4l2_mbus_framefmt *format = &fmt->format;
	const struct v4l2_frmsize_discrete *sizes;
	unsigned int i;

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	sizes = v4l2_find_nearest_size(tegra_csi_tpg_sizes,
				       ARRAY_SIZE(tegra_csi_tpg_sizes),
				       width, height,
				       format->width, format->width);
	format->width = sizes->width;
	format->height = sizes->height;

	for (i = 0; i < ARRAY_SIZE(tegra_csi_tpg_fmts); i++)
		if (format->code == tegra_csi_tpg_fmts[i].code)
			break;

	if (i == ARRAY_SIZE(tegra_csi_tpg_fmts))
		i = 0;

	format->code = tegra_csi_tpg_fmts[i].code;
	format->field = V4L2_FIELD_NONE;

	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
		return 0;

	/* update blanking intervals from frame rate table and format */
	csi_chan_update_blank_intervals(csi_chan, format->code,
					format->width, format->height);
	csi_chan->format = *format;

	return 0;
}

/*
 * V4L2 Subdevice Video Operations
 */
static int tegra_csi_g_frame_interval(struct v4l2_subdev *subdev,
				      struct v4l2_subdev_frame_interval *vfi)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return -ENOIOCTLCMD;

	vfi->interval.numerator = 1;
	vfi->interval.denominator = csi_chan->framerate;

	return 0;
}

static unsigned int csi_get_pixel_rate(struct tegra_csi_channel *csi_chan)
{
	struct tegra_vi_channel *chan;
	struct v4l2_subdev *src_subdev;
	struct v4l2_ctrl *ctrl;

	chan = v4l2_get_subdev_hostdata(&csi_chan->subdev);
	src_subdev = tegra_channel_get_remote_source_subdev(chan);
	ctrl = v4l2_ctrl_find(src_subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
	if (ctrl)
		return v4l2_ctrl_g_ctrl_int64(ctrl);

	return 0;
}

void tegra_csi_calc_settle_time(struct tegra_csi_channel *csi_chan,
				u8 csi_port_num,
				u8 *clk_settle_time,
				u8 *ths_settle_time)
{
	struct tegra_csi *csi = csi_chan->csi;
	unsigned int cil_clk_mhz;
	unsigned int pix_clk_mhz;
	int clk_idx = (csi_port_num >> 1) + 1;

	cil_clk_mhz = clk_get_rate(csi->clks[clk_idx].clk) / MHZ;
	pix_clk_mhz = csi_get_pixel_rate(csi_chan) / MHZ;

	/*
	 * CLK Settle time is the interval during which HS receiver should
	 * ignore any clock lane HS transitions, starting from the beginning
	 * of T-CLK-PREPARE.
	 * Per DPHY specification, T-CLK-SETTLE should be between 95ns ~ 300ns
	 *
	 * 95ns < (clk-settle-programmed + 7) * lp clk period < 300ns
	 * midpoint = 197.5 ns
	 */
	*clk_settle_time = ((95 + 300) * cil_clk_mhz - 14000) / 2000;

	/*
	 * THS Settle time is the interval during which HS receiver should
	 * ignore any data lane HS transitions, starting from the beginning
	 * of THS-PREPARE.
	 *
	 * Per DPHY specification, T-HS-SETTLE should be between 85ns + 6UI
	 * and 145ns+10UI.
	 * 85ns + 6UI < (Ths-settle-prog + 5) * lp_clk_period < 145ns + 10UI
	 * midpoint = 115ns + 8UI
	 */
	if (pix_clk_mhz)
		*ths_settle_time = (115 * cil_clk_mhz + 8000 * cil_clk_mhz
				   / (2 * pix_clk_mhz) - 5000) / 1000;
}

static int tegra_csi_enable_stream(struct v4l2_subdev *subdev)
{
	struct tegra_vi_channel *chan = v4l2_get_subdev_hostdata(subdev);
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
	struct tegra_csi *csi = csi_chan->csi;
	int ret, err;

	ret = pm_runtime_get_sync(csi->dev);
	if (ret < 0) {
		dev_err(csi->dev, "failed to get runtime PM: %d\n", ret);
		pm_runtime_put_noidle(csi->dev);
		return ret;
	}

	if (csi_chan->mipi) {
		ret = tegra_mipi_enable(csi_chan->mipi);
		if (ret < 0) {
			dev_err(csi->dev,
				"failed to enable MIPI pads: %d\n", ret);
			goto rpm_put;
		}

		/*
		 * CSI MIPI pads PULLUP, PULLDN and TERM impedances need to
		 * be calibrated after power on.
		 * So, trigger the calibration start here and results will
		 * be latched and applied to the pads when link is in LP11
		 * state during start of sensor streaming.
		 */
		ret = tegra_mipi_start_calibration(csi_chan->mipi);
		if (ret < 0) {
			dev_err(csi->dev,
				"failed to start MIPI calibration: %d\n", ret);
			goto disable_mipi;
		}
	}

	csi_chan->pg_mode = chan->pg_mode;
	ret = csi->ops->csi_start_streaming(csi_chan);
	if (ret < 0)
		goto finish_calibration;

	return 0;

finish_calibration:
	if (csi_chan->mipi)
		tegra_mipi_finish_calibration(csi_chan->mipi);
disable_mipi:
	if (csi_chan->mipi) {
		err = tegra_mipi_disable(csi_chan->mipi);
		if (err < 0)
			dev_err(csi->dev,
				"failed to disable MIPI pads: %d\n", err);
	}

rpm_put:
	pm_runtime_put(csi->dev);
	return ret;
}

static int tegra_csi_disable_stream(struct v4l2_subdev *subdev)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
	struct tegra_csi *csi = csi_chan->csi;
	int err;

	csi->ops->csi_stop_streaming(csi_chan);

	if (csi_chan->mipi) {
		err = tegra_mipi_disable(csi_chan->mipi);
		if (err < 0)
			dev_err(csi->dev,
				"failed to disable MIPI pads: %d\n", err);
	}

	pm_runtime_put(csi->dev);

	return 0;
}

static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable)
{
	int ret;

	if (enable)
		ret = tegra_csi_enable_stream(subdev);
	else
		ret = tegra_csi_disable_stream(subdev);

	return ret;
}

/*
 * V4L2 Subdevice Operations
 */
static const struct v4l2_subdev_video_ops tegra_csi_video_ops = {
	.s_stream = tegra_csi_s_stream,
	.g_frame_interval = tegra_csi_g_frame_interval,
	.s_frame_interval = tegra_csi_g_frame_interval,
};

static const struct v4l2_subdev_pad_ops tegra_csi_pad_ops = {
	.enum_mbus_code		= csi_enum_bus_code,
	.enum_frame_size	= csi_enum_framesizes,
	.enum_frame_interval	= csi_enum_frameintervals,
	.get_fmt		= csi_get_format,
	.set_fmt		= csi_set_format,
};

static const struct v4l2_subdev_ops tegra_csi_ops = {
	.video  = &tegra_csi_video_ops,
	.pad    = &tegra_csi_pad_ops,
};

static int tegra_csi_channel_alloc(struct tegra_csi *csi,
				   struct device_node *node,
				   unsigned int port_num, unsigned int lanes,
				   unsigned int num_pads)
{
	struct tegra_csi_channel *chan;
	int ret = 0, i;

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

	list_add_tail(&chan->list, &csi->csi_chans);
	chan->csi = csi;
	/*
	 * Each CSI brick has maximum of 4 lanes.
	 * For lanes more than 4, use multiple of immediate CSI bricks as gang.
	 */
	if (lanes <= CSI_LANES_PER_BRICK) {
		chan->numlanes = lanes;
		chan->numgangports = 1;
	} else {
		chan->numlanes = CSI_LANES_PER_BRICK;
		chan->numgangports = lanes / CSI_LANES_PER_BRICK;
	}

	for (i = 0; i < chan->numgangports; i++)
		chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;

	chan->of_node = node;
	chan->numpads = num_pads;
	if (num_pads & 0x2) {
		chan->pads[0].flags = MEDIA_PAD_FL_SINK;
		chan->pads[1].flags = MEDIA_PAD_FL_SOURCE;
	} else {
		chan->pads[0].flags = MEDIA_PAD_FL_SOURCE;
	}

	if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		return 0;

	chan->mipi = tegra_mipi_request(csi->dev, node);
	if (IS_ERR(chan->mipi)) {
		ret = PTR_ERR(chan->mipi);
		dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
	}

	return ret;
}

static int tegra_csi_tpg_channels_alloc(struct tegra_csi *csi)
{
	struct device_node *node = csi->dev->of_node;
	unsigned int port_num;
	unsigned int tpg_channels = csi->soc->csi_max_channels;
	int ret;

	/* allocate CSI channel for each CSI x2 ports */
	for (port_num = 0; port_num < tpg_channels; port_num++) {
		ret = tegra_csi_channel_alloc(csi, node, port_num, 2, 1);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int tegra_csi_channels_alloc(struct tegra_csi *csi)
{
	struct device_node *node = csi->dev->of_node;
	struct v4l2_fwnode_endpoint v4l2_ep = {
		.bus_type = V4L2_MBUS_CSI2_DPHY
	};
	struct fwnode_handle *fwh;
	struct device_node *channel;
	struct device_node *ep;
	unsigned int lanes, portno, num_pads;
	int ret;

	for_each_child_of_node(node, channel) {
		if (!of_node_name_eq(channel, "channel"))
			continue;

		ret = of_property_read_u32(channel, "reg", &portno);
		if (ret < 0)
			continue;

		if (portno >= csi->soc->csi_max_channels) {
			dev_err(csi->dev, "invalid port num %d for %pOF\n",
				portno, channel);
			ret = -EINVAL;
			goto err_node_put;
		}

		ep = of_graph_get_endpoint_by_regs(channel, 0, 0);
		if (!ep)
			continue;

		fwh = of_fwnode_handle(ep);
		ret = v4l2_fwnode_endpoint_parse(fwh, &v4l2_ep);
		of_node_put(ep);
		if (ret) {
			dev_err(csi->dev,
				"failed to parse v4l2 endpoint for %pOF: %d\n",
				channel, ret);
			goto err_node_put;
		}

		lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
		/*
		 * Each CSI brick has maximum 4 data lanes.
		 * For lanes more than 4, validate lanes to be multiple of 4
		 * so multiple of consecutive CSI bricks can be ganged up for
		 * streaming.
		 */
		if (!lanes || ((lanes & (lanes - 1)) != 0) ||
		    (lanes > CSI_LANES_PER_BRICK && ((portno & 1) != 0))) {
			dev_err(csi->dev, "invalid data-lanes %d for %pOF\n",
				lanes, channel);
			ret = -EINVAL;
			goto err_node_put;
		}

		num_pads = of_graph_get_endpoint_count(channel);
		if (num_pads == TEGRA_CSI_PADS_NUM) {
			ret = tegra_csi_channel_alloc(csi, channel, portno,
						      lanes, num_pads);
			if (ret < 0)
				goto err_node_put;
		}
	}

	return 0;

err_node_put:
	of_node_put(channel);
	return ret;
}

static int tegra_csi_channel_init(struct tegra_csi_channel *chan)
{
	struct tegra_csi *csi = chan->csi;
	struct v4l2_subdev *subdev;
	int ret;

	/* initialize the default format */
	chan->format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
	chan->format.field = V4L2_FIELD_NONE;
	chan->format.colorspace = V4L2_COLORSPACE_SRGB;
	chan->format.width = TEGRA_DEF_WIDTH;
	chan->format.height = TEGRA_DEF_HEIGHT;
	csi_chan_update_blank_intervals(chan, chan->format.code,
					chan->format.width,
					chan->format.height);
	/* initialize V4L2 subdevice and media entity */
	subdev = &chan->subdev;
	v4l2_subdev_init(subdev, &tegra_csi_ops);
	subdev->dev = csi->dev;
	if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "%s-%d", "tpg",
			 chan->csi_port_nums[0]);
	else
		snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "%s",
			 kbasename(chan->of_node->full_name));

	v4l2_set_subdevdata(subdev, chan);
	subdev->fwnode = of_fwnode_handle(chan->of_node);
	subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;

	/* initialize media entity pads */
	ret = media_entity_pads_init(&subdev->entity, chan->numpads,
				     chan->pads);
	if (ret < 0) {
		dev_err(csi->dev,
			"failed to initialize media entity: %d\n", ret);
		subdev->dev = NULL;
		return ret;
	}

	if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) {
		ret = v4l2_async_register_subdev(subdev);
		if (ret < 0) {
			dev_err(csi->dev,
				"failed to register subdev: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

void tegra_csi_error_recover(struct v4l2_subdev *sd)
{
	struct tegra_csi_channel *csi_chan = to_csi_chan(sd);
	struct tegra_csi *csi = csi_chan->csi;

	/* stop streaming during error recovery */
	csi->ops->csi_stop_streaming(csi_chan);
	csi->ops->csi_err_recover(csi_chan);
	csi->ops->csi_start_streaming(csi_chan);
}

static int tegra_csi_channels_init(struct tegra_csi *csi)
{
	struct tegra_csi_channel *chan;
	int ret;

	list_for_each_entry(chan, &csi->csi_chans, list) {
		ret = tegra_csi_channel_init(chan);
		if (ret) {
			dev_err(csi->dev,
				"failed to initialize channel-%d: %d\n",
				chan->csi_port_nums[0], ret);
			return ret;
		}
	}

	return 0;
}

static void tegra_csi_channels_cleanup(struct tegra_csi *csi)
{
	struct v4l2_subdev *subdev;
	struct tegra_csi_channel *chan, *tmp;

	list_for_each_entry_safe(chan, tmp, &csi->csi_chans, list) {
		if (chan->mipi)
			tegra_mipi_free(chan->mipi);

		subdev = &chan->subdev;
		if (subdev->dev) {
			if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
				v4l2_async_unregister_subdev(subdev);
			media_entity_cleanup(&subdev->entity);
		}

		list_del(&chan->list);
		kfree(chan);
	}
}

static int __maybe_unused csi_runtime_suspend(struct device *dev)
{
	struct tegra_csi *csi = dev_get_drvdata(dev);

	clk_bulk_disable_unprepare(csi->soc->num_clks, csi->clks);

	return 0;
}

static int __maybe_unused csi_runtime_resume(struct device *dev)
{
	struct tegra_csi *csi = dev_get_drvdata(dev);
	int ret;

	ret = clk_bulk_prepare_enable(csi->soc->num_clks, csi->clks);
	if (ret < 0) {
		dev_err(csi->dev, "failed to enable clocks: %d\n", ret);
		return ret;
	}

	return 0;
}

static int tegra_csi_init(struct host1x_client *client)
{
	struct tegra_csi *csi = host1x_client_to_csi(client);
	struct tegra_video_device *vid = dev_get_drvdata(client->host);
	int ret;

	INIT_LIST_HEAD(&csi->csi_chans);

	if (IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
		ret = tegra_csi_tpg_channels_alloc(csi);
	else
		ret = tegra_csi_channels_alloc(csi);
	if (ret < 0) {
		dev_err(csi->dev,
			"failed to allocate channels: %d\n", ret);
		goto cleanup;
	}

	ret = tegra_csi_channels_init(csi);
	if (ret < 0)
		goto cleanup;

	vid->csi = csi;

	return 0;

cleanup:
	tegra_csi_channels_cleanup(csi);
	return ret;
}

static int tegra_csi_exit(struct host1x_client *client)
{
	struct tegra_csi *csi = host1x_client_to_csi(client);

	tegra_csi_channels_cleanup(csi);

	return 0;
}

static const struct host1x_client_ops csi_client_ops = {
	.init = tegra_csi_init,
	.exit = tegra_csi_exit,
};

static int tegra_csi_probe(struct platform_device *pdev)
{
	struct tegra_csi *csi;
	unsigned int i;
	int ret;

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

	csi->iomem = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(csi->iomem))
		return PTR_ERR(csi->iomem);

	csi->soc = of_device_get_match_data(&pdev->dev);

	csi->clks = devm_kcalloc(&pdev->dev, csi->soc->num_clks,
				 sizeof(*csi->clks), GFP_KERNEL);
	if (!csi->clks)
		return -ENOMEM;

	for (i = 0; i < csi->soc->num_clks; i++)
		csi->clks[i].id = csi->soc->clk_names[i];

	ret = devm_clk_bulk_get(&pdev->dev, csi->soc->num_clks, csi->clks);
	if (ret) {
		dev_err(&pdev->dev, "failed to get the clocks: %d\n", ret);
		return ret;
	}

	if (!pdev->dev.pm_domain) {
		ret = -ENOENT;
		dev_warn(&pdev->dev, "PM domain is not attached: %d\n", ret);
		return ret;
	}

	csi->dev = &pdev->dev;
	csi->ops = csi->soc->ops;
	platform_set_drvdata(pdev, csi);
	pm_runtime_enable(&pdev->dev);

	/* initialize host1x interface */
	INIT_LIST_HEAD(&csi->client.list);
	csi->client.ops = &csi_client_ops;
	csi->client.dev = &pdev->dev;

	ret = host1x_client_register(&csi->client);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"failed to register host1x client: %d\n", ret);
		goto rpm_disable;
	}

	return 0;

rpm_disable:
	pm_runtime_disable(&pdev->dev);
	return ret;
}

static int tegra_csi_remove(struct platform_device *pdev)
{
	struct tegra_csi *csi = platform_get_drvdata(pdev);
	int err;

	err = host1x_client_unregister(&csi->client);
	if (err < 0) {
		dev_err(&pdev->dev,
			"failed to unregister host1x client: %d\n", err);
		return err;
	}

	pm_runtime_disable(&pdev->dev);

	return 0;
}

static const struct of_device_id tegra_csi_of_id_table[] = {
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
	{ .compatible = "nvidia,tegra210-csi", .data = &tegra210_csi_soc },
#endif
	{ }
};
MODULE_DEVICE_TABLE(of, tegra_csi_of_id_table);

static const struct dev_pm_ops tegra_csi_pm_ops = {
	SET_RUNTIME_PM_OPS(csi_runtime_suspend, csi_runtime_resume, NULL)
};

struct platform_driver tegra_csi_driver = {
	.driver = {
		.name		= "tegra-csi",
		.of_match_table	= tegra_csi_of_id_table,
		.pm		= &tegra_csi_pm_ops,
	},
	.probe			= tegra_csi_probe,
	.remove			= tegra_csi_remove,
};
