mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 19:43:40 +02:00
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 <niklas.soderlund+renesas@ragnatech.se> Tested-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://lore.kernel.org/r/20250613153434.2001800-6-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
parent
b38ba9b160
commit
d568581b07
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user