From 50ba0232fd5312410f1b65247e774244f89a628e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 20:50:36 +0200 Subject: Merging upstream version 6.8.9. Signed-off-by: Daniel Baumann --- include/media/cec.h | 22 ++- include/media/v4l2-cci.h | 5 + include/media/v4l2-common.h | 4 +- include/media/v4l2-mem2mem.h | 9 +- include/media/v4l2-subdev.h | 419 ++++++++++++++++++++--------------------- include/media/videobuf2-core.h | 61 ++++-- 6 files changed, 286 insertions(+), 234 deletions(-) (limited to 'include/media') diff --git a/include/media/cec.h b/include/media/cec.h index 53e4b2eb2b..d779826851 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -207,7 +207,20 @@ struct cec_adap_ops { * passthrough mode. * @log_addrs: current logical addresses * @conn_info: current connector info - * @tx_timeouts: number of transmit timeouts + * @tx_timeout_cnt: count the number of Timed Out transmits. + * Reset to 0 when this is reported in cec_adap_status(). + * @tx_low_drive_cnt: count the number of Low Drive transmits. + * Reset to 0 when this is reported in cec_adap_status(). + * @tx_error_cnt: count the number of Error transmits. + * Reset to 0 when this is reported in cec_adap_status(). + * @tx_arb_lost_cnt: count the number of Arb Lost transmits. + * Reset to 0 when this is reported in cec_adap_status(). + * @tx_low_drive_log_cnt: number of logged Low Drive transmits since the + * adapter was enabled. Used to avoid flooding the kernel + * log if this happens a lot. + * @tx_error_log_cnt: number of logged Error transmits since the adapter was + * enabled. Used to avoid flooding the kernel log if this + * happens a lot. * @notifier: CEC notifier * @pin: CEC pin status struct * @cec_dir: debugfs cec directory @@ -262,7 +275,12 @@ struct cec_adapter { struct cec_log_addrs log_addrs; struct cec_connector_info conn_info; - u32 tx_timeouts; + u32 tx_timeout_cnt; + u32 tx_low_drive_cnt; + u32 tx_error_cnt; + u32 tx_arb_lost_cnt; + u32 tx_low_drive_log_cnt; + u32 tx_error_log_cnt; #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h index 8b0b361b46..4e96e90ee6 100644 --- a/include/media/v4l2-cci.h +++ b/include/media/v4l2-cci.h @@ -34,6 +34,11 @@ struct cci_reg_sequence { #define CCI_REG_ADDR_MASK GENMASK(15, 0) #define CCI_REG_WIDTH_SHIFT 16 #define CCI_REG_WIDTH_MASK GENMASK(19, 16) +/* + * Private CCI register flags, for the use of drivers. + */ +#define CCI_REG_PRIVATE_SHIFT 28U +#define CCI_REG_PRIVATE_MASK GENMASK(31U, CCI_REG_PRIVATE_SHIFT) #define CCI_REG_WIDTH_BYTES(x) FIELD_GET(CCI_REG_WIDTH_MASK, x) #define CCI_REG_WIDTH(x) (CCI_REG_WIDTH_BYTES(x) << 3) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index d278836fd9..acf5be24a5 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -425,7 +425,7 @@ __v4l2_find_nearest_size(const void *array, size_t array_size, /** * v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by - * calling the g_frame_interval op of the given subdev. It only works + * calling the get_frame_interval op of the given subdev. It only works * for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the * function name. * @@ -438,7 +438,7 @@ int v4l2_g_parm_cap(struct video_device *vdev, /** * v4l2_s_parm_cap - helper routine for vidioc_s_parm to fill this in by - * calling the s_frame_interval op of the given subdev. It only works + * calling the set_frame_interval op of the given subdev. It only works * for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the * function name. * diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index d6c8eb2b52..7f1af1f7f9 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -84,6 +84,12 @@ struct v4l2_m2m_queue_ctx { * @last_src_buf: indicate the last source buffer for draining * @next_buf_last: next capture queud buffer will be tagged as last * @has_stopped: indicate the device has been stopped + * @ignore_cap_streaming: If true, job_ready can be called even if the CAPTURE + * queue is not streaming. This allows firmware to + * analyze the bitstream header which arrives on the + * OUTPUT queue. The driver must implement the job_ready + * callback correctly to make sure that the requirements + * for actual decoding are met. * @m2m_dev: opaque pointer to the internal data to handle M2M context * @cap_q_ctx: Capture (output to memory) queue context * @out_q_ctx: Output (input from memory) queue context @@ -106,6 +112,7 @@ struct v4l2_m2m_ctx { struct vb2_v4l2_buffer *last_src_buf; bool next_buf_last; bool has_stopped; + bool ignore_cap_streaming; /* internal use only */ struct v4l2_m2m_dev *m2m_dev; @@ -661,7 +668,7 @@ v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) struct vb2_v4l2_buffer *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx); /** - * v4l2_m2m_last_src_buf() - return last destination buffer from the list of + * v4l2_m2m_last_src_buf() - return last source buffer from the list of * ready buffers * * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index c1f90c1223..a9e6b81462 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -452,12 +452,6 @@ enum v4l2_subdev_pre_streamon_flags { * * @g_pixelaspect: callback to return the pixelaspect ratio. * - * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL() - * ioctl handler code. - * - * @s_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL() - * ioctl handler code. - * * @s_dv_timings: Set custom dv timings in the sub device. This is used * when sub device is capable of setting detailed timing information * in the hardware to generate/detect the video signal. @@ -496,10 +490,6 @@ struct v4l2_subdev_video_ops { int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); - int (*g_frame_interval)(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval); - int (*s_frame_interval)(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval); int (*s_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); int (*g_dv_timings)(struct v4l2_subdev *sd, @@ -688,21 +678,16 @@ struct v4l2_subdev_ir_ops { /** * struct v4l2_subdev_pad_config - Used for storing subdev pad information. * - * @try_fmt: &struct v4l2_mbus_framefmt - * @try_crop: &struct v4l2_rect to be used for crop - * @try_compose: &struct v4l2_rect to be used for compose - * - * This structure only needs to be passed to the pad op if the 'which' field - * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For - * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL. - * - * Note: This struct is also used in active state, and the 'try' prefix is - * historical and to be removed. + * @format: &struct v4l2_mbus_framefmt + * @crop: &struct v4l2_rect to be used for crop + * @compose: &struct v4l2_rect to be used for compose + * @interval: frame interval */ struct v4l2_subdev_pad_config { - struct v4l2_mbus_framefmt try_fmt; - struct v4l2_rect try_crop; - struct v4l2_rect try_compose; + struct v4l2_mbus_framefmt format; + struct v4l2_rect crop; + struct v4l2_rect compose; + struct v4l2_fract interval; }; /** @@ -714,6 +699,7 @@ struct v4l2_subdev_pad_config { * @fmt: &struct v4l2_mbus_framefmt * @crop: &struct v4l2_rect to be used for crop * @compose: &struct v4l2_rect to be used for compose + * @interval: frame interval * * This structure stores configuration for a stream. */ @@ -725,6 +711,7 @@ struct v4l2_subdev_stream_config { struct v4l2_mbus_framefmt fmt; struct v4l2_rect crop; struct v4l2_rect compose; + struct v4l2_fract interval; }; /** @@ -756,6 +743,7 @@ struct v4l2_subdev_krouting { * * @_lock: default for 'lock' * @lock: mutex for the state. May be replaced by the user. + * @sd: the sub-device which the state is related to * @pads: &struct v4l2_subdev_pad_config array * @routing: routing table for the subdev * @stream_configs: stream configurations (only for V4L2_SUBDEV_FL_STREAMS) @@ -768,6 +756,7 @@ struct v4l2_subdev_state { /* lock for the struct v4l2_subdev_state fields */ struct mutex _lock; struct mutex *lock; + struct v4l2_subdev *sd; struct v4l2_subdev_pad_config *pads; struct v4l2_subdev_krouting routing; struct v4l2_subdev_stream_configs stream_configs; @@ -776,7 +765,6 @@ struct v4l2_subdev_state { /** * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations * - * @init_cfg: initialize the pad config to default values * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler * code. * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE() ioctl handler @@ -793,6 +781,12 @@ struct v4l2_subdev_state { * * @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code. * + * @get_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL() + * ioctl handler code. + * + * @set_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL() + * ioctl handler code. + * * @get_edid: callback for VIDIOC_SUBDEV_G_EDID() ioctl handler code. * * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code. @@ -841,8 +835,6 @@ struct v4l2_subdev_state { * directly, use v4l2_subdev_disable_streams() instead. */ struct v4l2_subdev_pad_ops { - int (*init_cfg)(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state); int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code); @@ -864,6 +856,12 @@ struct v4l2_subdev_pad_ops { int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel); + int (*get_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_interval *interval); + int (*set_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_interval *interval); int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); int (*dv_timings_cap)(struct v4l2_subdev *sd, @@ -919,6 +917,8 @@ struct v4l2_subdev_ops { /** * struct v4l2_subdev_internal_ops - V4L2 subdev internal ops * + * @init_state: initialize the subdev state to default values + * * @registered: called when this subdev is registered. When called the v4l2_dev * field is set to the correct v4l2_device. * @@ -944,6 +944,8 @@ struct v4l2_subdev_ops { * these ops. */ struct v4l2_subdev_internal_ops { + int (*init_state)(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state); int (*registered)(struct v4l2_subdev *sd); void (*unregistered)(struct v4l2_subdev *sd); int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); @@ -1142,83 +1144,6 @@ struct v4l2_subdev_fh { #define to_v4l2_subdev_fh(fh) \ container_of(fh, struct v4l2_subdev_fh, vfh) -#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) - -/** - * v4l2_subdev_get_pad_format - ancillary routine to call - * &struct v4l2_subdev_pad_config->try_fmt - * - * @sd: pointer to &struct v4l2_subdev - * @state: pointer to &struct v4l2_subdev_state - * @pad: index of the pad in the &struct v4l2_subdev_state->pads array - */ -static inline struct v4l2_mbus_framefmt * -v4l2_subdev_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - unsigned int pad) -{ - if (WARN_ON(!state)) - return NULL; - if (WARN_ON(pad >= sd->entity.num_pads)) - pad = 0; - return &state->pads[pad].try_fmt; -} - -/** - * v4l2_subdev_get_pad_crop - ancillary routine to call - * &struct v4l2_subdev_pad_config->try_crop - * - * @sd: pointer to &struct v4l2_subdev - * @state: pointer to &struct v4l2_subdev_state. - * @pad: index of the pad in the &struct v4l2_subdev_state->pads array. - */ -static inline struct v4l2_rect * -v4l2_subdev_get_pad_crop(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - unsigned int pad) -{ - if (WARN_ON(!state)) - return NULL; - if (WARN_ON(pad >= sd->entity.num_pads)) - pad = 0; - return &state->pads[pad].try_crop; -} - -/** - * v4l2_subdev_get_pad_compose - ancillary routine to call - * &struct v4l2_subdev_pad_config->try_compose - * - * @sd: pointer to &struct v4l2_subdev - * @state: pointer to &struct v4l2_subdev_state. - * @pad: index of the pad in the &struct v4l2_subdev_state->pads array. - */ -static inline struct v4l2_rect * -v4l2_subdev_get_pad_compose(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - unsigned int pad) -{ - if (WARN_ON(!state)) - return NULL; - if (WARN_ON(pad >= sd->entity.num_pads)) - pad = 0; - return &state->pads[pad].try_compose; -} - -/* - * Temprary helpers until uses of v4l2_subdev_get_try_* functions have been - * renamed - */ -#define v4l2_subdev_get_try_format(sd, state, pad) \ - v4l2_subdev_get_pad_format(sd, state, pad) - -#define v4l2_subdev_get_try_crop(sd, state, pad) \ - v4l2_subdev_get_pad_crop(sd, state, pad) - -#define v4l2_subdev_get_try_compose(sd, state, pad) \ - v4l2_subdev_get_pad_compose(sd, state, pad) - -#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */ - extern const struct v4l2_file_operations v4l2_subdev_fops; /** @@ -1392,88 +1317,105 @@ int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name, */ void v4l2_subdev_cleanup(struct v4l2_subdev *sd); -/** - * v4l2_subdev_lock_state() - Locks the subdev state - * @state: The subdevice state - * - * Locks the given subdev state. - * - * The state must be unlocked with v4l2_subdev_unlock_state() after use. +/* + * A macro to generate the macro or function name for sub-devices state access + * wrapper macros below. */ -static inline void v4l2_subdev_lock_state(struct v4l2_subdev_state *state) -{ - mutex_lock(state->lock); -} +#define __v4l2_subdev_state_gen_call(NAME, _1, ARG, ...) \ + __v4l2_subdev_state_get_ ## NAME ## ARG /** - * v4l2_subdev_unlock_state() - Unlocks the subdev state - * @state: The subdevice state + * v4l2_subdev_state_get_format() - Get pointer to a stream format + * @state: subdevice state + * @pad: pad id + * @...: stream id (optional argument) * - * Unlocks the given subdev state. + * This returns a pointer to &struct v4l2_mbus_framefmt for the given pad + + * stream in the subdev state. + * + * For stream-unaware drivers the format for the corresponding pad is returned. + * If the pad does not exist, NULL is returned. */ -static inline void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state) -{ - mutex_unlock(state->lock); -} +/* + * Wrap v4l2_subdev_state_get_format(), allowing the function to be called with + * two or three arguments. The purpose of the __v4l2_subdev_state_get_format() + * macro below is to come up with the name of the function or macro to call, + * using the last two arguments (_stream and _pad). The selected function or + * macro is then called using the arguments specified by the caller. A similar + * arrangement is used for v4l2_subdev_state_crop() and + * v4l2_subdev_state_compose() below. + */ +#define v4l2_subdev_state_get_format(state, pad, ...) \ + __v4l2_subdev_state_gen_call(format, ##__VA_ARGS__, , _pad) \ + (state, pad, ##__VA_ARGS__) +#define __v4l2_subdev_state_get_format_pad(state, pad) \ + __v4l2_subdev_state_get_format(state, pad, 0) +struct v4l2_mbus_framefmt * +__v4l2_subdev_state_get_format(struct v4l2_subdev_state *state, + unsigned int pad, u32 stream); /** - * v4l2_subdev_get_unlocked_active_state() - Checks that the active subdev state - * is unlocked and returns it - * @sd: The subdevice + * v4l2_subdev_state_get_crop() - Get pointer to a stream crop rectangle + * @state: subdevice state + * @pad: pad id + * @...: stream id (optional argument) * - * 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. + * This returns a pointer to crop rectangle for the given pad + stream in the + * subdev state. * - * 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. + * For stream-unaware drivers the crop rectangle for the corresponding pad is + * returned. If the pad does not exist, NULL is returned. */ -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_state_get_crop(state, pad, ...) \ + __v4l2_subdev_state_gen_call(crop, ##__VA_ARGS__, , _pad) \ + (state, pad, ##__VA_ARGS__) +#define __v4l2_subdev_state_get_crop_pad(state, pad) \ + __v4l2_subdev_state_get_crop(state, pad, 0) +struct v4l2_rect * +__v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad, + u32 stream); /** - * v4l2_subdev_get_locked_active_state() - Checks that the active subdev state - * is locked and returns it - * - * @sd: The subdevice + * v4l2_subdev_state_get_compose() - Get pointer to a stream compose rectangle + * @state: subdevice state + * @pad: pad id + * @...: stream id (optional argument) * - * 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. + * This returns a pointer to compose rectangle for the given pad + stream in the + * subdev state. * - * This function is to be used when the caller knows that the active state is - * already locked. + * For stream-unaware drivers the compose rectangle for the corresponding pad is + * returned. If the pad does not exist, NULL is returned. */ -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_state_get_compose(state, pad, ...) \ + __v4l2_subdev_state_gen_call(compose, ##__VA_ARGS__, , _pad) \ + (state, pad, ##__VA_ARGS__) +#define __v4l2_subdev_state_get_compose_pad(state, pad) \ + __v4l2_subdev_state_get_compose(state, pad, 0) +struct v4l2_rect * +__v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state, + unsigned int pad, u32 stream); /** - * v4l2_subdev_lock_and_get_active_state() - Locks and returns the active subdev - * state for the subdevice - * @sd: The subdevice + * v4l2_subdev_state_get_interval() - Get pointer to a stream frame interval + * @state: subdevice state + * @pad: pad id + * @...: stream id (optional argument) * - * Returns the locked active state for the subdevice, or NULL if the subdev - * does not support active state. + * This returns a pointer to the frame interval for the given pad + stream in + * the subdev state. * - * The state must be unlocked with v4l2_subdev_unlock_state() after use. + * For stream-unaware drivers the frame interval for the corresponding pad is + * returned. If the pad does not exist, NULL is returned. */ -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_state_get_interval(state, pad, ...) \ + __v4l2_subdev_state_gen_call(interval, ##__VA_ARGS__, , _pad) \ + (state, pad, ##__VA_ARGS__) +#define __v4l2_subdev_state_get_interval_pad(state, pad) \ + __v4l2_subdev_state_get_interval(state, pad, 0) +struct v4l2_fract * +__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state, + unsigned int pad, u32 stream); #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) @@ -1494,6 +1436,24 @@ v4l2_subdev_lock_and_get_active_state(struct v4l2_subdev *sd) int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format); +/** + * v4l2_subdev_get_frame_interval() - Fill frame interval based on state + * @sd: subdevice + * @state: subdevice state + * @fi: pointer to &struct v4l2_subdev_frame_interval + * + * Fill @fi->interval field based on the information in the @fi struct. + * + * This function can be used by the subdev drivers which support active state to + * implement v4l2_subdev_pad_ops.get_frame_interval if the subdev driver does + * not need to do anything special in their get_frame_interval op. + * + * Returns 0 on success, error value otherwise. + */ +int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_interval *fi); + /** * v4l2_subdev_set_routing() - Set given routing to subdev state * @sd: The subdevice @@ -1539,52 +1499,6 @@ int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd, const struct v4l2_subdev_krouting *routing, const struct v4l2_mbus_framefmt *fmt); -/** - * v4l2_subdev_state_get_stream_format() - Get pointer to a stream format - * @state: subdevice state - * @pad: pad id - * @stream: stream id - * - * This returns a pointer to &struct v4l2_mbus_framefmt for the given pad + - * stream in the subdev state. - * - * If the state does not contain the given pad + stream, NULL is returned. - */ -struct v4l2_mbus_framefmt * -v4l2_subdev_state_get_stream_format(struct v4l2_subdev_state *state, - unsigned int pad, u32 stream); - -/** - * v4l2_subdev_state_get_stream_crop() - Get pointer to a stream crop rectangle - * @state: subdevice state - * @pad: pad id - * @stream: stream id - * - * This returns a pointer to crop rectangle for the given pad + stream in the - * subdev state. - * - * If the state does not contain the given pad + stream, NULL is returned. - */ -struct v4l2_rect * -v4l2_subdev_state_get_stream_crop(struct v4l2_subdev_state *state, - unsigned int pad, u32 stream); - -/** - * v4l2_subdev_state_get_stream_compose() - Get pointer to a stream compose - * rectangle - * @state: subdevice state - * @pad: pad id - * @stream: stream id - * - * This returns a pointer to compose rectangle for the given pad + stream in the - * subdev state. - * - * If the state does not contain the given pad + stream, NULL is returned. - */ -struct v4l2_rect * -v4l2_subdev_state_get_stream_compose(struct v4l2_subdev_state *state, - unsigned int pad, u32 stream); - /** * v4l2_subdev_routing_find_opposite_end() - Find the opposite stream * @routing: routing used to find the opposite side @@ -1786,6 +1700,89 @@ int v4l2_subdev_s_stream_helper(struct v4l2_subdev *sd, int enable); #endif /* CONFIG_MEDIA_CONTROLLER */ +/** + * v4l2_subdev_lock_state() - Locks the subdev state + * @state: The subdevice state + * + * Locks the given subdev state. + * + * The state must be unlocked with v4l2_subdev_unlock_state() after use. + */ +static inline void v4l2_subdev_lock_state(struct v4l2_subdev_state *state) +{ + mutex_lock(state->lock); +} + +/** + * v4l2_subdev_unlock_state() - Unlocks the subdev state + * @state: The subdevice state + * + * Unlocks the given subdev state. + */ +static inline void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state) +{ + mutex_unlock(state->lock); +} + +/** + * v4l2_subdev_get_unlocked_active_state() - Checks that the active subdev state + * is unlocked and returns it + * @sd: The subdevice + * + * 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. + * + * 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. + */ +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; +} + +/** + * v4l2_subdev_get_locked_active_state() - Checks that the active subdev state + * is locked and returns it + * + * @sd: The subdevice + * + * 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. + * + * This function is to be used when the caller knows that the active 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; +} + +/** + * v4l2_subdev_lock_and_get_active_state() - Locks and returns the active subdev + * state for the subdevice + * @sd: The subdevice + * + * Returns the locked active state for the subdevice, or NULL if the subdev + * does not support active state. + * + * 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; +} + /** * v4l2_subdev_init - initializes the sub-device struct * diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 4b6a9d2ea3..bec8c3a1ed 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -72,6 +72,10 @@ struct vb2_buffer; * argument to other ops in this structure. * @put_userptr: inform the allocator that a USERPTR buffer will no longer * be used. + * @prepare: called every time the buffer is passed from userspace to the + * driver, useful for cache synchronisation, optional. + * @finish: called every time the buffer is passed back from the driver + * to the userspace, also optional. * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation; * used for DMABUF memory types; dev is the alloc device * dbuf is the shared dma_buf; returns ERR_PTR() on failure; @@ -86,10 +90,6 @@ struct vb2_buffer; * dmabuf. * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified * that this driver is done using the dmabuf for now. - * @prepare: called every time the buffer is passed from userspace to the - * driver, useful for cache synchronisation, optional. - * @finish: called every time the buffer is passed back from the driver - * to the userspace, also optional. * @vaddr: return a kernel virtual address to a given memory buffer * associated with the passed private structure or NULL if no * such mapping exists. @@ -402,7 +402,7 @@ struct vb2_buffer { * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED. * If you need a minimum number of buffers before you can * start streaming, then set - * &vb2_queue->min_buffers_needed. If that is non-zero + * &vb2_queue->min_queued_buffers. If that is non-zero * then @start_streaming won't be called until at least * that many buffers have been queued up by userspace. * @stop_streaming: called when 'streaming' state must be disabled; driver @@ -484,7 +484,6 @@ struct vb2_buf_ops { * caller. For example, for V4L2, it should match * the types defined on &enum v4l2_buf_type. * @io_modes: supported io methods (see &enum vb2_io_modes). - * @alloc_devs: &struct device memory type/allocator-specific per-plane device * @dev: device to use for the default allocation context if the driver * doesn't fill in the @alloc_devs array. * @dma_attrs: DMA attributes to use for the DMA. @@ -546,10 +545,14 @@ struct vb2_buf_ops { * @gfp_flags: additional gfp flags used when allocating the buffers. * Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32 * to force the buffer allocation to a specific memory zone. - * @min_buffers_needed: the minimum number of buffers needed before + * @min_queued_buffers: the minimum number of queued buffers needed before * @start_streaming can be called. Used when a DMA engine * cannot be started unless at least this number of buffers * have been queued into the driver. + * VIDIOC_REQBUFS will ensure at least @min_queued_buffers + * buffers will be allocated. Note that VIDIOC_CREATE_BUFS will not + * modify the requested buffer count. + * @alloc_devs: &struct device memory type/allocator-specific per-plane device */ /* * Private elements (won't appear at the uAPI book): @@ -558,6 +561,9 @@ struct vb2_buf_ops { * @dma_dir: DMA mapping direction. * @bufs: videobuf2 buffer structures * @num_buffers: number of allocated/used buffers + * @max_num_buffers: upper limit of number of allocated/used buffers. + * If set to 0 v4l2 core will change it VB2_MAX_FRAME + * for backward compatibility. * @queued_list: list of buffers currently queued from userspace * @queued_count: number of buffers queued and ready for streaming. * @owned_by_drv_count: number of buffers owned by the driver @@ -571,6 +577,9 @@ struct vb2_buf_ops { * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for * buffers. Only set for capture queues if qbuf has not yet been * called since poll() needs to return %EPOLLERR in that situation. + * @waiting_in_dqbuf: set by the core for the duration of a blocking DQBUF, when + * it has to wait for a buffer to become available with vb2_queue->lock + * released. Used to prevent destroying the queue by other threads. * @is_multiplanar: set if buffer type is multiplanar * @is_output: set if buffer type is output * @copy_timestamp: set if vb2-core should set timestamps @@ -611,7 +620,7 @@ struct vb2_queue { unsigned int buf_struct_size; u32 timestamp_flags; gfp_t gfp_flags; - u32 min_buffers_needed; + u32 min_queued_buffers; struct device *alloc_devs[VB2_MAX_PLANES]; @@ -619,8 +628,9 @@ struct vb2_queue { struct mutex mmap_lock; unsigned int memory; enum dma_data_direction dma_dir; - struct vb2_buffer *bufs[VB2_MAX_FRAME]; + struct vb2_buffer **bufs; unsigned int num_buffers; + unsigned int max_num_buffers; struct list_head queued_list; unsigned int queued_count; @@ -747,7 +757,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q); /** * vb2_core_querybuf() - query video buffer information. * @q: pointer to &struct vb2_queue with videobuf2 queue. - * @index: id number of the buffer. + * @vb: pointer to struct &vb2_buffer. * @pb: buffer struct passed from userspace. * * Videobuf2 core helper to implement VIDIOC_QUERYBUF() operation. It is called @@ -759,7 +769,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q); * * Return: returns zero on success; an error code otherwise. */ -void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); +void vb2_core_querybuf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb); /** * vb2_core_reqbufs() - Initiate streaming. @@ -823,7 +833,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace * to the kernel. * @q: pointer to &struct vb2_queue with videobuf2 queue. - * @index: id number of the buffer. + * @vb: pointer to struct &vb2_buffer. * @pb: buffer structure passed from userspace to * &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver. * @@ -839,13 +849,13 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, * * Return: returns zero on success; an error code otherwise. */ -int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); +int vb2_core_prepare_buf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb); /** * vb2_core_qbuf() - Queue a buffer from userspace * * @q: pointer to &struct vb2_queue with videobuf2 queue. - * @index: id number of the buffer + * @vb: pointer to struct &vb2_buffer. * @pb: buffer structure passed from userspace to * v4l2_ioctl_ops->vidioc_qbuf handler in driver * @req: pointer to &struct media_request, may be NULL. @@ -867,7 +877,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); * * Return: returns zero on success; an error code otherwise. */ -int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, +int vb2_core_qbuf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb, struct media_request *req); /** @@ -931,7 +941,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); * @fd: pointer to the file descriptor associated with DMABUF * (set by driver). * @type: buffer type. - * @index: id number of the buffer. + * @vb: pointer to struct &vb2_buffer. * @plane: index of the plane to be exported, 0 for single plane queues * @flags: file flags for newly created file, as defined at * include/uapi/asm-generic/fcntl.h. @@ -945,7 +955,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); * Return: returns zero on success; an error code otherwise. */ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, - unsigned int index, unsigned int plane, unsigned int flags); + struct vb2_buffer *vb, unsigned int plane, unsigned int flags); /** * vb2_core_queue_init() - initialize a videobuf2 queue @@ -1139,6 +1149,15 @@ static inline bool vb2_fileio_is_active(struct vb2_queue *q) return q->fileio; } +/** + * vb2_get_num_buffers() - get the number of buffer in a queue + * @q: pointer to &struct vb2_queue with videobuf2 queue. + */ +static inline unsigned int vb2_get_num_buffers(struct vb2_queue *q) +{ + return q->num_buffers; +} + /** * vb2_is_busy() - return busy status of the queue. * @q: pointer to &struct vb2_queue with videobuf2 queue. @@ -1147,7 +1166,7 @@ static inline bool vb2_fileio_is_active(struct vb2_queue *q) */ static inline bool vb2_is_busy(struct vb2_queue *q) { - return (q->num_buffers > 0); + return vb2_get_num_buffers(q) > 0; } /** @@ -1239,6 +1258,12 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q) static inline struct vb2_buffer *vb2_get_buffer(struct vb2_queue *q, unsigned int index) { + if (!q->bufs) + return NULL; + + if (index >= q->max_num_buffers) + return NULL; + if (index < q->num_buffers) return q->bufs[index]; return NULL; -- cgit v1.2.3