From c4e620eccbef76aa5564ebb295e23d6540e27215 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jun 2025 08:57:35 +0200 Subject: media: dvb-core: dmxdevfilter must always flush bufs Currently the buffers are being filled until full, which works fine for the transport stream, but not when reading sections, those have to be returned to userspace immediately, otherwise dvbv5-scan will just wait forever. Add a 'flush' argument to dvb_vb2_fill_buffer to indicate whether the buffer must be flushed or wait until it is full. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/dvb_vb2.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/media') diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 8cb88452cd6c..0fbbfc65157e 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h @@ -124,7 +124,7 @@ static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx) return 0; }; #define dvb_vb2_is_streaming(ctx) (0) -#define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0) +#define dvb_vb2_fill_buffer(ctx, file, wait, flags, flush) (0) static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, @@ -166,10 +166,12 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx); * @buffer_flags: * pointer to buffer flags as defined by &enum dmx_buffer_flags. * can be NULL. + * @flush: flush the buffer, even if it isn't full. */ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, const unsigned char *src, int len, - enum dmx_buffer_flags *buffer_flags); + enum dmx_buffer_flags *buffer_flags, + bool flush); /** * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV -- cgit v1.2.3 From cbb5cd440d06a87c2c8c5819c5ad5c2a73021687 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jun 2025 08:57:37 +0200 Subject: media: dvb-core: dvb_vb2: drop wait_prepare/finish callbacks Since commit 88785982a19d ("media: vb2: use lock if wait_prepare/finish are NULL") it is no longer needed to set the wait_prepare/finish vb2_ops callbacks as long as the lock field in vb2_queue is set. Set the queue lock to &ctx->mutex, which makes it possible to drop the wait_prepare/finish callbacks. This simplifies the code and this is a step towards the goal of deleting these callbacks. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/dvb_vb2.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/media') diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 0fbbfc65157e..8932396d2c99 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h @@ -72,8 +72,6 @@ struct dvb_buffer { /** * struct dvb_vb2_ctx - control struct for VB2 handler * @vb_q: pointer to &struct vb2_queue with videobuf2 queue. - * @mutex: mutex to serialize vb2 operations. Used by - * vb2 core %wait_prepare and %wait_finish operations. * @slock: spin lock used to protect buffer filling at dvb_vb2.c. * @dvb_q: List of buffers that are not filled yet. * @buf: Pointer to the buffer that are currently being filled. @@ -96,7 +94,6 @@ struct dvb_buffer { */ struct dvb_vb2_ctx { struct vb2_queue vb_q; - struct mutex mutex; spinlock_t slock; struct list_head dvb_q; struct dvb_buffer *buf; @@ -114,8 +111,8 @@ struct dvb_vb2_ctx { }; #ifndef CONFIG_DVB_MMAP -static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, - const char *name, int non_blocking) +static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, + struct mutex *mutex, int non_blocking) { return 0; }; @@ -138,10 +135,12 @@ static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, * * @ctx: control struct for VB2 handler * @name: name for the VB2 handler + * @mutex: pointer to the mutex that serializes vb2 ioctls * @non_blocking: * if not zero, it means that the device is at non-blocking mode */ -int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking); +int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, + struct mutex *mutex, int non_blocking); /** * dvb_vb2_release - Releases the VB2 handler allocated resources and -- cgit v1.2.3 From d0730006dac2922bcd3cd16818516ddd3ffb7302 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jun 2025 08:57:38 +0200 Subject: media: vb2: remove vb2_ops_wait_prepare/finish helpers Since vb2 now relies on the presence of the vb2_queue lock field and there are no more drivers that use these helpers, it is safe to drop them. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-v4l2.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'include/media') diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 77ce8238ab30..71d2864fb235 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -367,24 +367,6 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, */ void vb2_video_unregister_device(struct video_device *vdev); -/** - * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue - * - * @vq: pointer to &struct vb2_queue - * - * ..note:: only use if vq->lock is non-NULL. - */ -void vb2_ops_wait_prepare(struct vb2_queue *vq); - -/** - * vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue - * - * @vq: pointer to &struct vb2_queue - * - * ..note:: only use if vq->lock is non-NULL. - */ -void vb2_ops_wait_finish(struct vb2_queue *vq); - struct media_request; int vb2_request_validate(struct media_request *req); void vb2_request_queue(struct media_request *req); -- cgit v1.2.3 From b70886ff5833cf499e77af77d2324ce8f68b60ce Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jun 2025 08:57:39 +0200 Subject: media: vb2: drop wait_prepare/finish callbacks Drop the wait_prepare/finish callbacks. Instead require that the vb2_queue lock field is always set and use that lock when waiting for buffers to arrive. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-core.h | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'include/media') diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 9b02aeba4108..4424d481d7f7 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -351,13 +351,6 @@ struct vb2_buffer { * \*num_buffers are being allocated additionally to * the buffers already allocated. If either \*num_planes * or the requested sizes are invalid callback must return %-EINVAL. - * @wait_prepare: release any locks taken while calling vb2 functions; - * it is called before an ioctl needs to wait for a new - * buffer to arrive; required to avoid a deadlock in - * blocking access type. - * @wait_finish: reacquire all locks released in the previous callback; - * required to continue operation after sleeping while - * waiting for a new buffer to arrive. * @buf_out_validate: called when the output buffer is prepared or queued * to a request; drivers can use this to validate * userspace-provided information; this is required only @@ -436,9 +429,6 @@ struct vb2_ops { unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], struct device *alloc_devs[]); - void (*wait_prepare)(struct vb2_queue *q); - void (*wait_finish)(struct vb2_queue *q); - int (*buf_out_validate)(struct vb2_buffer *vb); int (*buf_init)(struct vb2_buffer *vb); int (*buf_prepare)(struct vb2_buffer *vb); @@ -521,10 +511,10 @@ struct vb2_buf_ops { * @non_coherent_mem: when set queue will attempt to allocate buffers using * non-coherent memory. * @lock: pointer to a mutex that protects the &struct vb2_queue. The - * driver can set this to a mutex to let the v4l2 core serialize - * the queuing ioctls. If the driver wants to handle locking - * itself, then this should be set to NULL. This lock is not used - * by the videobuf2 core API. + * driver must set this to a mutex to let the v4l2 core serialize + * the queuing ioctls. This lock is used when waiting for a new + * buffer to arrive: the lock is released, we wait for the new + * buffer, and then retaken. * @owner: The filehandle that 'owns' the buffers, i.e. the filehandle * that called reqbufs, create_buffers or started fileio. * This field is not used by the videobuf2 core API, but it allows @@ -680,8 +670,6 @@ struct vb2_queue { * called. Used to check for unbalanced ops. */ u32 cnt_queue_setup; - u32 cnt_wait_prepare; - u32 cnt_wait_finish; u32 cnt_prepare_streaming; u32 cnt_start_streaming; u32 cnt_stop_streaming; @@ -766,8 +754,7 @@ void vb2_discard_done(struct vb2_queue *q); * @q: pointer to &struct vb2_queue with videobuf2 queue. * * This function will wait until all buffers that have been given to the driver - * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It - * doesn't call &vb2_ops->wait_prepare/&vb2_ops->wait_finish pair. + * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). * It is intended to be called with all locks taken, for example from * &vb2_ops->stop_streaming callback. */ -- cgit v1.2.3 From bea467aa5da1f51834501da3ac3c40204027a221 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 16 Dec 2025 15:26:14 +0100 Subject: docs: media: v4l2-ioctl.h: document two global variables The media kAPI has two global variables at v4l2-ioctl.h. Document them. Acked-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet Message-ID: <8ebe25ff579962fec09b586f00e77fae7802985f.1765894964.git.mchehab+huawei@kernel.org> --- include/media/v4l2-ioctl.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/media') diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 6f7a58350441..54c83b18d555 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -663,7 +663,22 @@ void v4l_printk_ioctl(const char *prefix, unsigned int cmd); struct video_device; /* names for fancy debug output */ + +/** + * var v4l2_field_names - Helper array mapping ``V4L2_FIELD_*`` to strings. + * + * Specially when printing debug messages, it is interesting to output + * the field order at the V4L2 buffers. This array associates all possible + * values of field pix format from V4L2 API into a string. + */ extern const char *v4l2_field_names[]; + +/** + * var v4l2_type_names - Helper array mapping ``V4L2_BUF_TYPE_*`` to strings. + * + * When printing debug messages, it is interesting to output the V4L2 buffer + * type number with a name that represents its content. + */ extern const char *v4l2_type_names[]; #ifdef CONFIG_COMPAT -- cgit v1.2.3 From c789a7f40288c19004f786a6da67c3733d38c6af Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 28 Nov 2025 14:16:12 -0500 Subject: media: mc: add manual request completion By default when the last request object is completed, the whole request completes as well. But sometimes you want to delay this completion to an arbitrary point in time so add a manual complete mode for this. In req_queue the driver marks the request for manual completion by calling media_request_mark_manual_completion, and when the driver wants to manually complete the request it calls media_request_manual_complete(). Signed-off-by: Hans Verkuil Signed-off-by: Nicolas Dufresne --- include/media/media-request.h | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'include/media') diff --git a/include/media/media-request.h b/include/media/media-request.h index bb500b2f9da4..3256fcf3709d 100644 --- a/include/media/media-request.h +++ b/include/media/media-request.h @@ -56,6 +56,9 @@ struct media_request_object; * @access_count: count the number of request accesses that are in progress * @objects: List of @struct media_request_object request objects * @num_incomplete_objects: The number of incomplete objects in the request + * @manual_completion: if true, then the request won't be marked as completed + * when @num_incomplete_objects reaches 0. Call media_request_manual_complete() + * to complete the request after @num_incomplete_objects == 0. * @poll_wait: Wait queue for poll * @lock: Serializes access to this struct */ @@ -68,6 +71,7 @@ struct media_request { unsigned int access_count; struct list_head objects; unsigned int num_incomplete_objects; + bool manual_completion; wait_queue_head_t poll_wait; spinlock_t lock; }; @@ -218,6 +222,38 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd); int media_request_alloc(struct media_device *mdev, int *alloc_fd); +/** + * media_request_mark_manual_completion - Enable manual completion + * + * @req: The request + * + * Mark that the request has to be manually completed by calling + * media_request_manual_complete(). + * + * This function shall be called in the req_queue callback. + */ +static inline void +media_request_mark_manual_completion(struct media_request *req) +{ + req->manual_completion = true; +} + +/** + * media_request_manual_complete - Mark the request as completed + * + * @req: The request + * + * This function completes a request that was marked for manual completion by an + * earlier call to media_request_mark_manual_completion(). The request's + * @manual_completion field is reset to false. + * + * All objects contained in the request must have been completed previously. It + * is an error to call this function otherwise. If such an error occurred, the + * function will WARN and the object completion will be delayed until + * @num_incomplete_objects is 0. + */ +void media_request_manual_complete(struct media_request *req); + #else static inline void media_request_get(struct media_request *req) @@ -336,7 +372,7 @@ void media_request_object_init(struct media_request_object *obj); * @req: The media request * @ops: The object ops for this object * @priv: A driver-specific priv pointer associated with this object - * @is_buffer: Set to true if the object a buffer object. + * @is_buffer: Set to true if the object is a buffer object. * @obj: The object * * Bind this object to the request and set the ops and priv values of -- cgit v1.2.3 From de9f0c2a1ce3d97561d5cf4678b80e13943647fd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 28 Nov 2025 14:16:14 -0500 Subject: media: mc: add debugfs node to keep track of requests Keep track of the number of requests and request objects of a media device. Helps to verify that all request-related memory is freed. Signed-off-by: Hans Verkuil Signed-off-by: Nicolas Dufresne --- include/media/media-device.h | 9 +++++++++ include/media/media-devnode.h | 4 ++++ include/media/media-request.h | 2 ++ 3 files changed, 15 insertions(+) (limited to 'include/media') diff --git a/include/media/media-device.h b/include/media/media-device.h index 53d2a16a70b0..749c327e3c58 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -11,6 +11,7 @@ #ifndef _MEDIA_DEVICE_H #define _MEDIA_DEVICE_H +#include #include #include #include @@ -106,6 +107,9 @@ struct media_device_ops { * @ops: Operation handler callbacks * @req_queue_mutex: Serialise the MEDIA_REQUEST_IOC_QUEUE ioctl w.r.t. * other operations that stop or start streaming. + * @num_requests: number of associated requests + * @num_request_objects: number of associated request objects + * @media_dir: DebugFS media directory * @request_id: Used to generate unique request IDs * * This structure represents an abstract high-level media device. It allows easy @@ -179,6 +183,11 @@ struct media_device { const struct media_device_ops *ops; struct mutex req_queue_mutex; + atomic_t num_requests; + atomic_t num_request_objects; + + /* debugfs */ + struct dentry *media_dir; atomic_t request_id; }; diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index d27c1c646c28..dbcabeffcb57 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -20,9 +20,13 @@ #include #include #include +#include struct media_device; +/* debugfs top-level media directory */ +extern struct dentry *media_debugfs_root; + /* * Flag to mark the media_devnode struct as registered. Drivers must not touch * this flag directly, it will be set and cleared by media_devnode_register and diff --git a/include/media/media-request.h b/include/media/media-request.h index 3256fcf3709d..43ed18c11b51 100644 --- a/include/media/media-request.h +++ b/include/media/media-request.h @@ -292,6 +292,7 @@ struct media_request_object_ops { * struct media_request_object - An opaque object that belongs to a media * request * + * @mdev: Media device this object belongs to * @ops: object's operations * @priv: object's priv pointer * @req: the request this object belongs to (can be NULL) @@ -303,6 +304,7 @@ struct media_request_object_ops { * another struct that contains the actual data for this request object. */ struct media_request_object { + struct media_device *mdev; const struct media_request_object_ops *ops; void *priv; struct media_request *req; -- cgit v1.2.3 From db6b97a4f8041e479be9ef4b8b07022636c96f50 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 5 Dec 2025 09:54:24 +0800 Subject: media: v4l2-mem2mem: Add a kref to the v4l2_m2m_dev structure Adding a reference count to the v4l2_m2m_dev structure allow safely sharing it across multiple hardware nodes. This can be used to prevent running jobs concurrently on m2m cores that have some internal resource sharing. Signed-off-by: Ming Qian Reviewed-by: Frank Li Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil [hverkuil: fix typos in v4l2_m2m_put documentation] --- include/media/v4l2-mem2mem.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/media') diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index bf6a09a04dcf..31de25d792b9 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -547,6 +547,27 @@ v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev, */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); +/** + * v4l2_m2m_get() - take a reference to the m2m_dev structure + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * This is used to share the M2M device across multiple devices. This + * can be used to avoid scheduling two hardware nodes concurrently. + */ +void v4l2_m2m_get(struct v4l2_m2m_dev *m2m_dev); + +/** + * v4l2_m2m_put() - remove a reference to the m2m_dev structure + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Once the M2M device has no more references, v4l2_m2m_release() will be + * called automatically. Users of this method should never call + * v4l2_m2m_release() directly. See v4l2_m2m_get() for more details. + */ +void v4l2_m2m_put(struct v4l2_m2m_dev *m2m_dev); + /** * v4l2_m2m_ctx_init() - allocate and initialize a m2m context * -- cgit v1.2.3 From e3d5436c7099881e3604826757c8d65acc2d94f3 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 11 Nov 2025 13:07:29 +0200 Subject: media: v4l2-ctrls: Set error v4l2_ctrl_new_fwnode_properties consistently The vast majority of the callers of v4l2_ctrl_new_fwnode_properties() do check the returned error code but the function does not set the control handler's error on failure. This will make error handling more complicated and prone for bugs. Always assign the control handler's error field on error in v4l2_ctrl_new_fwnode_properties(). Signed-off-by: Sakari Ailus Reviewed-by: Jacopo Mondi Signed-off-by: Hans Verkuil --- include/media/v4l2-ctrls.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/media') diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 31fc1bee3797..327976b14d50 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -1581,6 +1581,9 @@ int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd); * not overwritten. Callers should register the controls they want to handle * themselves before calling this function. * + * This function will set the control handler's error field on failure, just as + * other functions adding controls to the handler. + * * Return: 0 on success, a negative error code on failure. */ int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, -- cgit v1.2.3 From 37a5b80a94cc6ca3b6a5c2999a6ad008ca2e6277 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 12 Nov 2025 09:57:57 +0200 Subject: media: v4l2-fwnode: Allow passing NULL fwnode to endpoint parsers v4l2_fwnode_endpoint_parse() and v4l2_fwnode_endpoint_alloc_parse() take a fwnode as the first argument and leave it up to the caller to check a valid fwnode has been obtained through various means. Instead, add a check here so the callers won't need to do that anymore. Signed-off-by: Sakari Ailus Reviewed-by: Michael Riesch Signed-off-by: Hans Verkuil --- include/media/v4l2-fwnode.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/media') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index f7c57c776589..cd82e70ccbaa 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -182,7 +182,7 @@ enum v4l2_fwnode_bus_type { /** * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties - * @fwnode: pointer to the endpoint's fwnode handle + * @fwnode: pointer to the endpoint's fwnode handle (may be NULL) * @vep: pointer to the V4L2 fwnode data structure * * This function parses the V4L2 fwnode endpoint specific parameters from the @@ -218,7 +218,7 @@ enum v4l2_fwnode_bus_type { * * Return: %0 on success or a negative error code on failure: * %-ENOMEM on memory allocation failure - * %-EINVAL on parsing failure + * %-EINVAL on parsing failure, including @fwnode == NULL * %-ENXIO on mismatching bus types */ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, @@ -236,7 +236,7 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); /** * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties - * @fwnode: pointer to the endpoint's fwnode handle + * @fwnode: pointer to the endpoint's fwnode handle (may be NULL) * @vep: pointer to the V4L2 fwnode data structure * * This function parses the V4L2 fwnode endpoint specific parameters from the @@ -276,7 +276,7 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * * Return: %0 on success or a negative error code on failure: * %-ENOMEM on memory allocation failure - * %-EINVAL on parsing failure + * %-EINVAL on parsing failure, including @fwnode == NULL * %-ENXIO on mismatching bus types */ int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode, -- cgit v1.2.3