Skip to content

drivers: bcm2835_isp: Allow multiple users for the ISP driver. #4709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 23, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 60 additions & 16 deletions drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1279,6 +1285,7 @@ static int bcm2835_isp_get_supported_fmts(struct bcm2835_isp_node *node)
* or output nodes.
*/
static int register_node(struct bcm2835_isp_dev *dev,
unsigned int instance,
struct bcm2835_isp_node *node,
int index)
{
Expand Down Expand Up @@ -1439,7 +1446,7 @@ static int register_node(struct bcm2835_isp_dev *dev,
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",
Expand Down Expand Up @@ -1660,9 +1667,8 @@ static int media_controller_register(struct bcm2835_isp_dev *dev)
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);
Expand All @@ -1677,11 +1683,11 @@ static int bcm2835_isp_remove(struct platform_device *pdev)
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;
Expand All @@ -1691,6 +1697,7 @@ static int bcm2835_isp_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;

*dev_int = dev;
dev->dev = &pdev->dev;

ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
Expand All @@ -1708,7 +1715,7 @@ static int bcm2835_isp_probe(struct platform_device *pdev)
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 ||
Expand All @@ -1720,25 +1727,62 @@ static int bcm2835_isp_probe(struct platform_device *pdev)
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);

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:
Expand Down