From: Niklas Söderlund Date: Fri, 13 Jun 2025 15:34:26 +0000 (+0200) Subject: media: rcar-vin: Generate a VIN group ID for Gen2 X-Git-Tag: v6.17-rc1~90^2~291 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d568581b07f4ace5916e9b8b85fa2100f5716952;p=thirdparty%2Flinux.git media: rcar-vin: Generate a VIN group ID for Gen2 Prepare to move Gen2 and earlier models to media controller by generating a unique VIN group id for each VIN instance. On Gen3 and Gen4 it is important to have a specific id in the group as media graph routes depend on this. On Gen2 and earlier models all that will matter is to have a unique id in the range. Break out the id generation to a own function keeping the logic for Gen3 and Gen4 while generating a sequential id for Gen2 models. Signed-off-by: Niklas Söderlund Tested-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20250613153434.2001800-6-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index 59751ec23a156..55957dd955767 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -10,6 +10,7 @@ * Based on the soc-camera rcar_vin driver */ +#include #include #include #include @@ -55,6 +56,7 @@ * be only one group for all instances. */ +static DEFINE_IDA(rvin_ida); static DEFINE_MUTEX(rvin_group_lock); static struct rvin_group *rvin_group_data; @@ -119,23 +121,8 @@ static int rvin_group_get(struct rvin_dev *vin, const struct media_device_ops *ops) { struct rvin_group *group; - u32 id; int ret; - /* Make sure VIN id is present and sane */ - ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id); - if (ret) { - vin_err(vin, "%pOF: No renesas,id property found\n", - vin->dev->of_node); - return -EINVAL; - } - - if (id >= RCAR_VIN_NUM) { - vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", - vin->dev->of_node, id); - return -EINVAL; - } - /* Join or create a VIN group */ mutex_lock(&rvin_group_lock); if (rvin_group_data) { @@ -165,16 +152,15 @@ static int rvin_group_get(struct rvin_dev *vin, /* Add VIN to group */ mutex_lock(&group->lock); - if (group->vin[id]) { - vin_err(vin, "Duplicate renesas,id property value %u\n", id); + if (group->vin[vin->id]) { + vin_err(vin, "Duplicate renesas,id property value %u\n", vin->id); mutex_unlock(&group->lock); kref_put(&group->refcount, rvin_group_release); return -EINVAL; } - group->vin[id] = vin; + group->vin[vin->id] = vin; - vin->id = id; vin->group = group; vin->v4l2_dev.mdev = &group->mdev; @@ -1363,6 +1349,56 @@ static const struct of_device_id rvin_of_id_table[] = { }; MODULE_DEVICE_TABLE(of, rvin_of_id_table); +static int rvin_id_get(struct rvin_dev *vin) +{ + u32 oid; + int id; + + switch (vin->info->model) { + case RCAR_GEN3: + case RCAR_GEN4: + if (of_property_read_u32(vin->dev->of_node, "renesas,id", &oid)) { + vin_err(vin, "%pOF: No renesas,id property found\n", + vin->dev->of_node); + return -EINVAL; + } + + if (oid < 0 || oid >= RCAR_VIN_NUM) { + vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", + vin->dev->of_node, oid); + return -EINVAL; + } + + vin->id = oid; + break; + default: + id = ida_alloc_range(&rvin_ida, 0, RCAR_VIN_NUM - 1, + GFP_KERNEL); + if (id < 0) { + vin_err(vin, "%pOF: Failed to allocate VIN group ID\n", + vin->dev->of_node); + return -EINVAL; + } + + vin->id = id; + break; + } + + return 0; +} + +static void rvin_id_put(struct rvin_dev *vin) +{ + switch (vin->info->model) { + case RCAR_GEN3: + case RCAR_GEN4: + break; + default: + ida_free(&rvin_ida, vin->id); + break; + } +} + static int rcar_vin_probe(struct platform_device *pdev) { struct rvin_dev *vin; @@ -1390,6 +1426,11 @@ static int rcar_vin_probe(struct platform_device *pdev) platform_set_drvdata(pdev, vin); + if (rvin_id_get(vin)) { + ret = -EINVAL; + goto err_dma; + } + if (vin->info->use_isp) { ret = rvin_isp_init(vin); } else if (vin->info->use_mc) { @@ -1406,13 +1447,15 @@ static int rcar_vin_probe(struct platform_device *pdev) } if (ret) - goto err_dma; + goto err_id; pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); return 0; +err_id: + rvin_id_put(vin); err_dma: rvin_dma_unregister(vin); @@ -1434,6 +1477,8 @@ static void rcar_vin_remove(struct platform_device *pdev) else rvin_parallel_cleanup(vin); + rvin_id_put(vin); + rvin_dma_unregister(vin); }