diff options
Diffstat (limited to 'drivers/media/platform/ti-vpe/cal.c')
-rw-r--r-- | drivers/media/platform/ti-vpe/cal.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index d1febe5baa6d..95a093f41905 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; @@ -912,8 +911,8 @@ static int cal_querycap(struct file *file, void *priv, { struct cal_ctx *ctx = video_drvdata(file); - strlcpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card)); + strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver)); + strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", ctx->v4l2_dev.name); @@ -1711,9 +1710,9 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) } v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint); - if (endpoint->bus_type != V4L2_MBUS_CSI2) { - ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n", - inst, sensor_node->name); + if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) { + ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n", + inst, sensor_node); goto cleanup_exit; } @@ -1732,29 +1731,38 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) endpoint->bus.mipi_csi2.data_lanes[lane]); ctx_dbg(3, ctx, "\t>\n"); - ctx_dbg(1, ctx, "Port: %d found sub-device %s\n", - inst, sensor_node->name); + ctx_dbg(1, ctx, "Port: %d found sub-device %pOFn\n", + inst, sensor_node); + + 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->asd_list[0] = asd; - ctx->notifier.subdevs = ctx->asd_list; - ctx->notifier.num_subdevs = 1; 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: - if (remote_ep) - of_node_put(remote_ep); - if (sensor_node) - of_node_put(sensor_node); - if (ep_node) - of_node_put(ep_node); - if (port) - of_node_put(port); + of_node_put(remote_ep); + of_node_put(sensor_node); + of_node_put(ep_node); + of_node_put(port); return ret; } @@ -1810,15 +1818,17 @@ 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) return -ENOMEM; /* set pseudo v4l2 device name so we can use v4l2_printk */ - strlcpy(dev->v4l2_dev.name, CAL_MODULE_NAME, + strscpy(dev->v4l2_dev.name, CAL_MODULE_NAME, sizeof(dev->v4l2_dev.name)); /* save pdev pointer */ @@ -1879,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; } @@ -1900,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); |