Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: Drop V4L2_FL_USES_V4L2_FH checks

Now that all drivers use v4l2_fh, we can drop the V4L2_FL_USES_V4L2_FH
checks through the V4L2 core.

To ensure that all new drivers use v4l2_fh, keep setting the
V4L2_FL_USES_V4L2_FH flag in v4l2_fh_init(), and verify it is set after
the .open() file operation returns.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Laurent Pinchart and committed by
Hans Verkuil
bb4d6be2 b3d945ba

+43 -72
+2 -13
Documentation/driver-api/media/v4l2-fh.rst
··· 3 3 V4L2 File handles 4 4 ----------------- 5 5 6 - struct v4l2_fh provides a way to easily keep file handle specific 7 - data that is used by the V4L2 framework. 8 - 9 - .. attention:: 10 - New drivers must use struct v4l2_fh 11 - since it is also used to implement priority handling 12 - (:ref:`VIDIOC_G_PRIORITY`). 6 + struct v4l2_fh provides a way to easily keep file handle specific data that is 7 + used by the V4L2 framework. Its usage is mandatory in all drivers. 13 8 14 9 struct v4l2_fh is allocated in the driver's ``open()`` file operation handler. 15 10 It is typically embedded in a larger driver-specific structure. The ··· 128 133 (struct file \*filp) 129 134 130 135 - Same, but it calls v4l2_fh_is_singular with filp->private_data. 131 - 132 - .. note:: 133 - The V4L2 framework knows whether a driver uses :c:type:`v4l2_fh` as its 134 - ``file->private_data`` pointer by testing the ``V4L2_FL_USES_V4L2_FH`` 135 - bit in :c:type:`video_device`->flags. This bit is set whenever 136 - :c:func:`v4l2_fh_init` is called. 137 136 138 137 139 138 V4L2 fh functions and data structures
-5
Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
··· 775 775 如果 video_device 标志,新驱动 776 776 必须使用 v4l2_fh 结构体,因为它也用于实现优先级处理(VIDIOC_G/S_PRIORITY)。 777 777 778 - v4l2_fh 的用户(位于 V4l2 框架中,并非驱动)可通过测试 779 - video_device->flags 中的 V4L2_FL_USES_V4L2_FH 位得知驱动是否使用 780 - v4l2_fh 作为他的 file->private_data 指针。这个位会在调用 v4l2_fh_init() 781 - 时被设置。 782 - 783 778 v4l2_fh 结构体作为驱动自身文件句柄结构体的一部分被分配,且驱动在 784 779 其打开函数中将 file->private_data 指向它。 785 780
+4 -8
drivers/media/common/videobuf2/videobuf2-v4l2.c
··· 973 973 974 974 __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) 975 975 { 976 - struct video_device *vfd = video_devdata(file); 976 + struct v4l2_fh *fh = file_to_v4l2_fh(file); 977 977 __poll_t res; 978 978 979 979 res = vb2_core_poll(q, file, wait); 980 980 981 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { 982 - struct v4l2_fh *fh = file_to_v4l2_fh(file); 983 - 984 - poll_wait(file, &fh->wait, wait); 985 - if (v4l2_event_pending(fh)) 986 - res |= EPOLLPRI; 987 - } 981 + poll_wait(file, &fh->wait, wait); 982 + if (v4l2_event_pending(fh)) 983 + res |= EPOLLPRI; 988 984 989 985 return res; 990 986 }
+2 -5
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
··· 672 672 static inline bool ctrl_is_pointer(struct file *file, u32 id) 673 673 { 674 674 struct video_device *vdev = video_devdata(file); 675 - struct v4l2_fh *fh = NULL; 675 + struct v4l2_fh *fh = file_to_v4l2_fh(file); 676 676 struct v4l2_ctrl_handler *hdl = NULL; 677 677 struct v4l2_query_ext_ctrl qec = { id }; 678 678 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; 679 679 680 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) 681 - fh = file_to_v4l2_fh(file); 682 - 683 - if (fh && fh->ctrl_handler) 680 + if (fh->ctrl_handler) 684 681 hdl = fh->ctrl_handler; 685 682 else if (vdev->ctrl_handler) 686 683 hdl = vdev->ctrl_handler;
+1 -1
drivers/media/v4l2-core/v4l2-ctrls-api.c
··· 1254 1254 { 1255 1255 struct video_device *vfd = video_devdata(file); 1256 1256 1257 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) { 1257 + if (vfd->v4l2_dev) { 1258 1258 struct v4l2_fh *vfh = file_to_v4l2_fh(file); 1259 1259 1260 1260 v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
+16 -5
drivers/media/v4l2-core/v4l2-dev.c
··· 425 425 video_get(vdev); 426 426 mutex_unlock(&videodev_lock); 427 427 428 - if (video_is_registered(vdev)) 429 - ret = vdev->fops->open(filp); 430 - else 428 + if (!video_is_registered(vdev)) { 431 429 ret = -ENODEV; 430 + goto done; 431 + } 432 432 433 + ret = vdev->fops->open(filp); 434 + if (ret) 435 + goto done; 436 + 437 + /* All drivers must use v4l2_fh. */ 438 + if (WARN_ON(!test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))) { 439 + vdev->fops->release(filp); 440 + ret = -ENODEV; 441 + } 442 + 443 + done: 433 444 if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP) 434 445 dprintk("%s: open (%d)\n", 435 446 video_device_node_name(vdev), ret); 447 + 436 448 /* decrease the refcount in case of an error */ 437 449 if (ret) 438 450 video_put(vdev); ··· 1126 1114 */ 1127 1115 clear_bit(V4L2_FL_REGISTERED, &vdev->flags); 1128 1116 mutex_unlock(&videodev_lock); 1129 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) 1130 - v4l2_event_wake_all(vdev); 1117 + v4l2_event_wake_all(vdev); 1131 1118 device_unregister(&vdev->dev); 1132 1119 } 1133 1120 EXPORT_SYMBOL(video_unregister_device);
+12 -25
drivers/media/v4l2-core/v4l2-ioctl.c
··· 1195 1195 u32 *p = arg; 1196 1196 1197 1197 vfd = video_devdata(file); 1198 - if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 1199 - return -ENOTTY; 1200 1198 vfh = file_to_v4l2_fh(file); 1201 1199 return v4l2_prio_change(vfd->prio, &vfh->prio, *p); 1202 1200 } ··· 2295 2297 struct video_device *vfd = video_devdata(file); 2296 2298 struct v4l2_query_ext_ctrl qec = {}; 2297 2299 struct v4l2_queryctrl *p = arg; 2298 - struct v4l2_fh *vfh = 2299 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2300 + struct v4l2_fh *vfh = fh; 2300 2301 int ret; 2301 2302 2302 2303 if (vfh && vfh->ctrl_handler) ··· 2319 2322 { 2320 2323 struct video_device *vfd = video_devdata(file); 2321 2324 struct v4l2_query_ext_ctrl *p = arg; 2322 - struct v4l2_fh *vfh = 2323 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2325 + struct v4l2_fh *vfh = fh; 2324 2326 2325 2327 if (vfh && vfh->ctrl_handler) 2326 2328 return v4l2_query_ext_ctrl(vfh->ctrl_handler, p); ··· 2335 2339 { 2336 2340 struct video_device *vfd = video_devdata(file); 2337 2341 struct v4l2_querymenu *p = arg; 2338 - struct v4l2_fh *vfh = 2339 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2342 + struct v4l2_fh *vfh = fh; 2340 2343 2341 2344 if (vfh && vfh->ctrl_handler) 2342 2345 return v4l2_querymenu(vfh->ctrl_handler, p); ··· 2351 2356 { 2352 2357 struct video_device *vfd = video_devdata(file); 2353 2358 struct v4l2_control *p = arg; 2354 - struct v4l2_fh *vfh = 2355 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2359 + struct v4l2_fh *vfh = fh; 2356 2360 struct v4l2_ext_controls ctrls; 2357 2361 struct v4l2_ext_control ctrl; 2358 2362 ··· 2382 2388 { 2383 2389 struct video_device *vfd = video_devdata(file); 2384 2390 struct v4l2_control *p = arg; 2385 - struct v4l2_fh *vfh = 2386 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2391 + struct v4l2_fh *vfh = fh; 2387 2392 struct v4l2_ext_controls ctrls; 2388 2393 struct v4l2_ext_control ctrl; 2389 2394 int ret; ··· 2411 2418 { 2412 2419 struct video_device *vfd = video_devdata(file); 2413 2420 struct v4l2_ext_controls *p = arg; 2414 - struct v4l2_fh *vfh = 2415 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2421 + struct v4l2_fh *vfh = fh; 2416 2422 2417 2423 p->error_idx = p->count; 2418 2424 if (vfh && vfh->ctrl_handler) ··· 2431 2439 { 2432 2440 struct video_device *vfd = video_devdata(file); 2433 2441 struct v4l2_ext_controls *p = arg; 2434 - struct v4l2_fh *vfh = 2435 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2442 + struct v4l2_fh *vfh = fh; 2436 2443 2437 2444 p->error_idx = p->count; 2438 2445 if (vfh && vfh->ctrl_handler) ··· 2451 2460 { 2452 2461 struct video_device *vfd = video_devdata(file); 2453 2462 struct v4l2_ext_controls *p = arg; 2454 - struct v4l2_fh *vfh = 2455 - test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; 2463 + struct v4l2_fh *vfh = fh; 2456 2464 2457 2465 p->error_idx = p->count; 2458 2466 if (vfh && vfh->ctrl_handler) ··· 3063 3073 struct v4l2_ioctl_info default_info; 3064 3074 const struct v4l2_ioctl_info *info; 3065 3075 void *fh = file->private_data; 3066 - struct v4l2_fh *vfh = NULL; 3076 + struct v4l2_fh *vfh = file_to_v4l2_fh(file); 3067 3077 int dev_debug = vfd->dev_debug; 3068 3078 long ret = -ENOTTY; 3069 3079 ··· 3072 3082 video_device_node_name(vfd)); 3073 3083 return ret; 3074 3084 } 3075 - 3076 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) 3077 - vfh = file_to_v4l2_fh(file); 3078 3085 3079 3086 /* 3080 3087 * We need to serialize streamon/off with queueing new requests. ··· 3104 3117 info = &v4l2_ioctls[_IOC_NR(cmd)]; 3105 3118 3106 3119 if (!is_valid_ioctl(vfd, cmd) && 3107 - !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) 3120 + !((info->flags & INFO_FL_CTRL) && vfh->ctrl_handler)) 3108 3121 goto done; 3109 3122 3110 - if (vfh && (info->flags & INFO_FL_PRIO)) { 3123 + if (info->flags & INFO_FL_PRIO) { 3111 3124 ret = v4l2_prio_check(vfd->prio, vfh->prio); 3112 3125 if (ret) 3113 3126 goto done; ··· 3126 3139 ret = -ENOTTY; 3127 3140 } else { 3128 3141 ret = ops->vidioc_default(file, fh, 3129 - vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, 3142 + v4l2_prio_check(vfd->prio, vfh->prio) >= 0, 3130 3143 cmd, arg); 3131 3144 } 3132 3145
+4 -8
drivers/media/v4l2-core/v4l2-mem2mem.c
··· 951 951 __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 952 952 struct poll_table_struct *wait) 953 953 { 954 - struct video_device *vfd = video_devdata(file); 954 + struct v4l2_fh *fh = file_to_v4l2_fh(file); 955 955 struct vb2_queue *src_q = v4l2_m2m_get_src_vq(m2m_ctx); 956 956 struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); 957 957 __poll_t req_events = poll_requested_events(wait); ··· 970 970 if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM)) 971 971 rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait); 972 972 973 - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { 974 - struct v4l2_fh *fh = file_to_v4l2_fh(file); 975 - 976 - poll_wait(file, &fh->wait, wait); 977 - if (v4l2_event_pending(fh)) 978 - rc |= EPOLLPRI; 979 - } 973 + poll_wait(file, &fh->wait, wait); 974 + if (v4l2_event_pending(fh)) 975 + rc |= EPOLLPRI; 980 976 981 977 return rc; 982 978 }
+1 -1
include/media/v4l2-dev.h
··· 74 74 * @V4L2_FL_USES_V4L2_FH: 75 75 * indicates that file->private_data points to &struct v4l2_fh. 76 76 * This flag is set by the core when v4l2_fh_init() is called. 77 - * All new drivers should use it. 77 + * All drivers must use it. 78 78 * @V4L2_FL_QUIRK_INVERTED_CROP: 79 79 * some old M2M drivers use g/s_crop/cropcap incorrectly: crop and 80 80 * compose are swapped. If this flag is set, then the selection
+1 -1
include/media/v4l2-fh.h
··· 3 3 * v4l2-fh.h 4 4 * 5 5 * V4L2 file handle. Store per file handle data for the V4L2 6 - * framework. Using file handles is optional for the drivers. 6 + * framework. Using file handles is mandatory for the drivers. 7 7 * 8 8 * Copyright (C) 2009--2010 Nokia Corporation. 9 9 *