[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250717-multicontext-mainline-2025-v1-16-81ac18979c03@ideasonboard.com>
Date: Thu, 17 Jul 2025 12:45:42 +0200
From: Jacopo Mondi <jacopo.mondi@...asonboard.com>
To: Sakari Ailus <sakari.ailus@...ux.intel.com>,
Laurent Pinchart <laurent.pinchart@...asonboard.com>,
Tomi Valkeinen <tomi.valkeinen@...asonboard.com>,
Kieran Bingham <kieran.bingham@...asonboard.com>,
Nicolas Dufresne <nicolas.dufresne@...labora.com>,
Mauro Carvalho Chehab <mchehab@...nel.org>,
Tomasz Figa <tfiga@...omium.org>,
Marek Szyprowski <m.szyprowski@...sung.com>,
Raspberry Pi Kernel Maintenance <kernel-list@...pberrypi.com>,
Florian Fainelli <florian.fainelli@...adcom.com>,
Broadcom internal kernel review list <bcm-kernel-feedback-list@...adcom.com>,
Hans Verkuil <hverkuil@...nel.org>
Cc: linux-kernel@...r.kernel.org, linux-media@...r.kernel.org,
linux-rpi-kernel@...ts.infradead.org, linux-arm-kernel@...ts.infradead.org,
Jacopo Mondi <jacopo.mondi@...asonboard.com>
Subject: [PATCH 16/26] media: v4l2-subdev: Add subdev state accessor
helpers
The v4l2-subdev.c file offers three helpers to access the subdevice
active state from a v4l2_subdev pointer:
- v4l2_subdev_get_unlocked_active_state(sd)
- v4l2_subdev_get_locked_active_state(sd)
- v4l2_subdev_lock_and_get_active_state(sd)
With the introduction of struct v4l2_subdev_context which contains a
subdev_state as well, the actual "active" state is stored in three
possible places:
- A context associated with a v4l2_subdev_fh for context aware drivers
operated by context aware userspace
- The default subdevice context for context aware drivers operated by
non-context aware userspace
- The subdevice active state for non-context aware drivers
Provide helpers similar in spirit the existing ones but accept as
argument either a subdevice the context itself and retrieve the active
state from the correct place.
Helpers will be used in following patches for link validation.
Signed-off-by: Jacopo Mondi <jacopo.mondi@...asonboard.com>
---
drivers/media/v4l2-core/v4l2-subdev.c | 101 +++++++++++++++++++++++++++++++++
include/media/v4l2-subdev.h | 104 +++++++++++++++++++---------------
2 files changed, 159 insertions(+), 46 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 438f51980e5ac0f092ba6b0a979a376133968ddf..7372f61127c871cec44a3d1900e2b8bef34632b9 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -20,6 +20,7 @@
#include <linux/version.h>
#include <linux/videodev2.h>
+#include <media/media-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@@ -189,6 +190,106 @@ static inline int check_pad(struct v4l2_subdev *sd, u32 pad)
return 0;
}
+/* subdev state accessor helpers */
+
+/*
+ * Access the state from the subdevice.
+ *
+ * If the driver is context-aware use the state stored in the default context
+ * otherwise use the active state stored in the subdevice.
+ */
+
+struct v4l2_subdev_state *
+v4l2_subdev_get_unlocked_active_state_from_sd(struct v4l2_subdev *sd)
+{
+ if (!sd)
+ return NULL;
+
+ if (sd->default_context) {
+ lockdep_assert_not_held(sd->default_context->state->lock);
+
+ return sd->default_context->state;
+ }
+
+ if (sd->active_state)
+ lockdep_assert_not_held(sd->active_state->lock);
+ return sd->active_state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_unlocked_active_state_from_sd);
+
+struct v4l2_subdev_state *
+v4l2_subdev_get_locked_active_state_from_sd(struct v4l2_subdev *sd)
+{
+ if (!sd)
+ return NULL;
+
+ if (sd->default_context) {
+ lockdep_assert_held(sd->default_context->state->lock);
+
+ return sd->default_context->state;
+ }
+
+ if (sd->active_state)
+ lockdep_assert_held(sd->active_state->lock);
+ return sd->active_state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_locked_active_state_from_sd);
+
+struct v4l2_subdev_state *
+v4l2_subdev_lock_and_get_active_state_from_sd(struct v4l2_subdev *sd)
+{
+ if (!sd)
+ return NULL;
+
+ if (sd->default_context) {
+ v4l2_subdev_lock_state(sd->default_context->state);
+
+ return sd->default_context->state;
+ }
+
+ if (sd->active_state)
+ v4l2_subdev_lock_state(sd->active_state);
+ return sd->active_state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_lock_and_get_active_state_from_sd);
+
+/* Access the subdevice state from a subdvice context. */
+struct v4l2_subdev_state *
+v4l2_subdev_get_unlocked_active_state_from_ctx(struct v4l2_subdev_context *ctx)
+{
+ if (!ctx)
+ return NULL;
+
+ if (ctx->state)
+ lockdep_assert_not_held(ctx->state->lock);
+ return ctx->state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_unlocked_active_state_from_ctx);
+
+struct v4l2_subdev_state *
+v4l2_subdev_get_locked_active_state_from_ctx(struct v4l2_subdev_context *ctx)
+{
+ if (!ctx)
+ return NULL;
+
+ if (ctx->state)
+ lockdep_assert_held(ctx->state->lock);
+ return ctx->state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_get_locked_active_state_from_ctx);
+
+struct v4l2_subdev_state *
+v4l2_subdev_lock_and_get_active_state_from_ctx(struct v4l2_subdev_context *ctx)
+{
+ if (!ctx)
+ return NULL;
+
+ if (ctx->state)
+ v4l2_subdev_lock_state(ctx->state);
+ return ctx->state;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_lock_and_get_active_state_from_ctx);
+
static int check_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,
u32 which, u32 pad, u32 stream)
{
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 1fa42a9f322be0be44fc9308744f4f4ae0cf1606..8087c0ae3bc0a0a95512b4b0ff5257522a104ca0 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -29,16 +29,17 @@
#define V4L2_DEVICE_NOTIFY_EVENT _IOW('v', 2, struct v4l2_event)
-struct v4l2_device;
+struct led_classdev;
+struct media_device_context;
+struct tuner_setup;
struct v4l2_ctrl_handler;
+struct v4l2_device;
struct v4l2_event;
struct v4l2_event_subscription;
struct v4l2_fh;
+struct v4l2_mbus_frame_desc;
struct v4l2_subdev;
struct v4l2_subdev_fh;
-struct tuner_setup;
-struct v4l2_mbus_frame_desc;
-struct led_classdev;
/**
* struct v4l2_decode_vbi_line - used to decode_vbi_line
@@ -1968,64 +1969,75 @@ static inline void v4l2_subdev_unlock_states(struct v4l2_subdev_state *state1,
mutex_unlock(state2->lock);
}
+struct v4l2_subdev_state *
+v4l2_subdev_get_unlocked_active_state_from_sd(struct v4l2_subdev *sd);
+struct v4l2_subdev_state *
+v4l2_subdev_get_locked_active_state_from_sd(struct v4l2_subdev *sd);
+struct v4l2_subdev_state *
+v4l2_subdev_lock_and_get_active_state_from_sd(struct v4l2_subdev *sd);
+
+struct v4l2_subdev_state *
+v4l2_subdev_get_unlocked_active_state_from_ctx(struct v4l2_subdev_context *ctx);
+struct v4l2_subdev_state *
+v4l2_subdev_get_locked_active_state_from_ctx(struct v4l2_subdev_context *ctx);
+struct v4l2_subdev_state *
+v4l2_subdev_lock_and_get_active_state_from_ctx(struct v4l2_subdev_context *ctx);
+
/**
- * v4l2_subdev_get_unlocked_active_state() - Checks that the active subdev state
- * is unlocked and returns it
- * @sd: The subdevice
+ * v4l2_subdev_get_unlocked_active_state() - Checks that the subdev state is
+ * unlocked and returns it
+ * @sdctx: The subdevice, or the subdevice context
*
- * Returns the active state for the subdevice, or NULL if the subdev does not
- * support active state. If the state is not NULL, calls
- * lockdep_assert_not_held() to issue a warning if the state is locked.
+ * Returns the subdevice state, or NULL if it is not valid. If the state is
+ * not NULL, calls lockdep_assert_not_held() to issue a warning if the state
+ * is locked.
*
- * This function is to be used e.g. when getting the active state for the sole
- * purpose of passing it forward, without accessing the state fields.
+ * This function is to be used e.g. when getting the state for the sole purpose
+ * of passing it forward, without accessing the state fields.
*/
-static inline struct v4l2_subdev_state *
-v4l2_subdev_get_unlocked_active_state(struct v4l2_subdev *sd)
-{
- if (sd->active_state)
- lockdep_assert_not_held(sd->active_state->lock);
- return sd->active_state;
-}
+#define v4l2_subdev_get_unlocked_active_state(sdctx) \
+ _Generic((sdctx), \
+ struct v4l2_subdev *: \
+ v4l2_subdev_get_unlocked_active_state_from_sd, \
+ struct v4l2_subdev_context *: \
+ v4l2_subdev_get_unlocked_active_state_from_ctx) \
+ (sdctx)
/**
- * v4l2_subdev_get_locked_active_state() - Checks that the active subdev state
- * is locked and returns it
- *
- * @sd: The subdevice
+ * v4l2_subdev_get_locked_active_state() - Checks that the subdev state is
+ * locked and returns it
+ * @sdctx: The subdevice, or the subdevice context
*
- * Returns the active state for the subdevice, or NULL if the subdev does not
- * support active state. If the state is not NULL, calls lockdep_assert_held()
- * to issue a warning if the state is not locked.
+ * Returns the subdevice state, or NULL is not valid. If the state is not NULL,
+ * calls lockdep_assert_held() to issue a warning if the state is not locked.
*
- * This function is to be used when the caller knows that the active state is
+ * This function is to be used when the caller knows that the context state is
* already locked.
*/
-static inline struct v4l2_subdev_state *
-v4l2_subdev_get_locked_active_state(struct v4l2_subdev *sd)
-{
- if (sd->active_state)
- lockdep_assert_held(sd->active_state->lock);
- return sd->active_state;
-}
+#define v4l2_subdev_get_locked_active_state(sdctx) \
+ _Generic((sdctx), \
+ struct v4l2_subdev *: \
+ v4l2_subdev_get_locked_active_state_from_sd, \
+ struct v4l2_subdev_context *: \
+ v4l2_subdev_get_locked_active_state_from_ctx) \
+ (sdctx)
/**
- * v4l2_subdev_lock_and_get_active_state() - Locks and returns the active subdev
- * state for the subdevice
- * @sd: The subdevice
+ * v4l2_subdev_lock_and_get_active_state_from_ctx() - Locks and returns the
+ * subdevice state
+ * @sdctx: The subdevice, or the subdevice context
*
- * Returns the locked active state for the subdevice, or NULL if the subdev
- * does not support active state.
+ * Returns the locked subdevice state, or NULL if it is not valid.
*
* The state must be unlocked with v4l2_subdev_unlock_state() after use.
*/
-static inline struct v4l2_subdev_state *
-v4l2_subdev_lock_and_get_active_state(struct v4l2_subdev *sd)
-{
- if (sd->active_state)
- v4l2_subdev_lock_state(sd->active_state);
- return sd->active_state;
-}
+#define v4l2_subdev_lock_and_get_active_state(sdctx) \
+ _Generic((sdctx), \
+ struct v4l2_subdev *: \
+ v4l2_subdev_lock_and_get_active_state_from_sd, \
+ struct v4l2_subdev_context *: \
+ v4l2_subdev_get_locked_active_state_from_ctx) \
+ (sdctx)
/**
* v4l2_subdev_init - initializes the sub-device struct
--
2.49.0
Powered by blists - more mailing lists