hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/media/v4l2-core/v4l2-dev.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Video capture interface for Linux version 2
34 *
45 * A generic video device interface for the LINUX operating system
56 * using a set of device structures/vectors for low level operations.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
117 *
128 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
139 * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
....@@ -444,8 +440,22 @@
444440 struct video_device *vdev = video_devdata(filp);
445441 int ret = 0;
446442
447
- if (vdev->fops->release)
448
- ret = vdev->fops->release(filp);
443
+ /*
444
+ * We need to serialize the release() with queueing new requests.
445
+ * The release() may trigger the cancellation of a streaming
446
+ * operation, and that should not be mixed with queueing a new
447
+ * request at the same time.
448
+ */
449
+ if (vdev->fops->release) {
450
+ if (v4l2_device_supports_requests(vdev->v4l2_dev)) {
451
+ mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex);
452
+ ret = vdev->fops->release(filp);
453
+ mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex);
454
+ } else {
455
+ ret = vdev->fops->release(filp);
456
+ }
457
+ }
458
+
449459 if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP)
450460 dprintk("%s: release\n",
451461 video_device_node_name(vdev));
....@@ -523,15 +533,26 @@
523533 */
524534 static void determine_valid_ioctls(struct video_device *vdev)
525535 {
536
+ const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
537
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE |
538
+ V4L2_CAP_VIDEO_OUTPUT |
539
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE |
540
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
541
+ const u32 meta_caps = V4L2_CAP_META_CAPTURE |
542
+ V4L2_CAP_META_OUTPUT;
526543 DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
527544 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
528
- bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
545
+ bool is_vid = vdev->vfl_type == VFL_TYPE_VIDEO &&
546
+ (vdev->device_caps & vid_caps);
529547 bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
530548 bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
531549 bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
532550 bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
551
+ bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO &&
552
+ (vdev->device_caps & meta_caps);
533553 bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
534554 bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
555
+ bool is_io_mc = vdev->device_caps & V4L2_CAP_IO_MC;
535556
536557 bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
537558
....@@ -561,8 +582,10 @@
561582 set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
562583 if (vdev->ctrl_handler || ops->vidioc_querymenu)
563584 set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
564
- SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
565
- SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
585
+ if (!is_tch) {
586
+ SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
587
+ SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
588
+ }
566589 SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
567590 #ifdef CONFIG_VIDEO_ADV_DEBUG
568591 set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_INFO), valid_ioctls);
....@@ -576,42 +599,32 @@
576599 if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator)
577600 set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
578601
579
- if (is_vid || is_tch) {
580
- /* video and metadata specific ioctls */
602
+ if (is_vid) {
603
+ /* video specific ioctls */
581604 if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
582
- ops->vidioc_enum_fmt_vid_cap_mplane ||
583
- ops->vidioc_enum_fmt_vid_overlay ||
584
- ops->vidioc_enum_fmt_meta_cap)) ||
585
- (is_tx && (ops->vidioc_enum_fmt_vid_out ||
586
- ops->vidioc_enum_fmt_vid_out_mplane ||
587
- ops->vidioc_enum_fmt_meta_out)))
605
+ ops->vidioc_enum_fmt_vid_overlay)) ||
606
+ (is_tx && ops->vidioc_enum_fmt_vid_out))
588607 set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
589608 if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
590609 ops->vidioc_g_fmt_vid_cap_mplane ||
591
- ops->vidioc_g_fmt_vid_overlay ||
592
- ops->vidioc_g_fmt_meta_cap)) ||
610
+ ops->vidioc_g_fmt_vid_overlay)) ||
593611 (is_tx && (ops->vidioc_g_fmt_vid_out ||
594612 ops->vidioc_g_fmt_vid_out_mplane ||
595
- ops->vidioc_g_fmt_vid_out_overlay ||
596
- ops->vidioc_g_fmt_meta_out)))
613
+ ops->vidioc_g_fmt_vid_out_overlay)))
597614 set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
598615 if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
599616 ops->vidioc_s_fmt_vid_cap_mplane ||
600
- ops->vidioc_s_fmt_vid_overlay ||
601
- ops->vidioc_s_fmt_meta_cap)) ||
617
+ ops->vidioc_s_fmt_vid_overlay)) ||
602618 (is_tx && (ops->vidioc_s_fmt_vid_out ||
603619 ops->vidioc_s_fmt_vid_out_mplane ||
604
- ops->vidioc_s_fmt_vid_out_overlay ||
605
- ops->vidioc_s_fmt_meta_out)))
620
+ ops->vidioc_s_fmt_vid_out_overlay)))
606621 set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
607622 if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
608623 ops->vidioc_try_fmt_vid_cap_mplane ||
609
- ops->vidioc_try_fmt_vid_overlay ||
610
- ops->vidioc_try_fmt_meta_cap)) ||
624
+ ops->vidioc_try_fmt_vid_overlay)) ||
611625 (is_tx && (ops->vidioc_try_fmt_vid_out ||
612626 ops->vidioc_try_fmt_vid_out_mplane ||
613
- ops->vidioc_try_fmt_vid_out_overlay ||
614
- ops->vidioc_try_fmt_meta_out)))
627
+ ops->vidioc_try_fmt_vid_out_overlay)))
615628 set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
616629 SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
617630 SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
....@@ -625,15 +638,29 @@
625638 SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd);
626639 SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
627640 SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
628
- if (ops->vidioc_g_crop || ops->vidioc_g_selection)
641
+ if (ops->vidioc_g_selection) {
629642 set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls);
630
- if (ops->vidioc_s_crop || ops->vidioc_s_selection)
643
+ set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
644
+ }
645
+ if (ops->vidioc_s_selection)
631646 set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
632647 SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
633648 SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
634
- if (ops->vidioc_cropcap || ops->vidioc_g_selection)
635
- set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
636
- } else if (is_vbi) {
649
+ }
650
+ if (is_meta && is_rx) {
651
+ /* metadata capture specific ioctls */
652
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_cap);
653
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_cap);
654
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_cap);
655
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_cap);
656
+ } else if (is_meta && is_tx) {
657
+ /* metadata output specific ioctls */
658
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_out);
659
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_out);
660
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out);
661
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out);
662
+ }
663
+ if (is_vbi) {
637664 /* vbi specific ioctls */
638665 if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||
639666 ops->vidioc_g_fmt_sliced_vbi_cap)) ||
....@@ -651,30 +678,35 @@
651678 ops->vidioc_try_fmt_sliced_vbi_out)))
652679 set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
653680 SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
681
+ } else if (is_tch) {
682
+ /* touch specific ioctls */
683
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_vid_cap);
684
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_vid_cap);
685
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_vid_cap);
686
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_vid_cap);
687
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
688
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
689
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
690
+ SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
691
+ SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
692
+ SET_VALID_IOCTL(ops, VIDIOC_G_PARM, vidioc_g_parm);
693
+ SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
654694 } else if (is_sdr && is_rx) {
655695 /* SDR receiver specific ioctls */
656
- if (ops->vidioc_enum_fmt_sdr_cap)
657
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
658
- if (ops->vidioc_g_fmt_sdr_cap)
659
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
660
- if (ops->vidioc_s_fmt_sdr_cap)
661
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
662
- if (ops->vidioc_try_fmt_sdr_cap)
663
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
696
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_cap);
697
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_cap);
698
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_cap);
699
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_cap);
664700 } else if (is_sdr && is_tx) {
665701 /* SDR transmitter specific ioctls */
666
- if (ops->vidioc_enum_fmt_sdr_out)
667
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
668
- if (ops->vidioc_g_fmt_sdr_out)
669
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
670
- if (ops->vidioc_s_fmt_sdr_out)
671
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
672
- if (ops->vidioc_try_fmt_sdr_out)
673
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
702
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_out);
703
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_out);
704
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_out);
705
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_out);
674706 }
675707
676
- if (is_vid || is_vbi || is_sdr || is_tch) {
677
- /* ioctls valid for video, metadata, vbi or sdr */
708
+ if (is_vid || is_vbi || is_sdr || is_tch || is_meta) {
709
+ /* ioctls valid for video, vbi, sdr, touch and metadata */
678710 SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
679711 SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
680712 SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
....@@ -686,17 +718,23 @@
686718 SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
687719 }
688720
689
- if (is_vid || is_vbi || is_tch) {
690
- /* ioctls valid for video or vbi */
721
+ if (is_vid || is_vbi || is_meta) {
722
+ /* ioctls valid for video, vbi and metadata */
691723 if (ops->vidioc_s_std)
692724 set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
693725 SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
694726 SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
695727 if (is_rx) {
696728 SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
697
- SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
698
- SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
699
- SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
729
+ if (is_io_mc) {
730
+ set_bit(_IOC_NR(VIDIOC_ENUMINPUT), valid_ioctls);
731
+ set_bit(_IOC_NR(VIDIOC_G_INPUT), valid_ioctls);
732
+ set_bit(_IOC_NR(VIDIOC_S_INPUT), valid_ioctls);
733
+ } else {
734
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
735
+ SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
736
+ SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
737
+ }
700738 SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
701739 SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
702740 SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
....@@ -704,15 +742,20 @@
704742 SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid);
705743 }
706744 if (is_tx) {
707
- SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
708
- SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
709
- SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
745
+ if (is_io_mc) {
746
+ set_bit(_IOC_NR(VIDIOC_ENUMOUTPUT), valid_ioctls);
747
+ set_bit(_IOC_NR(VIDIOC_G_OUTPUT), valid_ioctls);
748
+ set_bit(_IOC_NR(VIDIOC_S_OUTPUT), valid_ioctls);
749
+ } else {
750
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
751
+ SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
752
+ SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
753
+ }
710754 SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
711755 SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
712756 SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
713757 }
714
- if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
715
- ops->vidioc_g_std))
758
+ if (ops->vidioc_g_parm || ops->vidioc_g_std)
716759 set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
717760 SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
718761 SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
....@@ -726,7 +769,7 @@
726769 SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
727770 SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
728771 }
729
- if (is_rx) {
772
+ if (is_rx && !is_tch) {
730773 /* receiver only ioctls */
731774 SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
732775 SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
....@@ -753,7 +796,7 @@
753796 vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
754797
755798 switch (vdev->vfl_type) {
756
- case VFL_TYPE_GRABBER:
799
+ case VFL_TYPE_VIDEO:
757800 intf_type = MEDIA_INTF_T_V4L_VIDEO;
758801 vdev->entity.function = MEDIA_ENT_F_IO_V4L;
759802 break;
....@@ -851,6 +894,9 @@
851894 /* the v4l2_dev pointer MUST be present */
852895 if (WARN_ON(!vdev->v4l2_dev))
853896 return -EINVAL;
897
+ /* the device_caps field MUST be set for all but subdevs */
898
+ if (WARN_ON(type != VFL_TYPE_SUBDEV && !vdev->device_caps))
899
+ return -EINVAL;
854900
855901 /* v4l2_fh support */
856902 spin_lock_init(&vdev->fh_lock);
....@@ -858,7 +904,7 @@
858904
859905 /* Part 1: check device type */
860906 switch (type) {
861
- case VFL_TYPE_GRABBER:
907
+ case VFL_TYPE_VIDEO:
862908 name_base = "video";
863909 break;
864910 case VFL_TYPE_VBI:
....@@ -902,7 +948,7 @@
902948 * of 128-191 and just pick the first free minor there
903949 * (new style). */
904950 switch (type) {
905
- case VFL_TYPE_GRABBER:
951
+ case VFL_TYPE_VIDEO:
906952 minor_offset = 0;
907953 minor_cnt = 64;
908954 break;
....@@ -1078,10 +1124,14 @@
10781124 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
10791125 }
10801126
1127
+#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
1128
+arch_initcall_sync(videodev_init);
1129
+#else
10811130 subsys_initcall(videodev_init);
1131
+#endif
10821132 module_exit(videodev_exit)
10831133
1084
-MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>");
1085
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1134
+MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>, Bill Dirks, Justin Schoeman, Gerd Knorr");
1135
+MODULE_DESCRIPTION("Video4Linux2 core driver");
10861136 MODULE_LICENSE("GPL");
10871137 MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);