media: camera: Fix v4l2-subdev for Linux v6.10

In Linux v6.10, the v4l2-subdev callbacks 'g_dv_timings' and
's_dv_timings' were moved from the v4l2_subdev_video_ops structure to
the v4l2_subdev_pad_ops structure. Fix the build for Linux v6.10 by
using conftest to determine which structure is used for these callbacks.

Bug 4593750

Change-Id: Ic54e88da22ed7d1da9b6026a45b9c4307637c7b4
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3142215
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Jon Hunter
2024-04-12 16:42:09 +01:00
committed by mobile promotions
parent 1a635bb0ea
commit 6255ffef44
3 changed files with 58 additions and 1 deletions

View File

@@ -25,6 +25,7 @@
#include <media/v4l2-dev.h> #include <media/v4l2-dev.h>
#include <media/v4l2-fh.h> #include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-core.h> #include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h> #include <media/videobuf2-dma-contig.h>
#include <media/tegra-v4l2-camera.h> #include <media/tegra-v4l2-camera.h>
@@ -1159,11 +1160,19 @@ tegra_channel_g_dv_timings(struct file *file, void *fh,
{ {
struct tegra_channel *chan = video_drvdata(file); struct tegra_channel *chan = video_drvdata(file);
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, g_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, g_dv_timings, 0, timings);
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, g_dv_timings)) if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, g_dv_timings))
return -ENOTTY; return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev, return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, g_dv_timings, timings); chan->grp_id, video, g_dv_timings, timings);
#endif
} }
static int static int
@@ -1175,7 +1184,11 @@ tegra_channel_s_dv_timings(struct file *file, void *fh,
struct v4l2_dv_timings curr_timings; struct v4l2_dv_timings curr_timings;
int ret; int ret;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, s_dv_timings))
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, s_dv_timings)) if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, s_dv_timings))
#endif
return -ENOTTY; return -ENOTTY;
ret = tegra_channel_g_dv_timings(file, fh, &curr_timings); ret = tegra_channel_g_dv_timings(file, fh, &curr_timings);
@@ -1188,9 +1201,13 @@ tegra_channel_s_dv_timings(struct file *file, void *fh,
if (vb2_is_busy(&chan->queue)) if (vb2_is_busy(&chan->queue))
return -EBUSY; return -EBUSY;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
ret = v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, s_dv_timings, 0, timings);
#else
ret = v4l2_device_call_until_err(chan->video->v4l2_dev, ret = v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, s_dv_timings, timings); chan->grp_id, video, s_dv_timings, timings);
#endif
if (!ret) if (!ret)
tegra_channel_update_format(chan, bt->width, bt->height, tegra_channel_update_format(chan, bt->width, bt->height,
chan->fmtinfo->fourcc, &chan->fmtinfo->bpp, chan->fmtinfo->fourcc, &chan->fmtinfo->bpp,
@@ -1208,11 +1225,19 @@ tegra_channel_query_dv_timings(struct file *file, void *fh,
{ {
struct tegra_channel *chan = video_drvdata(file); struct tegra_channel *chan = video_drvdata(file);
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, query_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, query_dv_timings, 0, timings);
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, query_dv_timings)) if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, query_dv_timings))
return -ENOTTY; return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev, return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, query_dv_timings, timings); chan->grp_id, video, query_dv_timings, timings);
#endif
} }
static int static int
@@ -1849,8 +1874,13 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
if (chan->pg_mode) { if (chan->pg_mode) {
/* TPG mode */ /* TPG mode */
cdev->sensor_type = SENSORTYPE_VIRTUAL; cdev->sensor_type = SENSORTYPE_VIRTUAL;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
} else if (v4l2_subdev_has_op(chan->subdev_on_csi,
pad, g_dv_timings)) {
#else
} else if (v4l2_subdev_has_op(chan->subdev_on_csi, } else if (v4l2_subdev_has_op(chan->subdev_on_csi,
video, g_dv_timings)) { video, g_dv_timings)) {
#endif
/* HDMI-IN */ /* HDMI-IN */
cdev->sensor_type = SENSORTYPE_OTHER; cdev->sensor_type = SENSORTYPE_OTHER;
pixelclock = tegra_channel_get_max_source_rate(); pixelclock = tegra_channel_get_max_source_rate();
@@ -2180,7 +2210,11 @@ tegra_channel_enum_input(struct file *file, void *fh, struct v4l2_input *inp)
return -ENODEV; return -ENODEV;
inp->type = V4L2_INPUT_TYPE_CAMERA; inp->type = V4L2_INPUT_TYPE_CAMERA;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (v4l2_subdev_has_op(sd_on_csi, pad, s_dv_timings)) {
#else
if (v4l2_subdev_has_op(sd_on_csi, video, s_dv_timings)) { if (v4l2_subdev_has_op(sd_on_csi, video, s_dv_timings)) {
#endif
inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
len = snprintf(inp->name, len = snprintf(inp->name,
sizeof(inp->name), "HDMI %u", sizeof(inp->name), "HDMI %u",

View File

@@ -180,6 +180,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_notifier_init
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_nf_init_has_v4l2_dev_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_nf_init_has_v4l2_dev_arg
NV_CONFTEST_FUNCTION_COMPILE_TESTS += __v4l2_async_nf_add_subdev NV_CONFTEST_FUNCTION_COMPILE_TESTS += __v4l2_async_nf_add_subdev
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_get_frame_interval NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_get_frame_interval
NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_dv_timings
NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_area_struct_has_const_vm_flags NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_fd_to_handle NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_fd_to_handle
NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_handle_to_fd NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_handle_to_fd

View File

@@ -8014,6 +8014,28 @@ compile_test() {
"NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL" "" "types" "NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL" "" "types"
;; ;;
v4l2_subdev_pad_ops_struct_has_dv_timings)
#
# Determine if struct v4l2_subdev_pad_ops has the 'g_dv_timings'
# and 's_dv_timings' function pointers.
#
# Commit 009e12561369 ("media: v4l2-subdev: Add pad versions of dv
# timing subdev calls)" added 'g_dv_timings' and 's_dv_timnigs' to
# the v4l2_subdev_pad_ops structure. Commit d8c9a6e204f1 ("media:
# v4l2-subdev: Remove non-pad dv timing callbacks") then removed the
# the original 'g_dv_timings' and 's_dv_timings' from the
# v4l2_subdev_video_ops structure. These changes were made for Linux
# v6.10.
CODE="
#define _LINUX_EFI_H
#include <media/v4l2-subdev.h>
int conftest_v4l2_subdev_pad_ops_struct_has_dv_timings(void) {
return offsetof(struct v4l2_subdev_pad_ops, g_dv_timings);
}
"
compile_check_conftest "$CODE" \
"NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS" "" "types"
;;
crypto_engine_ctx_struct_removed_test) crypto_engine_ctx_struct_removed_test)
# #
# Determine if struct 'crypto_engine_ctx' is removed in linux kernel. # Determine if struct 'crypto_engine_ctx' is removed in linux kernel.