cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rcar-core.c (35054B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Driver for Renesas R-Car VIN
      4 *
      5 * Copyright (C) 2016 Renesas Electronics Corp.
      6 * Copyright (C) 2011-2013 Renesas Solutions Corp.
      7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
      8 * Copyright (C) 2008 Magnus Damm
      9 *
     10 * Based on the soc-camera rcar_vin driver
     11 */
     12
     13#include <linux/module.h>
     14#include <linux/of.h>
     15#include <linux/of_device.h>
     16#include <linux/of_graph.h>
     17#include <linux/platform_device.h>
     18#include <linux/pm_runtime.h>
     19#include <linux/slab.h>
     20#include <linux/sys_soc.h>
     21
     22#include <media/v4l2-async.h>
     23#include <media/v4l2-fwnode.h>
     24#include <media/v4l2-mc.h>
     25
     26#include "rcar-vin.h"
     27
     28/*
     29 * The companion CSI-2 receiver driver (rcar-csi2) is known
     30 * and we know it has one source pad (pad 0) and four sink
     31 * pads (pad 1-4). So to translate a pad on the remote
     32 * CSI-2 receiver to/from the VIN internal channel number simply
     33 * subtract/add one from the pad/channel number.
     34 */
     35#define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
     36#define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
     37
     38/*
     39 * Not all VINs are created equal, master VINs control the
     40 * routing for other VIN's. We can figure out which VIN is
     41 * master by looking at a VINs id.
     42 */
     43#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
     44
     45#define v4l2_dev_to_vin(d)	container_of(d, struct rvin_dev, v4l2_dev)
     46
     47/* -----------------------------------------------------------------------------
     48 * Gen3 Group Allocator
     49 */
     50
     51/* FIXME:  This should if we find a system that supports more
     52 * than one group for the whole system be replaced with a linked
     53 * list of groups. And eventually all of this should be replaced
     54 * with a global device allocator API.
     55 *
     56 * But for now this works as on all supported systems there will
     57 * be only one group for all instances.
     58 */
     59
     60static DEFINE_MUTEX(rvin_group_lock);
     61static struct rvin_group *rvin_group_data;
     62
     63static void rvin_group_cleanup(struct rvin_group *group)
     64{
     65	media_device_cleanup(&group->mdev);
     66	mutex_destroy(&group->lock);
     67}
     68
     69static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
     70			   int (*link_setup)(struct rvin_dev *),
     71			   const struct media_device_ops *ops)
     72{
     73	struct media_device *mdev = &group->mdev;
     74	const struct of_device_id *match;
     75	struct device_node *np;
     76
     77	mutex_init(&group->lock);
     78
     79	/* Count number of VINs in the system */
     80	group->count = 0;
     81	for_each_matching_node(np, vin->dev->driver->of_match_table)
     82		if (of_device_is_available(np))
     83			group->count++;
     84
     85	vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
     86
     87	group->link_setup = link_setup;
     88
     89	mdev->dev = vin->dev;
     90	mdev->ops = ops;
     91
     92	match = of_match_node(vin->dev->driver->of_match_table,
     93			      vin->dev->of_node);
     94
     95	strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
     96	strscpy(mdev->model, match->compatible, sizeof(mdev->model));
     97
     98	media_device_init(mdev);
     99
    100	return 0;
    101}
    102
    103static void rvin_group_release(struct kref *kref)
    104{
    105	struct rvin_group *group =
    106		container_of(kref, struct rvin_group, refcount);
    107
    108	mutex_lock(&rvin_group_lock);
    109
    110	rvin_group_data = NULL;
    111
    112	rvin_group_cleanup(group);
    113
    114	kfree(group);
    115
    116	mutex_unlock(&rvin_group_lock);
    117}
    118
    119static int rvin_group_get(struct rvin_dev *vin,
    120			  int (*link_setup)(struct rvin_dev *),
    121			  const struct media_device_ops *ops)
    122{
    123	struct rvin_group *group;
    124	u32 id;
    125	int ret;
    126
    127	/* Make sure VIN id is present and sane */
    128	ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
    129	if (ret) {
    130		vin_err(vin, "%pOF: No renesas,id property found\n",
    131			vin->dev->of_node);
    132		return -EINVAL;
    133	}
    134
    135	if (id >= RCAR_VIN_NUM) {
    136		vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
    137			vin->dev->of_node, id);
    138		return -EINVAL;
    139	}
    140
    141	/* Join or create a VIN group */
    142	mutex_lock(&rvin_group_lock);
    143	if (rvin_group_data) {
    144		group = rvin_group_data;
    145		kref_get(&group->refcount);
    146	} else {
    147		group = kzalloc(sizeof(*group), GFP_KERNEL);
    148		if (!group) {
    149			ret = -ENOMEM;
    150			goto err_group;
    151		}
    152
    153		ret = rvin_group_init(group, vin, link_setup, ops);
    154		if (ret) {
    155			kfree(group);
    156			vin_err(vin, "Failed to initialize group\n");
    157			goto err_group;
    158		}
    159
    160		kref_init(&group->refcount);
    161
    162		rvin_group_data = group;
    163	}
    164	mutex_unlock(&rvin_group_lock);
    165
    166	/* Add VIN to group */
    167	mutex_lock(&group->lock);
    168
    169	if (group->vin[id]) {
    170		vin_err(vin, "Duplicate renesas,id property value %u\n", id);
    171		mutex_unlock(&group->lock);
    172		kref_put(&group->refcount, rvin_group_release);
    173		return -EINVAL;
    174	}
    175
    176	group->vin[id] = vin;
    177
    178	vin->id = id;
    179	vin->group = group;
    180	vin->v4l2_dev.mdev = &group->mdev;
    181
    182	mutex_unlock(&group->lock);
    183
    184	return 0;
    185err_group:
    186	mutex_unlock(&rvin_group_lock);
    187	return ret;
    188}
    189
    190static void rvin_group_put(struct rvin_dev *vin)
    191{
    192	struct rvin_group *group = vin->group;
    193
    194	mutex_lock(&group->lock);
    195
    196	vin->group = NULL;
    197	vin->v4l2_dev.mdev = NULL;
    198
    199	if (WARN_ON(group->vin[vin->id] != vin))
    200		goto out;
    201
    202	group->vin[vin->id] = NULL;
    203out:
    204	mutex_unlock(&group->lock);
    205
    206	kref_put(&group->refcount, rvin_group_release);
    207}
    208
    209/* group lock should be held when calling this function. */
    210static int rvin_group_entity_to_remote_id(struct rvin_group *group,
    211					  struct media_entity *entity)
    212{
    213	struct v4l2_subdev *sd;
    214	unsigned int i;
    215
    216	sd = media_entity_to_v4l2_subdev(entity);
    217
    218	for (i = 0; i < RVIN_REMOTES_MAX; i++)
    219		if (group->remotes[i].subdev == sd)
    220			return i;
    221
    222	return -ENODEV;
    223}
    224
    225static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
    226{
    227	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    228	unsigned int i;
    229	int ret;
    230
    231	ret = media_device_register(&vin->group->mdev);
    232	if (ret)
    233		return ret;
    234
    235	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
    236	if (ret) {
    237		vin_err(vin, "Failed to register subdev nodes\n");
    238		return ret;
    239	}
    240
    241	/* Register all video nodes for the group. */
    242	for (i = 0; i < RCAR_VIN_NUM; i++) {
    243		if (vin->group->vin[i] &&
    244		    !video_is_registered(&vin->group->vin[i]->vdev)) {
    245			ret = rvin_v4l2_register(vin->group->vin[i]);
    246			if (ret)
    247				return ret;
    248		}
    249	}
    250
    251	return vin->group->link_setup(vin);
    252}
    253
    254static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
    255				     struct v4l2_subdev *subdev,
    256				     struct v4l2_async_subdev *asd)
    257{
    258	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    259	unsigned int i;
    260
    261	for (i = 0; i < RCAR_VIN_NUM; i++)
    262		if (vin->group->vin[i])
    263			rvin_v4l2_unregister(vin->group->vin[i]);
    264
    265	mutex_lock(&vin->group->lock);
    266
    267	for (i = 0; i < RVIN_CSI_MAX; i++) {
    268		if (vin->group->remotes[i].asd != asd)
    269			continue;
    270		vin->group->remotes[i].subdev = NULL;
    271		vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
    272		break;
    273	}
    274
    275	mutex_unlock(&vin->group->lock);
    276
    277	media_device_unregister(&vin->group->mdev);
    278}
    279
    280static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
    281				   struct v4l2_subdev *subdev,
    282				   struct v4l2_async_subdev *asd)
    283{
    284	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    285	unsigned int i;
    286
    287	mutex_lock(&vin->group->lock);
    288
    289	for (i = 0; i < RVIN_CSI_MAX; i++) {
    290		if (vin->group->remotes[i].asd != asd)
    291			continue;
    292		vin->group->remotes[i].subdev = subdev;
    293		vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
    294		break;
    295	}
    296
    297	mutex_unlock(&vin->group->lock);
    298
    299	return 0;
    300}
    301
    302static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
    303	.bound = rvin_group_notify_bound,
    304	.unbind = rvin_group_notify_unbind,
    305	.complete = rvin_group_notify_complete,
    306};
    307
    308static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port,
    309			       unsigned int id)
    310{
    311	struct fwnode_handle *ep, *fwnode;
    312	struct v4l2_fwnode_endpoint vep = {
    313		.bus_type = V4L2_MBUS_CSI2_DPHY,
    314	};
    315	struct v4l2_async_subdev *asd;
    316	int ret;
    317
    318	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), port, id, 0);
    319	if (!ep)
    320		return 0;
    321
    322	fwnode = fwnode_graph_get_remote_endpoint(ep);
    323	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
    324	fwnode_handle_put(ep);
    325	if (ret) {
    326		vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
    327		ret = -EINVAL;
    328		goto out;
    329	}
    330
    331	asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode,
    332				       struct v4l2_async_subdev);
    333	if (IS_ERR(asd)) {
    334		ret = PTR_ERR(asd);
    335		goto out;
    336	}
    337
    338	vin->group->remotes[vep.base.id].asd = asd;
    339
    340	vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
    341		to_of_node(fwnode), vep.base.id);
    342out:
    343	fwnode_handle_put(fwnode);
    344
    345	return ret;
    346}
    347
    348static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
    349{
    350	if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
    351		v4l2_async_nf_unregister(&vin->group->notifier);
    352		v4l2_async_nf_cleanup(&vin->group->notifier);
    353	}
    354}
    355
    356static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
    357				    unsigned int max_id)
    358{
    359	unsigned int count = 0, vin_mask = 0;
    360	unsigned int i, id;
    361	int ret;
    362
    363	mutex_lock(&vin->group->lock);
    364
    365	/* If not all VIN's are registered don't register the notifier. */
    366	for (i = 0; i < RCAR_VIN_NUM; i++) {
    367		if (vin->group->vin[i]) {
    368			count++;
    369			vin_mask |= BIT(i);
    370		}
    371	}
    372
    373	if (vin->group->count != count) {
    374		mutex_unlock(&vin->group->lock);
    375		return 0;
    376	}
    377
    378	mutex_unlock(&vin->group->lock);
    379
    380	v4l2_async_nf_init(&vin->group->notifier);
    381
    382	/*
    383	 * Some subdevices may overlap but the parser function can handle it and
    384	 * each subdevice will only be registered once with the group notifier.
    385	 */
    386	for (i = 0; i < RCAR_VIN_NUM; i++) {
    387		if (!(vin_mask & BIT(i)))
    388			continue;
    389
    390		for (id = 0; id < max_id; id++) {
    391			if (vin->group->remotes[id].asd)
    392				continue;
    393
    394			ret = rvin_group_parse_of(vin->group->vin[i], port, id);
    395			if (ret)
    396				return ret;
    397		}
    398	}
    399
    400	if (list_empty(&vin->group->notifier.asd_list))
    401		return 0;
    402
    403	vin->group->notifier.ops = &rvin_group_notify_ops;
    404	ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier);
    405	if (ret < 0) {
    406		vin_err(vin, "Notifier registration failed\n");
    407		v4l2_async_nf_cleanup(&vin->group->notifier);
    408		return ret;
    409	}
    410
    411	return 0;
    412}
    413
    414/* -----------------------------------------------------------------------------
    415 * Controls
    416 */
    417
    418static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
    419{
    420	struct rvin_dev *vin =
    421		container_of(ctrl->handler, struct rvin_dev, ctrl_handler);
    422
    423	switch (ctrl->id) {
    424	case V4L2_CID_ALPHA_COMPONENT:
    425		rvin_set_alpha(vin, ctrl->val);
    426		break;
    427	}
    428
    429	return 0;
    430}
    431
    432static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
    433	.s_ctrl = rvin_s_ctrl,
    434};
    435
    436static void rvin_free_controls(struct rvin_dev *vin)
    437{
    438	v4l2_ctrl_handler_free(&vin->ctrl_handler);
    439	vin->vdev.ctrl_handler = NULL;
    440}
    441
    442static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
    443{
    444	int ret;
    445
    446	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
    447	if (ret < 0)
    448		return ret;
    449
    450	/* The VIN directly deals with alpha component. */
    451	v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
    452			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
    453
    454	if (vin->ctrl_handler.error) {
    455		ret = vin->ctrl_handler.error;
    456		rvin_free_controls(vin);
    457		return ret;
    458	}
    459
    460	/* For the non-MC mode add controls from the subdevice. */
    461	if (subdev) {
    462		ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
    463					    subdev->ctrl_handler, NULL, true);
    464		if (ret < 0) {
    465			rvin_free_controls(vin);
    466			return ret;
    467		}
    468	}
    469
    470	vin->vdev.ctrl_handler = &vin->ctrl_handler;
    471
    472	return 0;
    473}
    474
    475/* -----------------------------------------------------------------------------
    476 * Async notifier
    477 */
    478
    479static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
    480{
    481	unsigned int pad;
    482
    483	if (sd->entity.num_pads <= 1)
    484		return 0;
    485
    486	for (pad = 0; pad < sd->entity.num_pads; pad++)
    487		if (sd->entity.pads[pad].flags & direction)
    488			return pad;
    489
    490	return -EINVAL;
    491}
    492
    493/* -----------------------------------------------------------------------------
    494 * Parallel async notifier
    495 */
    496
    497/* The vin lock should be held when calling the subdevice attach and detach */
    498static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
    499					  struct v4l2_subdev *subdev)
    500{
    501	struct v4l2_subdev_mbus_code_enum code = {
    502		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
    503	};
    504	int ret;
    505
    506	/* Find source and sink pad of remote subdevice */
    507	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
    508	if (ret < 0)
    509		return ret;
    510	vin->parallel.source_pad = ret;
    511
    512	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
    513	vin->parallel.sink_pad = ret < 0 ? 0 : ret;
    514
    515	if (vin->info->use_mc) {
    516		vin->parallel.subdev = subdev;
    517		return 0;
    518	}
    519
    520	/* Find compatible subdevices mbus format */
    521	vin->mbus_code = 0;
    522	code.index = 0;
    523	code.pad = vin->parallel.source_pad;
    524	while (!vin->mbus_code &&
    525	       !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
    526		code.index++;
    527		switch (code.code) {
    528		case MEDIA_BUS_FMT_YUYV8_1X16:
    529		case MEDIA_BUS_FMT_UYVY8_1X16:
    530		case MEDIA_BUS_FMT_UYVY8_2X8:
    531		case MEDIA_BUS_FMT_UYVY10_2X10:
    532		case MEDIA_BUS_FMT_RGB888_1X24:
    533			vin->mbus_code = code.code;
    534			vin_dbg(vin, "Found media bus format for %s: %d\n",
    535				subdev->name, vin->mbus_code);
    536			break;
    537		default:
    538			break;
    539		}
    540	}
    541
    542	if (!vin->mbus_code) {
    543		vin_err(vin, "Unsupported media bus format for %s\n",
    544			subdev->name);
    545		return -EINVAL;
    546	}
    547
    548	/* Read tvnorms */
    549	ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
    550	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
    551		return ret;
    552
    553	/* Read standard */
    554	vin->std = V4L2_STD_UNKNOWN;
    555	ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
    556	if (ret < 0 && ret != -ENOIOCTLCMD)
    557		return ret;
    558
    559	/* Add the controls */
    560	ret = rvin_create_controls(vin, subdev);
    561	if (ret < 0)
    562		return ret;
    563
    564	vin->parallel.subdev = subdev;
    565
    566	return 0;
    567}
    568
    569static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
    570{
    571	rvin_v4l2_unregister(vin);
    572	vin->parallel.subdev = NULL;
    573
    574	if (!vin->info->use_mc)
    575		rvin_free_controls(vin);
    576}
    577
    578static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
    579{
    580	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    581	struct media_entity *source;
    582	struct media_entity *sink;
    583	int ret;
    584
    585	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
    586	if (ret < 0) {
    587		vin_err(vin, "Failed to register subdev nodes\n");
    588		return ret;
    589	}
    590
    591	if (!video_is_registered(&vin->vdev)) {
    592		ret = rvin_v4l2_register(vin);
    593		if (ret < 0)
    594			return ret;
    595	}
    596
    597	if (!vin->info->use_mc)
    598		return 0;
    599
    600	/* If we're running with media-controller, link the subdevs. */
    601	source = &vin->parallel.subdev->entity;
    602	sink = &vin->vdev.entity;
    603
    604	ret = media_create_pad_link(source, vin->parallel.source_pad,
    605				    sink, vin->parallel.sink_pad, 0);
    606	if (ret)
    607		vin_err(vin, "Error adding link from %s to %s: %d\n",
    608			source->name, sink->name, ret);
    609
    610	return ret;
    611}
    612
    613static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
    614					struct v4l2_subdev *subdev,
    615					struct v4l2_async_subdev *asd)
    616{
    617	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    618
    619	vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
    620
    621	mutex_lock(&vin->lock);
    622	rvin_parallel_subdevice_detach(vin);
    623	mutex_unlock(&vin->lock);
    624}
    625
    626static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
    627				      struct v4l2_subdev *subdev,
    628				      struct v4l2_async_subdev *asd)
    629{
    630	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
    631	int ret;
    632
    633	mutex_lock(&vin->lock);
    634	ret = rvin_parallel_subdevice_attach(vin, subdev);
    635	mutex_unlock(&vin->lock);
    636	if (ret)
    637		return ret;
    638
    639	v4l2_set_subdev_hostdata(subdev, vin);
    640
    641	vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
    642		subdev->name, vin->parallel.source_pad,
    643		vin->parallel.sink_pad);
    644
    645	return 0;
    646}
    647
    648static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
    649	.bound = rvin_parallel_notify_bound,
    650	.unbind = rvin_parallel_notify_unbind,
    651	.complete = rvin_parallel_notify_complete,
    652};
    653
    654static int rvin_parallel_parse_of(struct rvin_dev *vin)
    655{
    656	struct fwnode_handle *ep, *fwnode;
    657	struct v4l2_fwnode_endpoint vep = {
    658		.bus_type = V4L2_MBUS_UNKNOWN,
    659	};
    660	struct v4l2_async_subdev *asd;
    661	int ret;
    662
    663	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0);
    664	if (!ep)
    665		return 0;
    666
    667	fwnode = fwnode_graph_get_remote_endpoint(ep);
    668	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
    669	fwnode_handle_put(ep);
    670	if (ret) {
    671		vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
    672		ret = -EINVAL;
    673		goto out;
    674	}
    675
    676	switch (vep.bus_type) {
    677	case V4L2_MBUS_PARALLEL:
    678	case V4L2_MBUS_BT656:
    679		vin_dbg(vin, "Found %s media bus\n",
    680			vep.bus_type == V4L2_MBUS_PARALLEL ?
    681			"PARALLEL" : "BT656");
    682		vin->parallel.mbus_type = vep.bus_type;
    683		vin->parallel.bus = vep.bus.parallel;
    684		break;
    685	default:
    686		vin_err(vin, "Unknown media bus type\n");
    687		ret = -EINVAL;
    688		goto out;
    689	}
    690
    691	asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode,
    692				       struct v4l2_async_subdev);
    693	if (IS_ERR(asd)) {
    694		ret = PTR_ERR(asd);
    695		goto out;
    696	}
    697
    698	vin->parallel.asd = asd;
    699
    700	vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode));
    701out:
    702	fwnode_handle_put(fwnode);
    703
    704	return ret;
    705}
    706
    707static void rvin_parallel_cleanup(struct rvin_dev *vin)
    708{
    709	v4l2_async_nf_unregister(&vin->notifier);
    710	v4l2_async_nf_cleanup(&vin->notifier);
    711}
    712
    713static int rvin_parallel_init(struct rvin_dev *vin)
    714{
    715	int ret;
    716
    717	v4l2_async_nf_init(&vin->notifier);
    718
    719	ret = rvin_parallel_parse_of(vin);
    720	if (ret)
    721		return ret;
    722
    723	if (!vin->parallel.asd)
    724		return -ENODEV;
    725
    726	vin_dbg(vin, "Found parallel subdevice %pOF\n",
    727		to_of_node(vin->parallel.asd->match.fwnode));
    728
    729	vin->notifier.ops = &rvin_parallel_notify_ops;
    730	ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier);
    731	if (ret < 0) {
    732		vin_err(vin, "Notifier registration failed\n");
    733		v4l2_async_nf_cleanup(&vin->notifier);
    734		return ret;
    735	}
    736
    737	return 0;
    738}
    739
    740/* -----------------------------------------------------------------------------
    741 * CSI-2
    742 */
    743
    744/*
    745 * Link setup for the links between a VIN and a CSI-2 receiver is a bit
    746 * complex. The reason for this is that the register controlling routing
    747 * is not present in each VIN instance. There are special VINs which
    748 * control routing for themselves and other VINs. There are not many
    749 * different possible links combinations that can be enabled at the same
    750 * time, therefor all already enabled links which are controlled by a
    751 * master VIN need to be taken into account when making the decision
    752 * if a new link can be enabled or not.
    753 *
    754 * 1. Find out which VIN the link the user tries to enable is connected to.
    755 * 2. Lookup which master VIN controls the links for this VIN.
    756 * 3. Start with a bitmask with all bits set.
    757 * 4. For each previously enabled link from the master VIN bitwise AND its
    758 *    route mask (see documentation for mask in struct rvin_group_route)
    759 *    with the bitmask.
    760 * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask.
    761 * 6. If the bitmask is not empty at this point the new link can be enabled
    762 *    while keeping all previous links enabled. Update the CHSEL value of the
    763 *    master VIN and inform the user that the link could be enabled.
    764 *
    765 * Please note that no link can be enabled if any VIN in the group is
    766 * currently open.
    767 */
    768static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
    769				 unsigned int notification)
    770{
    771	struct rvin_group *group = container_of(link->graph_obj.mdev,
    772						struct rvin_group, mdev);
    773	struct media_entity *entity;
    774	struct video_device *vdev;
    775	struct rvin_dev *vin;
    776	unsigned int i;
    777	int csi_id, ret;
    778
    779	ret = v4l2_pipeline_link_notify(link, flags, notification);
    780	if (ret)
    781		return ret;
    782
    783	/* Only care about link enablement for VIN nodes. */
    784	if (!(flags & MEDIA_LNK_FL_ENABLED) ||
    785	    !is_media_entity_v4l2_video_device(link->sink->entity))
    786		return 0;
    787
    788	/*
    789	 * Don't allow link changes if any entity in the graph is
    790	 * streaming, modifying the CHSEL register fields can disrupt
    791	 * running streams.
    792	 */
    793	media_device_for_each_entity(entity, &group->mdev)
    794		if (media_entity_is_streaming(entity))
    795			return -EBUSY;
    796
    797	/* Find the master VIN that controls the routes. */
    798	vdev = media_entity_to_video_device(link->sink->entity);
    799	vin = container_of(vdev, struct rvin_dev, vdev);
    800
    801	mutex_lock(&group->lock);
    802
    803	csi_id = rvin_group_entity_to_remote_id(group, link->source->entity);
    804	if (csi_id == -ENODEV) {
    805		struct v4l2_subdev *sd;
    806
    807		/*
    808		 * Make sure the source entity subdevice is registered as
    809		 * a parallel input of one of the enabled VINs if it is not
    810		 * one of the CSI-2 subdevices.
    811		 *
    812		 * No hardware configuration required for parallel inputs,
    813		 * we can return here.
    814		 */
    815		sd = media_entity_to_v4l2_subdev(link->source->entity);
    816		for (i = 0; i < RCAR_VIN_NUM; i++) {
    817			if (group->vin[i] &&
    818			    group->vin[i]->parallel.subdev == sd) {
    819				group->vin[i]->is_csi = false;
    820				ret = 0;
    821				goto out;
    822			}
    823		}
    824
    825		vin_err(vin, "Subdevice %s not registered to any VIN\n",
    826			link->source->entity->name);
    827		ret = -ENODEV;
    828	} else {
    829		const struct rvin_group_route *route;
    830		unsigned int chsel = UINT_MAX;
    831		unsigned int master_id;
    832
    833		master_id = rvin_group_id_to_master(vin->id);
    834
    835		if (WARN_ON(!group->vin[master_id])) {
    836			ret = -ENODEV;
    837			goto out;
    838		}
    839
    840		/* Make sure group is connected to same CSI-2 */
    841		for (i = master_id; i < master_id + 4; i++) {
    842			struct media_pad *csi_pad;
    843
    844			if (!group->vin[i])
    845				continue;
    846
    847			/* Get remote CSI-2, if any. */
    848			csi_pad = media_entity_remote_pad(
    849					&group->vin[i]->vdev.entity.pads[0]);
    850			if (!csi_pad)
    851				continue;
    852
    853			if (csi_pad->entity != link->source->entity) {
    854				vin_dbg(vin, "Already attached to %s\n",
    855					csi_pad->entity->name);
    856				ret = -EBUSY;
    857				goto out;
    858			}
    859		}
    860
    861		for (route = vin->info->routes; route->chsel; route++) {
    862			if (route->master == master_id && route->csi == csi_id) {
    863				chsel = route->chsel;
    864				break;
    865			}
    866		}
    867
    868		if (chsel == UINT_MAX) {
    869			vin_err(vin, "No CHSEL value found\n");
    870			ret = -EINVAL;
    871			goto out;
    872		}
    873
    874		ret = rvin_set_channel_routing(group->vin[master_id], chsel);
    875		if (ret)
    876			goto out;
    877
    878		vin->is_csi = true;
    879	}
    880out:
    881	mutex_unlock(&group->lock);
    882
    883	return ret;
    884}
    885
    886static const struct media_device_ops rvin_csi2_media_ops = {
    887	.link_notify = rvin_csi2_link_notify,
    888};
    889
    890static int rvin_csi2_create_link(struct rvin_group *group, unsigned int id,
    891				 const struct rvin_group_route *route)
    892{
    893	struct media_entity *source = &group->remotes[route->csi].subdev->entity;
    894	struct media_entity *sink = &group->vin[id]->vdev.entity;
    895	struct media_pad *sink_pad = &sink->pads[0];
    896	unsigned int channel;
    897	int ret;
    898
    899	for (channel = 0; channel < 4; channel++) {
    900		unsigned int source_idx = rvin_group_csi_channel_to_pad(channel);
    901		struct media_pad *source_pad = &source->pads[source_idx];
    902
    903		/* Skip if link already exists. */
    904		if (media_entity_find_link(source_pad, sink_pad))
    905			continue;
    906
    907		ret = media_create_pad_link(source, source_idx, sink, 0, 0);
    908		if (ret)
    909			return ret;
    910	}
    911
    912	return 0;
    913}
    914
    915static int rvin_csi2_setup_links(struct rvin_dev *vin)
    916{
    917	const struct rvin_group_route *route;
    918	unsigned int id;
    919	int ret = -EINVAL;
    920
    921	/* Create all media device links between VINs and CSI-2's. */
    922	mutex_lock(&vin->group->lock);
    923	for (route = vin->info->routes; route->chsel; route++) {
    924		/* Check that VIN' master is part of the group. */
    925		if (!vin->group->vin[route->master])
    926			continue;
    927
    928		/* Check that CSI-2 is part of the group. */
    929		if (!vin->group->remotes[route->csi].subdev)
    930			continue;
    931
    932		for (id = route->master; id < route->master + 4; id++) {
    933			/* Check that VIN is part of the group. */
    934			if (!vin->group->vin[id])
    935				continue;
    936
    937			ret = rvin_csi2_create_link(vin->group, id, route);
    938			if (ret)
    939				goto out;
    940		}
    941	}
    942out:
    943	mutex_unlock(&vin->group->lock);
    944
    945	return ret;
    946}
    947
    948static void rvin_csi2_cleanup(struct rvin_dev *vin)
    949{
    950	rvin_parallel_cleanup(vin);
    951	rvin_group_notifier_cleanup(vin);
    952	rvin_group_put(vin);
    953	rvin_free_controls(vin);
    954}
    955
    956static int rvin_csi2_init(struct rvin_dev *vin)
    957{
    958	int ret;
    959
    960	vin->pad.flags = MEDIA_PAD_FL_SINK;
    961	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
    962	if (ret)
    963		return ret;
    964
    965	ret = rvin_create_controls(vin, NULL);
    966	if (ret < 0)
    967		return ret;
    968
    969	ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);
    970	if (ret)
    971		goto err_controls;
    972
    973	/* It's OK to not have a parallel subdevice. */
    974	ret = rvin_parallel_init(vin);
    975	if (ret && ret != -ENODEV)
    976		goto err_group;
    977
    978	ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);
    979	if (ret)
    980		goto err_parallel;
    981
    982	return 0;
    983err_parallel:
    984	rvin_parallel_cleanup(vin);
    985err_group:
    986	rvin_group_put(vin);
    987err_controls:
    988	rvin_free_controls(vin);
    989
    990	return ret;
    991}
    992
    993/* -----------------------------------------------------------------------------
    994 * ISP
    995 */
    996
    997static int rvin_isp_setup_links(struct rvin_dev *vin)
    998{
    999	unsigned int i;
   1000	int ret = -EINVAL;
   1001
   1002	/* Create all media device links between VINs and ISP's. */
   1003	mutex_lock(&vin->group->lock);
   1004	for (i = 0; i < RCAR_VIN_NUM; i++) {
   1005		struct media_pad *source_pad, *sink_pad;
   1006		struct media_entity *source, *sink;
   1007		unsigned int source_slot = i / 8;
   1008		unsigned int source_idx = i % 8 + 1;
   1009
   1010		if (!vin->group->vin[i])
   1011			continue;
   1012
   1013		/* Check that ISP is part of the group. */
   1014		if (!vin->group->remotes[source_slot].subdev)
   1015			continue;
   1016
   1017		source = &vin->group->remotes[source_slot].subdev->entity;
   1018		source_pad = &source->pads[source_idx];
   1019
   1020		sink = &vin->group->vin[i]->vdev.entity;
   1021		sink_pad = &sink->pads[0];
   1022
   1023		/* Skip if link already exists. */
   1024		if (media_entity_find_link(source_pad, sink_pad))
   1025			continue;
   1026
   1027		ret = media_create_pad_link(source, source_idx, sink, 0,
   1028					    MEDIA_LNK_FL_ENABLED |
   1029					    MEDIA_LNK_FL_IMMUTABLE);
   1030		if (ret) {
   1031			vin_err(vin, "Error adding link from %s to %s\n",
   1032				source->name, sink->name);
   1033			break;
   1034		}
   1035	}
   1036	mutex_unlock(&vin->group->lock);
   1037
   1038	return ret;
   1039}
   1040
   1041static void rvin_isp_cleanup(struct rvin_dev *vin)
   1042{
   1043	rvin_group_notifier_cleanup(vin);
   1044	rvin_group_put(vin);
   1045	rvin_free_controls(vin);
   1046}
   1047
   1048static int rvin_isp_init(struct rvin_dev *vin)
   1049{
   1050	int ret;
   1051
   1052	vin->pad.flags = MEDIA_PAD_FL_SINK;
   1053	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
   1054	if (ret)
   1055		return ret;
   1056
   1057	ret = rvin_create_controls(vin, NULL);
   1058	if (ret < 0)
   1059		return ret;
   1060
   1061	ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);
   1062	if (ret)
   1063		goto err_controls;
   1064
   1065	ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);
   1066	if (ret)
   1067		goto err_group;
   1068
   1069	return 0;
   1070err_group:
   1071	rvin_group_put(vin);
   1072err_controls:
   1073	rvin_free_controls(vin);
   1074
   1075	return ret;
   1076}
   1077
   1078/* -----------------------------------------------------------------------------
   1079 * Suspend / Resume
   1080 */
   1081
   1082static int __maybe_unused rvin_suspend(struct device *dev)
   1083{
   1084	struct rvin_dev *vin = dev_get_drvdata(dev);
   1085
   1086	if (vin->state != RUNNING)
   1087		return 0;
   1088
   1089	rvin_stop_streaming(vin);
   1090
   1091	vin->state = SUSPENDED;
   1092
   1093	return 0;
   1094}
   1095
   1096static int __maybe_unused rvin_resume(struct device *dev)
   1097{
   1098	struct rvin_dev *vin = dev_get_drvdata(dev);
   1099
   1100	if (vin->state != SUSPENDED)
   1101		return 0;
   1102
   1103	/*
   1104	 * Restore group master CHSEL setting.
   1105	 *
   1106	 * This needs to be done by every VIN resuming not only the master
   1107	 * as we don't know if and in which order the master VINs will
   1108	 * be resumed.
   1109	 */
   1110	if (vin->info->use_mc) {
   1111		unsigned int master_id = rvin_group_id_to_master(vin->id);
   1112		struct rvin_dev *master = vin->group->vin[master_id];
   1113		int ret;
   1114
   1115		if (WARN_ON(!master))
   1116			return -ENODEV;
   1117
   1118		ret = rvin_set_channel_routing(master, master->chsel);
   1119		if (ret)
   1120			return ret;
   1121	}
   1122
   1123	return rvin_start_streaming(vin);
   1124}
   1125
   1126/* -----------------------------------------------------------------------------
   1127 * Platform Device Driver
   1128 */
   1129
   1130static const struct rvin_info rcar_info_h1 = {
   1131	.model = RCAR_H1,
   1132	.use_mc = false,
   1133	.max_width = 2048,
   1134	.max_height = 2048,
   1135};
   1136
   1137static const struct rvin_info rcar_info_m1 = {
   1138	.model = RCAR_M1,
   1139	.use_mc = false,
   1140	.max_width = 2048,
   1141	.max_height = 2048,
   1142};
   1143
   1144static const struct rvin_info rcar_info_gen2 = {
   1145	.model = RCAR_GEN2,
   1146	.use_mc = false,
   1147	.max_width = 2048,
   1148	.max_height = 2048,
   1149};
   1150
   1151static const struct rvin_group_route rcar_info_r8a774e1_routes[] = {
   1152	{ .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 },
   1153	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1154	{ .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 },
   1155	{ /* Sentinel */ }
   1156};
   1157
   1158static const struct rvin_info rcar_info_r8a774e1 = {
   1159	.model = RCAR_GEN3,
   1160	.use_mc = true,
   1161	.max_width = 4096,
   1162	.max_height = 4096,
   1163	.routes = rcar_info_r8a774e1_routes,
   1164};
   1165
   1166static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
   1167	{ .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 },
   1168	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1169	{ .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 },
   1170	{ .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 },
   1171	{ /* Sentinel */ }
   1172};
   1173
   1174static const struct rvin_info rcar_info_r8a7795 = {
   1175	.model = RCAR_GEN3,
   1176	.use_mc = true,
   1177	.nv12 = true,
   1178	.max_width = 4096,
   1179	.max_height = 4096,
   1180	.routes = rcar_info_r8a7795_routes,
   1181};
   1182
   1183static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
   1184	{ .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 },
   1185	{ .master = 0, .csi = RVIN_CSI21, .chsel = 0x05 },
   1186	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1187	{ .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 },
   1188	{ .master = 4, .csi = RVIN_CSI21, .chsel = 0x05 },
   1189	{ .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 },
   1190	{ /* Sentinel */ }
   1191};
   1192
   1193static const struct rvin_info rcar_info_r8a7795es1 = {
   1194	.model = RCAR_GEN3,
   1195	.use_mc = true,
   1196	.max_width = 4096,
   1197	.max_height = 4096,
   1198	.routes = rcar_info_r8a7795es1_routes,
   1199};
   1200
   1201static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
   1202	{ .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 },
   1203	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1204	{ .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 },
   1205	{ .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 },
   1206	{ /* Sentinel */ }
   1207};
   1208
   1209static const struct rvin_info rcar_info_r8a7796 = {
   1210	.model = RCAR_GEN3,
   1211	.use_mc = true,
   1212	.nv12 = true,
   1213	.max_width = 4096,
   1214	.max_height = 4096,
   1215	.routes = rcar_info_r8a7796_routes,
   1216};
   1217
   1218static const struct rvin_group_route rcar_info_r8a77965_routes[] = {
   1219	{ .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 },
   1220	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1221	{ .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 },
   1222	{ .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 },
   1223	{ /* Sentinel */ }
   1224};
   1225
   1226static const struct rvin_info rcar_info_r8a77965 = {
   1227	.model = RCAR_GEN3,
   1228	.use_mc = true,
   1229	.nv12 = true,
   1230	.max_width = 4096,
   1231	.max_height = 4096,
   1232	.routes = rcar_info_r8a77965_routes,
   1233};
   1234
   1235static const struct rvin_group_route rcar_info_r8a77970_routes[] = {
   1236	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1237	{ /* Sentinel */ }
   1238};
   1239
   1240static const struct rvin_info rcar_info_r8a77970 = {
   1241	.model = RCAR_GEN3,
   1242	.use_mc = true,
   1243	.max_width = 4096,
   1244	.max_height = 4096,
   1245	.routes = rcar_info_r8a77970_routes,
   1246};
   1247
   1248static const struct rvin_group_route rcar_info_r8a77980_routes[] = {
   1249	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1250	{ .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 },
   1251	{ /* Sentinel */ }
   1252};
   1253
   1254static const struct rvin_info rcar_info_r8a77980 = {
   1255	.model = RCAR_GEN3,
   1256	.use_mc = true,
   1257	.nv12 = true,
   1258	.max_width = 4096,
   1259	.max_height = 4096,
   1260	.routes = rcar_info_r8a77980_routes,
   1261};
   1262
   1263static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
   1264	{ .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
   1265	{ /* Sentinel */ }
   1266};
   1267
   1268static const struct rvin_info rcar_info_r8a77990 = {
   1269	.model = RCAR_GEN3,
   1270	.use_mc = true,
   1271	.nv12 = true,
   1272	.max_width = 4096,
   1273	.max_height = 4096,
   1274	.routes = rcar_info_r8a77990_routes,
   1275};
   1276
   1277static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
   1278	{ /* Sentinel */ }
   1279};
   1280
   1281static const struct rvin_info rcar_info_r8a77995 = {
   1282	.model = RCAR_GEN3,
   1283	.use_mc = true,
   1284	.nv12 = true,
   1285	.max_width = 4096,
   1286	.max_height = 4096,
   1287	.routes = rcar_info_r8a77995_routes,
   1288};
   1289
   1290static const struct rvin_info rcar_info_r8a779a0 = {
   1291	.model = RCAR_GEN3,
   1292	.use_mc = true,
   1293	.use_isp = true,
   1294	.nv12 = true,
   1295	.max_width = 4096,
   1296	.max_height = 4096,
   1297};
   1298
   1299static const struct of_device_id rvin_of_id_table[] = {
   1300	{
   1301		.compatible = "renesas,vin-r8a774a1",
   1302		.data = &rcar_info_r8a7796,
   1303	},
   1304	{
   1305		.compatible = "renesas,vin-r8a774b1",
   1306		.data = &rcar_info_r8a77965,
   1307	},
   1308	{
   1309		.compatible = "renesas,vin-r8a774c0",
   1310		.data = &rcar_info_r8a77990,
   1311	},
   1312	{
   1313		.compatible = "renesas,vin-r8a774e1",
   1314		.data = &rcar_info_r8a774e1,
   1315	},
   1316	{
   1317		.compatible = "renesas,vin-r8a7778",
   1318		.data = &rcar_info_m1,
   1319	},
   1320	{
   1321		.compatible = "renesas,vin-r8a7779",
   1322		.data = &rcar_info_h1,
   1323	},
   1324	{
   1325		.compatible = "renesas,rcar-gen2-vin",
   1326		.data = &rcar_info_gen2,
   1327	},
   1328	{
   1329		.compatible = "renesas,vin-r8a7795",
   1330		.data = &rcar_info_r8a7795,
   1331	},
   1332	{
   1333		.compatible = "renesas,vin-r8a7796",
   1334		.data = &rcar_info_r8a7796,
   1335	},
   1336	{
   1337		.compatible = "renesas,vin-r8a77961",
   1338		.data = &rcar_info_r8a7796,
   1339	},
   1340	{
   1341		.compatible = "renesas,vin-r8a77965",
   1342		.data = &rcar_info_r8a77965,
   1343	},
   1344	{
   1345		.compatible = "renesas,vin-r8a77970",
   1346		.data = &rcar_info_r8a77970,
   1347	},
   1348	{
   1349		.compatible = "renesas,vin-r8a77980",
   1350		.data = &rcar_info_r8a77980,
   1351	},
   1352	{
   1353		.compatible = "renesas,vin-r8a77990",
   1354		.data = &rcar_info_r8a77990,
   1355	},
   1356	{
   1357		.compatible = "renesas,vin-r8a77995",
   1358		.data = &rcar_info_r8a77995,
   1359	},
   1360	{
   1361		.compatible = "renesas,vin-r8a779a0",
   1362		.data = &rcar_info_r8a779a0,
   1363	},
   1364	{ /* Sentinel */ },
   1365};
   1366MODULE_DEVICE_TABLE(of, rvin_of_id_table);
   1367
   1368static const struct soc_device_attribute r8a7795es1[] = {
   1369	{
   1370		.soc_id = "r8a7795", .revision = "ES1.*",
   1371		.data = &rcar_info_r8a7795es1,
   1372	},
   1373	{ /* Sentinel */ }
   1374};
   1375
   1376static int rcar_vin_probe(struct platform_device *pdev)
   1377{
   1378	const struct soc_device_attribute *attr;
   1379	struct rvin_dev *vin;
   1380	int irq, ret;
   1381
   1382	vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
   1383	if (!vin)
   1384		return -ENOMEM;
   1385
   1386	vin->dev = &pdev->dev;
   1387	vin->info = of_device_get_match_data(&pdev->dev);
   1388	vin->alpha = 0xff;
   1389
   1390	/*
   1391	 * Special care is needed on r8a7795 ES1.x since it
   1392	 * uses different routing than r8a7795 ES2.0.
   1393	 */
   1394	attr = soc_device_match(r8a7795es1);
   1395	if (attr)
   1396		vin->info = attr->data;
   1397
   1398	vin->base = devm_platform_ioremap_resource(pdev, 0);
   1399	if (IS_ERR(vin->base))
   1400		return PTR_ERR(vin->base);
   1401
   1402	irq = platform_get_irq(pdev, 0);
   1403	if (irq < 0)
   1404		return irq;
   1405
   1406	ret = rvin_dma_register(vin, irq);
   1407	if (ret)
   1408		return ret;
   1409
   1410	platform_set_drvdata(pdev, vin);
   1411
   1412	if (vin->info->use_isp)
   1413		ret = rvin_isp_init(vin);
   1414	else if (vin->info->use_mc)
   1415		ret = rvin_csi2_init(vin);
   1416	else
   1417		ret = rvin_parallel_init(vin);
   1418
   1419	if (ret) {
   1420		rvin_dma_unregister(vin);
   1421		return ret;
   1422	}
   1423
   1424	pm_suspend_ignore_children(&pdev->dev, true);
   1425	pm_runtime_enable(&pdev->dev);
   1426
   1427	return 0;
   1428}
   1429
   1430static int rcar_vin_remove(struct platform_device *pdev)
   1431{
   1432	struct rvin_dev *vin = platform_get_drvdata(pdev);
   1433
   1434	pm_runtime_disable(&pdev->dev);
   1435
   1436	rvin_v4l2_unregister(vin);
   1437
   1438	if (vin->info->use_isp)
   1439		rvin_isp_cleanup(vin);
   1440	else if (vin->info->use_mc)
   1441		rvin_csi2_cleanup(vin);
   1442	else
   1443		rvin_parallel_cleanup(vin);
   1444
   1445	rvin_dma_unregister(vin);
   1446
   1447	return 0;
   1448}
   1449
   1450static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
   1451
   1452static struct platform_driver rcar_vin_driver = {
   1453	.driver = {
   1454		.name = "rcar-vin",
   1455		.suppress_bind_attrs = true,
   1456		.pm = &rvin_pm_ops,
   1457		.of_match_table = rvin_of_id_table,
   1458	},
   1459	.probe = rcar_vin_probe,
   1460	.remove = rcar_vin_remove,
   1461};
   1462
   1463module_platform_driver(rcar_vin_driver);
   1464
   1465MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
   1466MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
   1467MODULE_LICENSE("GPL");