From 7d931ef33d92e7d3a3b6d2b6846f7026d0f2733d Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 29 Dec 2023 07:39:16 +0000 Subject: [PATCH] camera: vi: Use proper APIs from v4l2 for Linux6.6 The earlier porting of the driver for Linux 6.6 is not matching with the previous kernel implementation. Few V4L2 APIs have been deprecated from Linux 6.6. and added the new APIs. Use the correct API available from Linux6.6 for the replacement as the previous supported kernel APIs. For reference, the changes in core kernels are: The device argument is added in the API v4l2_async_nf_init() with commit b8ec754ae4c5 ("media: v4l: async: Set v4l2_device and subdev in async notifier init") in Linux 6.6. The API is removed with commit bda8953e8c3e ("media: v4l: async: Drop v4l2_async_nf_parse_fwnode_endpoints()") in Linux 6.6 Bug 4346767 Change-Id: I94877a8fe6a6764fc3c913fea7ecdbfdc7c793d6 Signed-off-by: Laxman Dewangan Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3042993 GVS: Gerrit_Virtual_Submit --- .../media/platform/tegra/camera/vi/graph.c | 41 +++++++++++-------- include/media/mc_common.h | 2 +- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/tegra/camera/vi/graph.c b/drivers/media/platform/tegra/camera/vi/graph.c index 06cc3490..b578792a 100644 --- a/drivers/media/platform/tegra/camera/vi/graph.c +++ b/drivers/media/platform/tegra/camera/vi/graph.c @@ -479,12 +479,14 @@ static int tegra_vi_graph_parse_one(struct tegra_channel *chan, } entity->node = remote; +#if !defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */ #if defined(NV_V4L2_ASYNC_MATCH_TYPE_ENUM_PRESENT) /* Linux 6.5 */ entity->asd.match.type = V4L2_ASYNC_MATCH_TYPE_FWNODE; #else entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; #endif entity->asd.match.fwnode = of_fwnode_handle(remote); +#endif list_add_tail(&entity->list, &chan->entities); chan->num_subdevs++; @@ -640,12 +642,14 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi) /* Add the remote entity of this endpoint */ entity->node = remote; +#if !defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */ #if defined(NV_V4L2_ASYNC_MATCH_TYPE_ENUM_PRESENT) /* Linux 6.5 */ entity->asd.match.type = V4L2_ASYNC_MATCH_TYPE_FWNODE; #else entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; #endif entity->asd.match.fwnode = of_fwnode_handle(remote); +#endif list_add_tail(&entity->list, &chan->entities); chan->num_subdevs++; chan->notifier.ops = chan->notifier.ops ? chan->notifier.ops : &vi_chan_notify_ops; @@ -671,23 +675,26 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi) list_for_each_entry(entity, &chan->entities, list) __v4l2_async_notifier_add_subdev(&chan->notifier, &entity->asd); #else -#if defined (NV_V4L2_ASYNC_SUBDEV_NF_INIT_PRESENT) /* Linux 6.5 */ - v4l2_async_subdev_nf_init(&chan->notifier, tegra_channel_find_linked_csi_subdev(chan)); - list_for_each_entry(entity, &chan->entities, list) { - struct v4l2_async_connection *asd; - asd = v4l2_async_nf_add_fwnode_remote(&chan->notifier, of_fwnode_handle(remote), - struct v4l2_async_connection); - if (IS_ERR(asd)) { - ret = PTR_ERR(asd); - goto done; - } - } +#if defined(NV_V4L2_ASYNC_NF_INIT_HAS_V4L2_DEV_ARG) /* Linux 6.6 */ + v4l2_async_nf_init(&chan->notifier, &vi->v4l2_dev); #else v4l2_async_nf_init(&chan->notifier); +#endif + +#if defined(NV_V4L2_ASYNC_NF_ADD_SUBDEV_PRESENT) /* Linux 6.6 */ list_for_each_entry(entity, &chan->entities, list) __v4l2_async_nf_add_subdev(&chan->notifier, &entity->asd); -#endif -#endif +#else + list_for_each_entry(entity, &chan->entities, list) { + struct v4l2_async_connection *asc; + asc = v4l2_async_nf_add_fwnode(&chan->notifier, of_fwnode_handle(entity->node), + struct v4l2_async_connection); + if (IS_ERR(asc)) + asc = NULL; + entity->asc = asc; + } +#endif /* NV_V4L2_ASYNC_NF_ADD_SUBDEV_PRESENT */ +#endif /* NV_V4L2_ASYNC_NOTIFIER_INIT_PRESENT */ chan->link_status = 0; chan->subdevs_bound = 0; @@ -697,8 +704,10 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi) ret = v4l2_async_notifier_register(&vi->v4l2_dev, &chan->notifier); #else -#if defined (NV_V4L2_ASYNC_SUBDEV_NF_INIT_PRESENT) /* Linux 6.5 */ +#if defined (NV_V4L2_ASYNC_NF_INIT_HAS_V4L2_DEV_ARG) /* Linux 6.6 */ ret = v4l2_async_nf_register(&chan->notifier); + if (ret < 0) + v4l2_async_nf_cleanup(&chan->notifier); #else ret = v4l2_async_nf_register(&vi->v4l2_dev, &chan->notifier); @@ -707,9 +716,9 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi) #else dev_err(vi->dev, "CONFIG_V4L2_ASYNC is not enabled!\n"); ret = -ENOTSUPP; -#endif +#endif /* CONFIG_V4L2_ASYNC */ if (ret < 0) { - dev_err(vi->dev, "notifier registration failed\n"); + dev_err(vi->dev, "notifier registration failed %d\n", ret); goto done; } diff --git a/include/media/mc_common.h b/include/media/mc_common.h index cab00b63..fcbac713 100644 --- a/include/media/mc_common.h +++ b/include/media/mc_common.h @@ -97,7 +97,7 @@ struct tegra_vi_graph_entity { struct media_entity *entity; #if defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */ - struct v4l2_async_connection asd; + struct v4l2_async_connection *asc; #else struct v4l2_async_subdev asd; #endif