On Fri Jun 13 17:34:26 2025 +0200, Niklas Söderlund wrote:
> 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 <niklas.soderlund+rene...@ragnatech.se>
> Tested-by: Tomi Valkeinen <tomi.valkeinen+rene...@ideasonboard.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> Link: 
> https://lore.kernel.org/r/20250613153434.2001800-6-niklas.soderlund+rene...@ragnatech.se
> Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 .../media/platform/renesas/rcar-vin/rcar-core.c    | 85 +++++++++++++++++-----
 1 file changed, 65 insertions(+), 20 deletions(-)

---

diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c 
b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
index 59751ec23a15..55957dd95576 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 <linux/idr.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -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);
 }
 

Reply via email to