Re: [PATCH v2 16/27] media: v4l2-subdev: Add subdev state accessor helpers

John Cox <[email protected]>
Newsgroups org.kernel.vger.linux-media,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <CAFyCYyNsKa4CvpYNsRc_UabDg5emev6qdCtqUkqMHbJ0BNiOnw@mail.gmail.com>
> 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 <[email protected]>
> ---
>  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_
> +                       v4l2_subdev_lock_and_get_active_state_from_sd,          \
> +               struct v4l2_subdev_context *:                                   \
> +                       v4l2_subdev_get_locked_active_state_from_ctx)           \
Cut and paste error?
This should be v4l2_subdev_lock_and_get_active_state_from_ctx?

Regards

John Cox

> +       (sdctx)
>
>  /**
>   * v4l2_subdev_init - initializes the sub-device struct
>
> --
> 2.49.0
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.