aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 18:04:33 +0100
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 23:42:32 +0100
commitf07e572f6447465d8938679533d604e402b0f066 (patch)
treecb333bd2a67e59e7c07659514850a0fd55fc825e /target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
parent5d3a6fd970619dfc55f8259035c3027d7613a2a6 (diff)
downloadupstream-f07e572f6447465d8938679533d604e402b0f066.tar.gz
upstream-f07e572f6447465d8938679533d604e402b0f066.tar.bz2
upstream-f07e572f6447465d8938679533d604e402b0f066.zip
bcm27xx: import latest patches from the RPi foundation
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch206
1 files changed, 206 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
new file mode 100644
index 0000000000..47f2551ec7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch
@@ -0,0 +1,206 @@
+From 90712c1a495c2aa4b10dd8127fdd7f1a0cd9ef00 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo@jmondi.org>
+Date: Tue, 7 Apr 2020 17:21:57 +0200
+Subject: [PATCH] media: v4l2-dev: Add
+ v4l2_device_register_ro_subdev_node()
+
+Add to the V4L2 core a function to register device nodes for video
+subdevices in read-only mode.
+
+Registering a device node in read-only mode is useful to expose to
+userspace the current sub-device configuration, without allowing
+application to change it by using the V4L2 subdevice ioctls.
+
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
+---
+ drivers/media/v4l2-core/v4l2-device.c | 7 ++--
+ drivers/media/v4l2-core/v4l2-subdev.c | 19 ++++++++++
+ include/media/v4l2-dev.h | 7 ++++
+ include/media/v4l2-device.h | 50 ++++++++++++++++++++++++---
+ 4 files changed, 77 insertions(+), 6 deletions(-)
+
+--- a/drivers/media/v4l2-core/v4l2-device.c
++++ b/drivers/media/v4l2-core/v4l2-device.c
+@@ -189,7 +189,8 @@ static void v4l2_device_release_subdev_n
+ kfree(vdev);
+ }
+
+-int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
++int __v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev,
++ bool read_only)
+ {
+ struct video_device *vdev;
+ struct v4l2_subdev *sd;
+@@ -218,6 +219,8 @@ int v4l2_device_register_subdev_nodes(st
+ vdev->fops = &v4l2_subdev_fops;
+ vdev->release = v4l2_device_release_subdev_node;
+ vdev->ctrl_handler = sd->ctrl_handler;
++ if (read_only)
++ set_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);
+ err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
+ sd->owner);
+ if (err < 0) {
+@@ -255,7 +258,7 @@ clean_up:
+
+ return err;
+ }
+-EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
++EXPORT_SYMBOL_GPL(__v4l2_device_register_subdev_nodes);
+
+ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
+ {
+--- a/drivers/media/v4l2-core/v4l2-subdev.c
++++ b/drivers/media/v4l2-core/v4l2-subdev.c
+@@ -331,6 +331,7 @@ static long subdev_do_ioctl(struct file
+ struct v4l2_fh *vfh = file->private_data;
+ #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+ struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
++ bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);
+ int rval;
+ #endif
+
+@@ -453,6 +454,9 @@ static long subdev_do_ioctl(struct file
+ case VIDIOC_SUBDEV_S_FMT: {
+ struct v4l2_subdev_format *format = arg;
+
++ if (format->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
++ return -EPERM;
++
+ memset(format->reserved, 0, sizeof(format->reserved));
+ memset(format->format.reserved, 0, sizeof(format->format.reserved));
+ return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format);
+@@ -480,6 +484,9 @@ static long subdev_do_ioctl(struct file
+ struct v4l2_subdev_crop *crop = arg;
+ struct v4l2_subdev_selection sel;
+
++ if (crop->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
++ return -EPERM;
++
+ memset(crop->reserved, 0, sizeof(crop->reserved));
+ memset(&sel, 0, sizeof(sel));
+ sel.which = crop->which;
+@@ -521,6 +528,9 @@ static long subdev_do_ioctl(struct file
+ case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
+ struct v4l2_subdev_frame_interval *fi = arg;
+
++ if (ro_subdev)
++ return -EPERM;
++
+ memset(fi->reserved, 0, sizeof(fi->reserved));
+ return v4l2_subdev_call(sd, video, s_frame_interval, arg);
+ }
+@@ -544,6 +554,9 @@ static long subdev_do_ioctl(struct file
+ case VIDIOC_SUBDEV_S_SELECTION: {
+ struct v4l2_subdev_selection *sel = arg;
+
++ if (sel->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
++ return -EPERM;
++
+ memset(sel->reserved, 0, sizeof(sel->reserved));
+ return v4l2_subdev_call(
+ sd, pad, set_selection, subdev_fh->pad, sel);
+@@ -580,6 +593,9 @@ static long subdev_do_ioctl(struct file
+ return v4l2_subdev_call(sd, video, g_dv_timings, arg);
+
+ case VIDIOC_SUBDEV_S_DV_TIMINGS:
++ if (ro_subdev)
++ return -EPERM;
++
+ return v4l2_subdev_call(sd, video, s_dv_timings, arg);
+
+ case VIDIOC_SUBDEV_G_STD:
+@@ -588,6 +604,9 @@ static long subdev_do_ioctl(struct file
+ case VIDIOC_SUBDEV_S_STD: {
+ v4l2_std_id *std = arg;
+
++ if (ro_subdev)
++ return -EPERM;
++
+ return v4l2_subdev_call(sd, video, s_std, *std);
+ }
+
+--- a/include/media/v4l2-dev.h
++++ b/include/media/v4l2-dev.h
+@@ -82,11 +82,18 @@ struct v4l2_ctrl_handler;
+ * but the old crop API will still work as expected in order to preserve
+ * backwards compatibility.
+ * Never set this flag for new drivers.
++ * @V4L2_FL_SUBDEV_RO_DEVNODE:
++ * indicates that the video device node is registered in read-only mode.
++ * The flag only applies to device nodes registered for sub-devices, it is
++ * set by the core when the sub-devices device nodes are registered with
++ * v4l2_device_register_ro_subdev_nodes() and used by the sub-device ioctl
++ * handler to restrict access to some ioctl calls.
+ */
+ enum v4l2_video_device_flags {
+ V4L2_FL_REGISTERED = 0,
+ V4L2_FL_USES_V4L2_FH = 1,
+ V4L2_FL_QUIRK_INVERTED_CROP = 2,
++ V4L2_FL_SUBDEV_RO_DEVNODE = 3,
+ };
+
+ /* Priority helper functions */
+--- a/include/media/v4l2-device.h
++++ b/include/media/v4l2-device.h
+@@ -174,14 +174,56 @@ int __must_check v4l2_device_register_su
+ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
+
+ /**
+- * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs
+- * of the v4l2 device that are marked with
+- * the %V4L2_SUBDEV_FL_HAS_DEVNODE flag.
++ * __v4l2_device_register_ro_subdev_nodes - Registers device nodes for
++ * all subdevs of the v4l2 device that are marked with the
++ * %V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
++ * @read_only: subdevices read-only flag. True to register the subdevices
++ * device nodes in read-only mode, false to allow full access to the
++ * subdevice userspace API.
+ */
+ int __must_check
+-v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
++__v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev,
++ bool read_only);
++
++/**
++ * v4l2_device_register_subdev_nodes - Registers subdevices device nodes with
++ * unrestricted access to the subdevice userspace operations
++ *
++ * Internally calls __v4l2_device_register_subdev_nodes(). See its documentation
++ * for more details.
++ *
++ * @v4l2_dev: pointer to struct v4l2_device
++ */
++static inline int __must_check
++v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
++{
++#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
++ return __v4l2_device_register_subdev_nodes(v4l2_dev, false);
++#else
++ return 0;
++#endif
++}
++
++/**
++ * v4l2_device_register_ro_subdev_nodes - Registers subdevices device nodes
++ * in read-only mode
++ *
++ * Internally calls __v4l2_device_register_subdev_nodes(). See its documentation
++ * for more details.
++ *
++ * @v4l2_dev: pointer to struct v4l2_device
++ */
++static inline int __must_check
++v4l2_device_register_ro_subdev_nodes(struct v4l2_device *v4l2_dev)
++{
++#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
++ return __v4l2_device_register_subdev_nodes(v4l2_dev, true);
++#else
++ return 0;
++#endif
++}
+
+ /**
+ * v4l2_subdev_notify - Sends a notification to v4l2_device.