summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/rcar-vin
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo+renesas@jmondi.org>2018-06-12 05:43:28 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-07-04 09:21:04 -0400
commita597a772cd3f51193e1917a729db8a991615341b (patch)
tree2433005b7d83880ead703632899e695733c00b9a /drivers/media/platform/rcar-vin
parent158e2a53fc9620fac7ebbb83223ec18280bd34f0 (diff)
downloadlinux-a597a772cd3f51193e1917a729db8a991615341b.tar.bz2
media: rcar-vin: Parse parallel input on Gen3
The rcar-vin driver so far had a mutually exclusive code path for handling parallel and CSI-2 video input subdevices, with only the CSI-2 use case supporting media-controller. As we add support for parallel inputs to Gen3 media-controller compliant code path now parse both port@0 and port@1, handling the media-controller use case in the parallel bound/unbind notifier operations. Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/rcar-vin')
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 7f84c7b9518a..e9b5b83122e6 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -397,6 +397,11 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
vin->parallel->sink_pad = ret < 0 ? 0 : ret;
+ if (vin->info->use_mc) {
+ vin->parallel->subdev = subdev;
+ return 0;
+ }
+
/* Find compatible subdevices mbus format */
vin->mbus_code = 0;
code.index = 0;
@@ -458,10 +463,12 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
{
rvin_v4l2_unregister(vin);
- v4l2_ctrl_handler_free(&vin->ctrl_handler);
-
- vin->vdev.ctrl_handler = NULL;
vin->parallel->subdev = NULL;
+
+ if (!vin->info->use_mc) {
+ v4l2_ctrl_handler_free(&vin->ctrl_handler);
+ vin->vdev.ctrl_handler = NULL;
+ }
}
static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
@@ -550,18 +557,19 @@ static int rvin_parallel_parse_v4l2(struct device *dev,
return 0;
}
-static int rvin_parallel_graph_init(struct rvin_dev *vin)
+static int rvin_parallel_init(struct rvin_dev *vin)
{
int ret;
- ret = v4l2_async_notifier_parse_fwnode_endpoints(
- vin->dev, &vin->notifier,
- sizeof(struct rvin_parallel_entity), rvin_parallel_parse_v4l2);
+ ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
+ vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity),
+ 0, rvin_parallel_parse_v4l2);
if (ret)
return ret;
+ /* If using mc, it's fine not to have any input registered. */
if (!vin->parallel)
- return -ENODEV;
+ return vin->info->use_mc ? 0 : -ENODEV;
vin_dbg(vin, "Found parallel subdevice %pOF\n",
to_of_node(vin->parallel->asd.match.fwnode));
@@ -1122,20 +1130,35 @@ static int rcar_vin_probe(struct platform_device *pdev)
return ret;
platform_set_drvdata(pdev, vin);
- if (vin->info->use_mc)
+
+ if (vin->info->use_mc) {
ret = rvin_mc_init(vin);
- else
- ret = rvin_parallel_graph_init(vin);
- if (ret < 0)
- goto error;
+ if (ret)
+ goto error_dma_unregister;
+ }
+
+ ret = rvin_parallel_init(vin);
+ if (ret)
+ goto error_group_unregister;
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
return 0;
-error:
+
+error_group_unregister:
+ if (vin->info->use_mc) {
+ mutex_lock(&vin->group->lock);
+ if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
+ v4l2_async_notifier_unregister(&vin->group->notifier);
+ v4l2_async_notifier_cleanup(&vin->group->notifier);
+ }
+ mutex_unlock(&vin->group->lock);
+ rvin_group_put(vin);
+ }
+
+error_dma_unregister:
rvin_dma_unregister(vin);
- v4l2_async_notifier_cleanup(&vin->notifier);
return ret;
}