|
@@ -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;
|
|
|
}
|