b2fadfb0ec8fbfe3aeecea97262366611c47699e
[openwrt/staging/blocktrron.git] /
1 From e858cd97b4301df3cc6b65f0ef16b4c1db1e1a06 Mon Sep 17 00:00:00 2001
2 From: Naushir Patuck <naush@raspberrypi.com>
3 Date: Tue, 16 Nov 2021 12:38:44 +0000
4 Subject: [PATCH] drivers: bcm2835_isp: Allow multiple users for the
5 ISP driver.
6
7 Add a second (identical) set of device nodes to allow concurrent use of the ISP
8 hardware by another user. This change effectively creates a second state
9 structure (struct bcm2835_isp_dev) to maintain independent state for the second
10 user. Node and media entity names are appened with the instance index
11 appropriately.
12
13 Further users can be added by changing the BCM2835_ISP_NUM_INSTANCES define.
14
15 Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
16 ---
17 .../bcm2835-isp/bcm2835-v4l2-isp.c | 76 +++++++++++++++----
18 1 file changed, 60 insertions(+), 16 deletions(-)
19
20 --- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
21 +++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
22 @@ -26,15 +26,21 @@
23 #include "bcm2835-isp-ctrls.h"
24 #include "bcm2835-isp-fmts.h"
25
26 +/*
27 + * We want to instantiate 2 independent instances allowing 2 simultaneous users
28 + * of the ISP hardware.
29 + */
30 +#define BCM2835_ISP_NUM_INSTANCES 2
31 +
32 MODULE_IMPORT_NS(DMA_BUF);
33
34 static unsigned int debug;
35 module_param(debug, uint, 0644);
36 MODULE_PARM_DESC(debug, "activates debug info");
37
38 -static unsigned int video_nr = 13;
39 -module_param(video_nr, uint, 0644);
40 -MODULE_PARM_DESC(video_nr, "base video device number");
41 +static unsigned int video_nr[BCM2835_ISP_NUM_INSTANCES] = { 13, 20 };
42 +module_param_array(video_nr, uint, NULL, 0644);
43 +MODULE_PARM_DESC(video_nr, "base video device numbers");
44
45 #define BCM2835_ISP_NAME "bcm2835-isp"
46 #define BCM2835_ISP_ENTITY_NAME_LEN 32
47 @@ -1281,6 +1287,7 @@ static int bcm2835_isp_get_supported_fmt
48 * or output nodes.
49 */
50 static int register_node(struct bcm2835_isp_dev *dev,
51 + unsigned int instance,
52 struct bcm2835_isp_node *node,
53 int index)
54 {
55 @@ -1441,7 +1448,7 @@ static int register_node(struct bcm2835_
56 snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
57 node->name, node->id);
58
59 - ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr + index);
60 + ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr[instance]);
61 if (ret) {
62 v4l2_err(&dev->v4l2_dev,
63 "Failed to register video %s[%d] device node\n",
64 @@ -1662,9 +1669,8 @@ done:
65 return ret;
66 }
67
68 -static int bcm2835_isp_remove(struct platform_device *pdev)
69 +static void bcm2835_isp_remove_instance(struct bcm2835_isp_dev *dev)
70 {
71 - struct bcm2835_isp_dev *dev = platform_get_drvdata(pdev);
72 unsigned int i;
73
74 media_controller_unregister(dev);
75 @@ -1679,11 +1685,11 @@ static int bcm2835_isp_remove(struct pla
76 dev->component);
77
78 vchiq_mmal_finalise(dev->mmal_instance);
79 -
80 - return 0;
81 }
82
83 -static int bcm2835_isp_probe(struct platform_device *pdev)
84 +static int bcm2835_isp_probe_instance(struct platform_device *pdev,
85 + struct bcm2835_isp_dev **dev_int,
86 + unsigned int instance)
87 {
88 struct bcm2835_isp_dev *dev;
89 unsigned int i;
90 @@ -1693,6 +1699,7 @@ static int bcm2835_isp_probe(struct plat
91 if (!dev)
92 return -ENOMEM;
93
94 + *dev_int = dev;
95 dev->dev = &pdev->dev;
96
97 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
98 @@ -1710,7 +1717,7 @@ static int bcm2835_isp_probe(struct plat
99 if (ret) {
100 v4l2_err(&dev->v4l2_dev,
101 "%s: failed to create ril.isp component\n", __func__);
102 - goto error;
103 + return ret;
104 }
105
106 if (dev->component->inputs < BCM2835_ISP_NUM_OUTPUTS ||
107 @@ -1722,7 +1729,7 @@ static int bcm2835_isp_probe(struct plat
108 BCM2835_ISP_NUM_OUTPUTS,
109 dev->component->outputs,
110 BCM2835_ISP_NUM_CAPTURES + BCM2835_ISP_NUM_METADATA);
111 - goto error;
112 + return -EINVAL;
113 }
114
115 atomic_set(&dev->num_streaming, 0);
116 @@ -1730,17 +1737,54 @@ static int bcm2835_isp_probe(struct plat
117 for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
118 struct bcm2835_isp_node *node = &dev->node[i];
119
120 - ret = register_node(dev, node, i);
121 + ret = register_node(dev, instance, node, i);
122 if (ret)
123 - goto error;
124 + return ret;
125 }
126
127 ret = media_controller_register(dev);
128 if (ret)
129 - goto error;
130 + return ret;
131 +
132 + return 0;
133 +}
134 +
135 +static int bcm2835_isp_remove(struct platform_device *pdev)
136 +{
137 + struct bcm2835_isp_dev **bcm2835_isp_instances;
138 + unsigned int i;
139 +
140 + bcm2835_isp_instances = platform_get_drvdata(pdev);
141 + for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
142 + if (bcm2835_isp_instances[i])
143 + bcm2835_isp_remove_instance(bcm2835_isp_instances[i]);
144 + }
145 +
146 + return 0;
147 +}
148 +
149 +static int bcm2835_isp_probe(struct platform_device *pdev)
150 +{
151 + struct bcm2835_isp_dev **bcm2835_isp_instances;
152 + unsigned int i;
153 + int ret;
154 +
155 + bcm2835_isp_instances = devm_kzalloc(&pdev->dev,
156 + sizeof(bcm2835_isp_instances) *
157 + BCM2835_ISP_NUM_INSTANCES,
158 + GFP_KERNEL);
159 + if (!bcm2835_isp_instances)
160 + return -ENOMEM;
161 +
162 + for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
163 + ret = bcm2835_isp_probe_instance(pdev,
164 + &bcm2835_isp_instances[i], i);
165 + if (ret)
166 + goto error;
167 + }
168
169 - platform_set_drvdata(pdev, dev);
170 - v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
171 + platform_set_drvdata(pdev, bcm2835_isp_instances);
172 + dev_info(&pdev->dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
173 return 0;
174
175 error: