aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch173
1 files changed, 173 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch b/target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch
new file mode 100644
index 0000000000..a9bb7ecba3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.15/950-0574-drivers-bcm2835_isp-Allow-multiple-users-for-the-ISP.patch
@@ -0,0 +1,173 @@
+From 3d3cffb860398e43856ac5f2c831cb042be68795 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Tue, 16 Nov 2021 12:38:44 +0000
+Subject: [PATCH] drivers: bcm2835_isp: Allow multiple users for the
+ ISP driver.
+
+Add a second (identical) set of device nodes to allow concurrent use of the ISP
+hardware by another user. This change effectively creates a second state
+structure (struct bcm2835_isp_dev) to maintain independent state for the second
+user. Node and media entity names are appened with the instance index
+appropriately.
+
+Further users can be added by changing the BCM2835_ISP_NUM_INSTANCES define.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../bcm2835-isp/bcm2835-v4l2-isp.c | 76 +++++++++++++++----
+ 1 file changed, 60 insertions(+), 16 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
+@@ -26,13 +26,19 @@
+ #include "bcm2835-isp-ctrls.h"
+ #include "bcm2835-isp-fmts.h"
+
++/*
++ * We want to instantiate 2 independent instances allowing 2 simultaneous users
++ * of the ISP hardware.
++ */
++#define BCM2835_ISP_NUM_INSTANCES 2
++
+ static unsigned int debug;
+ module_param(debug, uint, 0644);
+ MODULE_PARM_DESC(debug, "activates debug info");
+
+-static unsigned int video_nr = 13;
+-module_param(video_nr, uint, 0644);
+-MODULE_PARM_DESC(video_nr, "base video device number");
++static unsigned int video_nr[BCM2835_ISP_NUM_INSTANCES] = { 13, 20 };
++module_param_array(video_nr, uint, NULL, 0644);
++MODULE_PARM_DESC(video_nr, "base video device numbers");
+
+ #define BCM2835_ISP_NAME "bcm2835-isp"
+ #define BCM2835_ISP_ENTITY_NAME_LEN 32
+@@ -1279,6 +1285,7 @@ static int bcm2835_isp_get_supported_fmt
+ * or output nodes.
+ */
+ static int register_node(struct bcm2835_isp_dev *dev,
++ unsigned int instance,
+ struct bcm2835_isp_node *node,
+ int index)
+ {
+@@ -1439,7 +1446,7 @@ static int register_node(struct bcm2835_
+ snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
+ node->name, node->id);
+
+- ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr + index);
++ ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr[instance]);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev,
+ "Failed to register video %s[%d] device node\n",
+@@ -1660,9 +1667,8 @@ done:
+ return ret;
+ }
+
+-static int bcm2835_isp_remove(struct platform_device *pdev)
++static void bcm2835_isp_remove_instance(struct bcm2835_isp_dev *dev)
+ {
+- struct bcm2835_isp_dev *dev = platform_get_drvdata(pdev);
+ unsigned int i;
+
+ media_controller_unregister(dev);
+@@ -1677,11 +1683,11 @@ static int bcm2835_isp_remove(struct pla
+ dev->component);
+
+ vchiq_mmal_finalise(dev->mmal_instance);
+-
+- return 0;
+ }
+
+-static int bcm2835_isp_probe(struct platform_device *pdev)
++static int bcm2835_isp_probe_instance(struct platform_device *pdev,
++ struct bcm2835_isp_dev **dev_int,
++ unsigned int instance)
+ {
+ struct bcm2835_isp_dev *dev;
+ unsigned int i;
+@@ -1691,6 +1697,7 @@ static int bcm2835_isp_probe(struct plat
+ if (!dev)
+ return -ENOMEM;
+
++ *dev_int = dev;
+ dev->dev = &pdev->dev;
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+@@ -1708,7 +1715,7 @@ static int bcm2835_isp_probe(struct plat
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev,
+ "%s: failed to create ril.isp component\n", __func__);
+- goto error;
++ return ret;
+ }
+
+ if (dev->component->inputs < BCM2835_ISP_NUM_OUTPUTS ||
+@@ -1720,7 +1727,7 @@ static int bcm2835_isp_probe(struct plat
+ BCM2835_ISP_NUM_OUTPUTS,
+ dev->component->outputs,
+ BCM2835_ISP_NUM_CAPTURES + BCM2835_ISP_NUM_METADATA);
+- goto error;
++ return -EINVAL;
+ }
+
+ atomic_set(&dev->num_streaming, 0);
+@@ -1728,17 +1735,54 @@ static int bcm2835_isp_probe(struct plat
+ for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
+ struct bcm2835_isp_node *node = &dev->node[i];
+
+- ret = register_node(dev, node, i);
++ ret = register_node(dev, instance, node, i);
+ if (ret)
+- goto error;
++ return ret;
+ }
+
+ ret = media_controller_register(dev);
+ if (ret)
+- goto error;
++ return ret;
++
++ return 0;
++}
++
++static int bcm2835_isp_remove(struct platform_device *pdev)
++{
++ struct bcm2835_isp_dev **bcm2835_isp_instances;
++ unsigned int i;
++
++ bcm2835_isp_instances = platform_get_drvdata(pdev);
++ for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
++ if (bcm2835_isp_instances[i])
++ bcm2835_isp_remove_instance(bcm2835_isp_instances[i]);
++ }
++
++ return 0;
++}
++
++static int bcm2835_isp_probe(struct platform_device *pdev)
++{
++ struct bcm2835_isp_dev **bcm2835_isp_instances;
++ unsigned int i;
++ int ret;
++
++ bcm2835_isp_instances = devm_kzalloc(&pdev->dev,
++ sizeof(bcm2835_isp_instances) *
++ BCM2835_ISP_NUM_INSTANCES,
++ GFP_KERNEL);
++ if (!bcm2835_isp_instances)
++ return -ENOMEM;
++
++ for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
++ ret = bcm2835_isp_probe_instance(pdev,
++ &bcm2835_isp_instances[i], i);
++ if (ret)
++ goto error;
++ }
+
+- platform_set_drvdata(pdev, dev);
+- v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
++ platform_set_drvdata(pdev, bcm2835_isp_instances);
++ dev_info(&pdev->dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
+ return 0;
+
+ error: