Skip to content

Commit c9a44c3

Browse files
committed
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 <[email protected]>
1 parent 46c99e3 commit c9a44c3

File tree

1 file changed

+71
-25
lines changed

1 file changed

+71
-25
lines changed

drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,19 @@
2626
#include "bcm2835-isp-ctrls.h"
2727
#include "bcm2835-isp-fmts.h"
2828

29+
/*
30+
* We want to instantiate 2 independent instances allowing 2 simultaneous users
31+
* of the ISP hardware.
32+
*/
33+
#define BCM2835_ISP_NUM_INSTANCES 2
34+
2935
static unsigned int debug;
3036
module_param(debug, uint, 0644);
3137
MODULE_PARM_DESC(debug, "activates debug info");
3238

33-
static unsigned int video_nr = 13;
34-
module_param(video_nr, uint, 0644);
35-
MODULE_PARM_DESC(video_nr, "base video device number");
39+
static unsigned int video_nr[BCM2835_ISP_NUM_INSTANCES] = { 13, 20 };
40+
module_param_array(video_nr, uint, NULL, 0644);
41+
MODULE_PARM_DESC(video_nr, "base video device numbers");
3642

3743
#define BCM2835_ISP_NAME "bcm2835-isp"
3844
#define BCM2835_ISP_ENTITY_NAME_LEN 32
@@ -1279,6 +1285,7 @@ static int bcm2835_isp_get_supported_fmts(struct bcm2835_isp_node *node)
12791285
* or output nodes.
12801286
*/
12811287
static int register_node(struct bcm2835_isp_dev *dev,
1288+
unsigned int instance,
12821289
struct bcm2835_isp_node *node,
12831290
int index)
12841291
{
@@ -1436,10 +1443,10 @@ static int register_node(struct bcm2835_isp_dev *dev,
14361443
}
14371444

14381445
/* Define the device names */
1439-
snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME,
1440-
node->name, node->id);
1446+
snprintf(vfd->name, sizeof(node->vfd.name), "%s%d-%s%d",
1447+
BCM2835_ISP_NAME, instance, node->name, node->id);
14411448

1442-
ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr + index);
1449+
ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr[instance]);
14431450
if (ret) {
14441451
v4l2_err(&dev->v4l2_dev,
14451452
"Failed to register video %s[%d] device node\n",
@@ -1526,7 +1533,8 @@ static void media_controller_unregister(struct bcm2835_isp_dev *dev)
15261533
dev->v4l2_dev.mdev = NULL;
15271534
}
15281535

1529-
static int media_controller_register_node(struct bcm2835_isp_dev *dev, int num)
1536+
static int media_controller_register_node(struct bcm2835_isp_dev *dev,
1537+
unsigned int instance, int num)
15301538
{
15311539
struct bcm2835_isp_node *node = &dev->node[num];
15321540
struct media_entity *entity = &node->vfd.entity;
@@ -1546,8 +1554,8 @@ static int media_controller_register_node(struct bcm2835_isp_dev *dev, int num)
15461554
ret = -ENOMEM;
15471555
goto error_no_mem;
15481556
}
1549-
snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, "%s0-%s%d",
1550-
BCM2835_ISP_NAME, output ? "output" : "capture", num);
1557+
snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, "%s%d-%s%d",
1558+
BCM2835_ISP_NAME, instance, output ? "output" : "capture", num);
15511559
entity->name = name;
15521560
node->pad.flags = output ? MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
15531561
ret = media_entity_pads_init(entity, 1, &node->pad);
@@ -1605,7 +1613,8 @@ static int media_controller_register_node(struct bcm2835_isp_dev *dev, int num)
16051613
return ret;
16061614
}
16071615

1608-
static int media_controller_register(struct bcm2835_isp_dev *dev)
1616+
static int media_controller_register(struct bcm2835_isp_dev *dev,
1617+
unsigned int instance)
16091618
{
16101619
char *name;
16111620
unsigned int i;
@@ -1627,7 +1636,7 @@ static int media_controller_register(struct bcm2835_isp_dev *dev)
16271636
ret = -ENOMEM;
16281637
goto done;
16291638
}
1630-
snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, "bcm2835_isp0");
1639+
snprintf(name, BCM2835_ISP_ENTITY_NAME_LEN, BCM2835_ISP_NAME);
16311640
dev->entity.name = name;
16321641
dev->entity.obj_type = MEDIA_ENTITY_TYPE_BASE;
16331642
dev->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
@@ -1648,7 +1657,7 @@ static int media_controller_register(struct bcm2835_isp_dev *dev)
16481657

16491658
dev->media_entity_registered = true;
16501659
for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
1651-
ret = media_controller_register_node(dev, i);
1660+
ret = media_controller_register_node(dev, instance, i);
16521661
if (ret)
16531662
goto done;
16541663
}
@@ -1660,9 +1669,8 @@ static int media_controller_register(struct bcm2835_isp_dev *dev)
16601669
return ret;
16611670
}
16621671

1663-
static int bcm2835_isp_remove(struct platform_device *pdev)
1672+
static void bcm2835_isp_remove_instance(struct bcm2835_isp_dev *dev)
16641673
{
1665-
struct bcm2835_isp_dev *dev = platform_get_drvdata(pdev);
16661674
unsigned int i;
16671675

16681676
media_controller_unregister(dev);
@@ -1677,11 +1685,11 @@ static int bcm2835_isp_remove(struct platform_device *pdev)
16771685
dev->component);
16781686

16791687
vchiq_mmal_finalise(dev->mmal_instance);
1680-
1681-
return 0;
16821688
}
16831689

1684-
static int bcm2835_isp_probe(struct platform_device *pdev)
1690+
static int bcm2835_isp_probe_instance(struct platform_device *pdev,
1691+
struct bcm2835_isp_dev **dev_int,
1692+
unsigned int instance)
16851693
{
16861694
struct bcm2835_isp_dev *dev;
16871695
unsigned int i;
@@ -1708,7 +1716,7 @@ static int bcm2835_isp_probe(struct platform_device *pdev)
17081716
if (ret) {
17091717
v4l2_err(&dev->v4l2_dev,
17101718
"%s: failed to create ril.isp component\n", __func__);
1711-
goto error;
1719+
return ret;
17121720
}
17131721

17141722
if (dev->component->inputs < BCM2835_ISP_NUM_OUTPUTS ||
@@ -1720,25 +1728,63 @@ static int bcm2835_isp_probe(struct platform_device *pdev)
17201728
BCM2835_ISP_NUM_OUTPUTS,
17211729
dev->component->outputs,
17221730
BCM2835_ISP_NUM_CAPTURES + BCM2835_ISP_NUM_METADATA);
1723-
goto error;
1731+
return -EINVAL;
17241732
}
17251733

17261734
atomic_set(&dev->num_streaming, 0);
17271735

17281736
for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) {
17291737
struct bcm2835_isp_node *node = &dev->node[i];
17301738

1731-
ret = register_node(dev, node, i);
1739+
ret = register_node(dev, instance, node, i);
17321740
if (ret)
1733-
goto error;
1741+
return ret;
17341742
}
17351743

1736-
ret = media_controller_register(dev);
1744+
ret = media_controller_register(dev, instance);
17371745
if (ret)
1738-
goto error;
1746+
return ret;
1747+
1748+
*dev_int = dev;
1749+
return 0;
1750+
}
1751+
1752+
static int bcm2835_isp_remove(struct platform_device *pdev)
1753+
{
1754+
struct bcm2835_isp_dev **bcm2835_isp_instances;
1755+
unsigned int i;
1756+
1757+
bcm2835_isp_instances = platform_get_drvdata(pdev);
1758+
for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
1759+
if (bcm2835_isp_instances[i])
1760+
bcm2835_isp_remove_instance(bcm2835_isp_instances[i]);
1761+
}
1762+
1763+
return 0;
1764+
}
1765+
1766+
static int bcm2835_isp_probe(struct platform_device *pdev)
1767+
{
1768+
struct bcm2835_isp_dev **bcm2835_isp_instances;
1769+
unsigned int i;
1770+
int ret;
1771+
1772+
bcm2835_isp_instances = devm_kzalloc(&pdev->dev,
1773+
sizeof(bcm2835_isp_instances) *
1774+
BCM2835_ISP_NUM_INSTANCES,
1775+
GFP_KERNEL);
1776+
if (!bcm2835_isp_instances)
1777+
return -ENOMEM;
1778+
1779+
for (i = 0; i < BCM2835_ISP_NUM_INSTANCES; i++) {
1780+
ret = bcm2835_isp_probe_instance(pdev,
1781+
&bcm2835_isp_instances[i], i);
1782+
if (ret)
1783+
goto error;
1784+
}
17391785

1740-
platform_set_drvdata(pdev, dev);
1741-
v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
1786+
platform_set_drvdata(pdev, bcm2835_isp_instances);
1787+
dev_info(&pdev->dev, "Loaded V4L2 %s\n", BCM2835_ISP_NAME);
17421788
return 0;
17431789

17441790
error:

0 commit comments

Comments
 (0)