summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe/cal.c
diff options
context:
space:
mode:
authorSteve Longerbeam <slongerbeam@gmail.com>2018-09-29 15:54:18 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-10-04 15:55:38 -0400
commitd079f94c90469f413920b9f2b201537fac2ceb06 (patch)
tree81c01fba155425c957a7f827963b32efa9e0d872 /drivers/media/platform/ti-vpe/cal.c
parentd5099f81803fc7a7831aa893097fab3cf8d15d3e (diff)
downloadtalos-obmc-linux-d079f94c90469f413920b9f2b201537fac2ceb06.tar.gz
talos-obmc-linux-d079f94c90469f413920b9f2b201537fac2ceb06.zip
media: platform: Switch to v4l2_async_notifier_add_subdev
Switch all media platform drivers to call v4l2_async_notifier_add_subdev() to add asd's to a notifier, in place of referencing the notifier->subdevs[] array. These drivers also must now call v4l2_async_notifier_init() before adding asd's to their notifiers. There may still be cases where a platform driver maintains a list of asd's that is a duplicate of the notifier asd_list, in which case its possible the platform driver list can be removed, and can reference the notifier asd_list instead. One example of where a duplicate list has been removed in this patch is xilinx-vipp.c. If there are such cases remaining, those drivers should be optimized to remove the duplicate platform driver asd lists. None of the changes to the platform drivers in this patch have been tested. Verify that the async subdevices needed by the platform are bound at load time, and that the driver unloads and reloads correctly with no memory leaking of asd objects. Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/ti-vpe/cal.c')
-rw-r--r--drivers/media/platform/ti-vpe/cal.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 5f9d4e016d43..51f604332eea 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -270,7 +270,6 @@ struct cal_ctx {
struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_subdev asd;
- struct v4l2_async_subdev *asd_list[1];
struct v4l2_fh fh;
struct cal_dev *dev;
@@ -1735,17 +1734,30 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
ctx_dbg(1, ctx, "Port: %d found sub-device %pOFn\n",
inst, sensor_node);
- ctx->asd_list[0] = asd;
- ctx->notifier.subdevs = ctx->asd_list;
- ctx->notifier.num_subdevs = 1;
+ v4l2_async_notifier_init(&ctx->notifier);
+
+ ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd);
+ if (ret) {
+ ctx_err(ctx, "Error adding asd\n");
+ goto cleanup_exit;
+ }
+
ctx->notifier.ops = &cal_async_ops;
ret = v4l2_async_notifier_register(&ctx->v4l2_dev,
&ctx->notifier);
if (ret) {
ctx_err(ctx, "Error registering async notifier\n");
+ v4l2_async_notifier_cleanup(&ctx->notifier);
ret = -EINVAL;
}
+ /*
+ * On success we need to keep reference on sensor_node, or
+ * if notifier_cleanup was called above, sensor_node was
+ * already put.
+ */
+ sensor_node = NULL;
+
cleanup_exit:
of_node_put(remote_ep);
of_node_put(sensor_node);
@@ -1806,8 +1818,10 @@ err_exit:
static int cal_probe(struct platform_device *pdev)
{
struct cal_dev *dev;
+ struct cal_ctx *ctx;
int ret;
int irq;
+ int i;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -1875,6 +1889,16 @@ static int cal_probe(struct platform_device *pdev)
runtime_disable:
pm_runtime_disable(&pdev->dev);
+ for (i = 0; i < CAL_NUM_CONTEXT; i++) {
+ ctx = dev->ctx[i];
+ if (ctx) {
+ v4l2_async_notifier_unregister(&ctx->notifier);
+ v4l2_async_notifier_cleanup(&ctx->notifier);
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_device_unregister(&ctx->v4l2_dev);
+ }
+ }
+
return ret;
}
@@ -1896,6 +1920,7 @@ static int cal_remove(struct platform_device *pdev)
video_device_node_name(&ctx->vdev));
camerarx_phy_disable(ctx);
v4l2_async_notifier_unregister(&ctx->notifier);
+ v4l2_async_notifier_cleanup(&ctx->notifier);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
v4l2_device_unregister(&ctx->v4l2_dev);
video_unregister_device(&ctx->vdev);
OpenPOWER on IntegriCloud