summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>2021-07-09 16:25:57 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-09-30 10:07:34 +0200
commitcfef0c833a8dddf09d9f7d490a0fadbe81b91793 (patch)
treebab8fa3469e867c3bb3ee695f1dbe0ad34377530 /drivers/media
parent9c83300146b3ef592273ff8b09884d6181be3020 (diff)
media: rcar-vin: Create a callback to setup media links
New IP versions will have different media graphs and require a different link setup. Breakout the specific link setup to a callback that are associated with the group. Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c101
-rw-r--r--drivers/media/platform/rcar-vin/rcar-vin.h3
2 files changed, 59 insertions, 45 deletions
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index ae2a145b04f6..d04c222702ba 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -247,7 +247,8 @@ static void rvin_group_cleanup(struct rvin_group *group)
mutex_destroy(&group->lock);
}
-static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
+static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
+ int (*link_setup)(struct rvin_dev *))
{
struct media_device *mdev = &group->mdev;
const struct of_device_id *match;
@@ -263,6 +264,8 @@ static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
+ group->link_setup = link_setup;
+
mdev->dev = vin->dev;
mdev->ops = &rvin_media_ops;
@@ -295,7 +298,8 @@ static void rvin_group_release(struct kref *kref)
mutex_unlock(&rvin_group_lock);
}
-static int rvin_group_get(struct rvin_dev *vin)
+static int rvin_group_get(struct rvin_dev *vin,
+ int (*link_setup)(struct rvin_dev *))
{
struct rvin_group *group;
u32 id;
@@ -327,7 +331,7 @@ static int rvin_group_get(struct rvin_dev *vin)
goto err_group;
}
- ret = rvin_group_init(group, vin);
+ ret = rvin_group_init(group, vin, link_setup);
if (ret) {
kfree(group);
vin_err(vin, "Failed to initialize group\n");
@@ -386,7 +390,6 @@ out:
static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
{
struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
- const struct rvin_group_route *route;
unsigned int i;
int ret;
@@ -410,46 +413,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
}
}
- /* Create all media device links between VINs and CSI-2's. */
- mutex_lock(&vin->group->lock);
- for (route = vin->info->routes; route->mask; route++) {
- struct media_pad *source_pad, *sink_pad;
- struct media_entity *source, *sink;
- unsigned int source_idx;
-
- /* Check that VIN is part of the group. */
- if (!vin->group->vin[route->vin])
- continue;
-
- /* Check that VIN' master is part of the group. */
- if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
- continue;
-
- /* Check that CSI-2 is part of the group. */
- if (!vin->group->remotes[route->csi].subdev)
- continue;
-
- source = &vin->group->remotes[route->csi].subdev->entity;
- source_idx = rvin_group_csi_channel_to_pad(route->channel);
- source_pad = &source->pads[source_idx];
-
- sink = &vin->group->vin[route->vin]->vdev.entity;
- sink_pad = &sink->pads[0];
-
- /* Skip if link already exists. */
- if (media_entity_find_link(source_pad, sink_pad))
- continue;
-
- ret = media_create_pad_link(source, source_idx, sink, 0, 0);
- if (ret) {
- vin_err(vin, "Error adding link from %s to %s\n",
- source->name, sink->name);
- break;
- }
- }
- mutex_unlock(&vin->group->lock);
-
- return ret;
+ return vin->group->link_setup(vin);
}
static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -953,6 +917,53 @@ static int rvin_parallel_init(struct rvin_dev *vin)
* CSI-2
*/
+static int rvin_csi2_setup_links(struct rvin_dev *vin)
+{
+ const struct rvin_group_route *route;
+ int ret = -EINVAL;
+
+ /* Create all media device links between VINs and CSI-2's. */
+ mutex_lock(&vin->group->lock);
+ for (route = vin->info->routes; route->mask; route++) {
+ struct media_pad *source_pad, *sink_pad;
+ struct media_entity *source, *sink;
+ unsigned int source_idx;
+
+ /* Check that VIN is part of the group. */
+ if (!vin->group->vin[route->vin])
+ continue;
+
+ /* Check that VIN' master is part of the group. */
+ if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
+ continue;
+
+ /* Check that CSI-2 is part of the group. */
+ if (!vin->group->remotes[route->csi].subdev)
+ continue;
+
+ source = &vin->group->remotes[route->csi].subdev->entity;
+ source_idx = rvin_group_csi_channel_to_pad(route->channel);
+ source_pad = &source->pads[source_idx];
+
+ sink = &vin->group->vin[route->vin]->vdev.entity;
+ sink_pad = &sink->pads[0];
+
+ /* Skip if link already exists. */
+ if (media_entity_find_link(source_pad, sink_pad))
+ continue;
+
+ ret = media_create_pad_link(source, source_idx, sink, 0, 0);
+ if (ret) {
+ vin_err(vin, "Error adding link from %s to %s\n",
+ source->name, sink->name);
+ break;
+ }
+ }
+ mutex_unlock(&vin->group->lock);
+
+ return ret;
+}
+
static void rvin_csi2_cleanup(struct rvin_dev *vin)
{
rvin_parallel_cleanup(vin);
@@ -974,7 +985,7 @@ static int rvin_csi2_init(struct rvin_dev *vin)
if (ret < 0)
return ret;
- ret = rvin_group_get(vin);
+ ret = rvin_group_get(vin, rvin_csi2_setup_links);
if (ret)
goto err_controls;
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 39207aaf39ef..49c148c40ea5 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -269,6 +269,7 @@ struct rvin_dev {
* @count: number of enabled VIN instances found in DT
* @notifier: group notifier for CSI-2 async subdevices
* @vin: VIN instances which are part of the group
+ * @link_setup: Callback to create all links for the media graph
* @remotes: array of pairs of fwnode and subdev pointers
* to all remote subdevices.
*/
@@ -282,6 +283,8 @@ struct rvin_group {
struct v4l2_async_notifier notifier;
struct rvin_dev *vin[RCAR_VIN_NUM];
+ int (*link_setup)(struct rvin_dev *vin);
+
struct {
struct v4l2_async_subdev *asd;
struct v4l2_subdev *subdev;