[PATCH 2/6] v4l: subdev: Provide a locking scheme for subdev operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The V4L2 sub-device's operations are called both from other drivers as
well as through the IOCTL uAPI. Previously the sub-device drivers were
responsible for managing their own serialisation. This patch adds an
optional mutex the drivers may set, and it will be used to serialise
access to driver's data related to a device across the driver's ops.

Access to the driver's controls through the control framework works as
usual, i.e. using a different mutex.

Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
---
 include/media/v4l2-subdev.h | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 71f1f2f0da53..dc6e11019df6 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -9,6 +9,7 @@
 #define _V4L2_SUBDEV_H
 
 #include <linux/types.h>
+#include <linux/mutex.h>
 #include <linux/v4l2-subdev.h>
 #include <media/media-entity.h>
 #include <media/v4l2-async.h>
@@ -828,6 +829,7 @@ struct v4l2_subdev_platform_data {
  * @host_priv: pointer to private data used by the device where the subdev
  *	is attached.
  * @devnode: subdev device node
+ * @lock: A mutex for serialising access to the subdev's operations. Optional.
  * @dev: pointer to the physical device, if any
  * @fwnode: The fwnode_handle of the subdev, usually the same as
  *	    either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
@@ -862,6 +864,7 @@ struct v4l2_subdev {
 	void *dev_priv;
 	void *host_priv;
 	struct video_device *devnode;
+	struct mutex *lock;
 	struct device *dev;
 	struct fwnode_handle *fwnode;
 	struct list_head async_list;
@@ -1101,16 +1104,22 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers;
 	({								\
 		struct v4l2_subdev *__sd = (sd);			\
 		int __result;						\
-		if (!__sd)						\
+		if (!__sd) {						\
 			__result = -ENODEV;				\
-		else if (!(__sd->ops->o && __sd->ops->o->f))		\
+		} else if (!(__sd->ops->o && __sd->ops->o->f)) {	\
 			__result = -ENOIOCTLCMD;			\
-		else if (v4l2_subdev_call_wrappers.o &&			\
-			 v4l2_subdev_call_wrappers.o->f)		\
-			__result = v4l2_subdev_call_wrappers.o->f(	\
-							__sd, ##args);	\
-		else							\
-			__result = __sd->ops->o->f(__sd, ##args);	\
+		} else {						\
+			if (__sd->lock)					\
+				mutex_lock(__sd->lock);			\
+			if (v4l2_subdev_call_wrappers.o &&		\
+				 v4l2_subdev_call_wrappers.o->f)	\
+				__result = v4l2_subdev_call_wrappers.o->f( \
+					__sd, ##args);			\
+			else						\
+				__result = __sd->ops->o->f(__sd, ##args); \
+			if (__sd->lock)					\
+				mutex_unlock(__sd->lock);			\
+		}							\
 		__result;						\
 	})
 
-- 
2.20.1




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux