diff options
Diffstat (limited to 'include/media')
-rw-r--r-- | include/media/cec.h | 4 | ||||
-rw-r--r-- | include/media/ipu-bridge.h | 1 | ||||
-rw-r--r-- | include/media/ipu6-pci-table.h | 28 | ||||
-rw-r--r-- | include/media/media-device.h | 6 | ||||
-rw-r--r-- | include/media/rc-map.h | 1 | ||||
-rw-r--r-- | include/media/tuner.h | 1 | ||||
-rw-r--r-- | include/media/v4l2-async.h | 4 | ||||
-rw-r--r-- | include/media/v4l2-device.h | 7 | ||||
-rw-r--r-- | include/media/v4l2-ioctl.h | 4 | ||||
-rw-r--r-- | include/media/v4l2-jpeg.h | 32 | ||||
-rw-r--r-- | include/media/v4l2-mem2mem.h | 2 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 160 | ||||
-rw-r--r-- | include/media/videobuf2-core.h | 52 | ||||
-rw-r--r-- | include/media/videobuf2-v4l2.h | 2 |
14 files changed, 252 insertions, 52 deletions
diff --git a/include/media/cec.h b/include/media/cec.h index 10c9cf6058b7..d131514032f2 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -173,7 +173,7 @@ struct cec_adap_ops { * case the transmit will finish, but will not retransmit * and be marked as ABORTED. * @xfer_timeout_ms: the transfer timeout in ms. - * If 0, then timeout after 2.1 ms. + * If 0, then timeout after 2100 ms. * @kthread_config: kthread used to configure a CEC adapter * @config_completion: used to signal completion of the config kthread * @kthread: main CEC processing thread @@ -187,6 +187,7 @@ struct cec_adap_ops { * in order to transmit or receive CEC messages. This is usually a HW * limitation. * @is_enabled: the CEC adapter is enabled + * @is_claiming_log_addrs: true if cec_claim_log_addrs() is running * @is_configuring: the CEC adapter is configuring (i.e. claiming LAs) * @must_reconfigure: while configuring, the PA changed, so reclaim LAs * @is_configured: the CEC adapter is configured (i.e. has claimed LAs) @@ -258,6 +259,7 @@ struct cec_adapter { u16 phys_addr; bool needs_hpd; bool is_enabled; + bool is_claiming_log_addrs; bool is_configuring; bool must_reconfigure; bool is_configured; diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h index 783bda6d5cc3..16fac765456e 100644 --- a/include/media/ipu-bridge.h +++ b/include/media/ipu-bridge.h @@ -3,6 +3,7 @@ #ifndef __IPU_BRIDGE_H #define __IPU_BRIDGE_H +#include <linux/mod_devicetable.h> #include <linux/property.h> #include <linux/types.h> #include <media/v4l2-fwnode.h> diff --git a/include/media/ipu6-pci-table.h b/include/media/ipu6-pci-table.h new file mode 100644 index 000000000000..0899d9d2f978 --- /dev/null +++ b/include/media/ipu6-pci-table.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Intel Corporation + */ + +#ifndef __IPU6_PCI_TBL_H__ +#define __IPU6_PCI_TBL_H__ + +#include <linux/pci.h> + +#define PCI_DEVICE_ID_INTEL_IPU6 0x9a19 +#define PCI_DEVICE_ID_INTEL_IPU6SE 0x4e19 +#define PCI_DEVICE_ID_INTEL_IPU6EP_ADLP 0x465d +#define PCI_DEVICE_ID_INTEL_IPU6EP_ADLN 0x462e +#define PCI_DEVICE_ID_INTEL_IPU6EP_RPLP 0xa75d +#define PCI_DEVICE_ID_INTEL_IPU6EP_MTL 0x7d19 + +static const struct pci_device_id ipu6_pci_tbl[] = { + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6SE) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_ADLP) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_ADLN) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_RPLP) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_MTL) }, + { } +}; + +#endif /* __IPU6_PCI_TBL_H__ */ diff --git a/include/media/media-device.h b/include/media/media-device.h index 2c146d0b2b1c..53d2a16a70b0 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -429,6 +429,9 @@ void __media_device_usb_init(struct media_device *mdev, const char *driver_name); #else +static inline void media_device_init(struct media_device *mdev) +{ +} static inline int media_device_register(struct media_device *mdev) { return 0; @@ -436,6 +439,9 @@ static inline int media_device_register(struct media_device *mdev) static inline void media_device_unregister(struct media_device *mdev) { } +static inline void media_device_cleanup(struct media_device *mdev) +{ +} static inline int media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 4676545ffd8f..4867eb2f931e 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -290,6 +290,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_MSI_DIGIVOX_III "rc-msi-digivox-iii" #define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere" #define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus" +#define RC_MAP_MYGICA_UTV3 "rc-mygica-utv3" #define RC_MAP_NEBULA "rc-nebula" #define RC_MAP_NEC_TERRATEC_CINERGY_XS "rc-nec-terratec-cinergy-xs" #define RC_MAP_NORWOOD "rc-norwood" diff --git a/include/media/tuner.h b/include/media/tuner.h index a7796e0a3659..c5fd6faabfd6 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -133,6 +133,7 @@ #define TUNER_SONY_BTF_PK467Z 90 /* NTSC_JP */ #define TUNER_SONY_BTF_PB463Z 91 /* NTSC */ #define TUNER_SI2157 92 +#define TUNER_TENA_TNF_931D_DFDR1 93 /* tv card specific */ #define TDA9887_PRESENT (1<<0) diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 9bd326d31181..f26c323e9c96 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -310,7 +310,9 @@ void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier); * * @sd: pointer to &struct v4l2_subdev */ -int v4l2_async_register_subdev(struct v4l2_subdev *sd); +#define v4l2_async_register_subdev(sd) \ + __v4l2_async_register_subdev(sd, THIS_MODULE) +int __v4l2_async_register_subdev(struct v4l2_subdev *sd, struct module *module); /** * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index f6f111fae33c..dd897a362f36 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -156,8 +156,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); * An error is returned if the module is no longer loaded on any attempts * to register it. */ -int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, - struct v4l2_subdev *sd); +#define v4l2_device_register_subdev(v4l2_dev, sd) \ + __v4l2_device_register_subdev(v4l2_dev, sd, THIS_MODULE) +int __must_check __v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd, + struct module *module); /** * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device. diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index edb733f21604..bdbb7e542321 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -163,6 +163,8 @@ struct v4l2_fh; * :ref:`VIDIOC_CREATE_BUFS <vidioc_create_bufs>` ioctl * @vidioc_prepare_buf: pointer to the function that implements * :ref:`VIDIOC_PREPARE_BUF <vidioc_prepare_buf>` ioctl + * @vidioc_remove_bufs: pointer to the function that implements + * :ref:`VIDIOC_REMOVE_BUFS <vidioc_remove_bufs>` ioctl * @vidioc_overlay: pointer to the function that implements * :ref:`VIDIOC_OVERLAY <vidioc_overlay>` ioctl * @vidioc_g_fbuf: pointer to the function that implements @@ -422,6 +424,8 @@ struct v4l2_ioctl_ops { struct v4l2_create_buffers *b); int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b); + int (*vidioc_remove_bufs)(struct file *file, void *fh, + struct v4l2_remove_buffers *d); int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i); int (*vidioc_g_fbuf)(struct file *file, void *fh, diff --git a/include/media/v4l2-jpeg.h b/include/media/v4l2-jpeg.h index 2dba843ce3bd..b65658a02e3c 100644 --- a/include/media/v4l2-jpeg.h +++ b/include/media/v4l2-jpeg.h @@ -14,6 +14,30 @@ #define V4L2_JPEG_MAX_COMPONENTS 4 #define V4L2_JPEG_MAX_TABLES 4 +/* + * Prefixes used to generate huffman table class and destination identifiers as + * described below: + * + * V4L2_JPEG_LUM_HT | V4L2_JPEG_DC_HT : Prefix for Luma DC coefficients + * huffman table + * V4L2_JPEG_LUM_HT | V4L2_JPEG_AC_HT : Prefix for Luma AC coefficients + * huffman table + * V4L2_JPEG_CHR_HT | V4L2_JPEG_DC_HT : Prefix for Chroma DC coefficients + * huffman table + * V4L2_JPEG_CHR_HT | V4L2_JPEG_AC_HT : Prefix for Chroma AC coefficients + * huffman table + */ +#define V4L2_JPEG_LUM_HT 0x00 +#define V4L2_JPEG_CHR_HT 0x01 +#define V4L2_JPEG_DC_HT 0x00 +#define V4L2_JPEG_AC_HT 0x10 + +/* Length of reference huffman tables as provided in Table K.3 of ITU-T.81 */ +#define V4L2_JPEG_REF_HT_AC_LEN 178 +#define V4L2_JPEG_REF_HT_DC_LEN 28 + +/* Array size for 8x8 block of samples or DCT coefficient */ +#define V4L2_JPEG_PIXELS_IN_BLOCK 64 /** * struct v4l2_jpeg_reference - reference into the JPEG buffer @@ -154,4 +178,12 @@ int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision, int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len, struct v4l2_jpeg_reference *huffman_tables); +extern const u8 v4l2_jpeg_zigzag_scan_index[V4L2_JPEG_PIXELS_IN_BLOCK]; +extern const u8 v4l2_jpeg_ref_table_luma_qt[V4L2_JPEG_PIXELS_IN_BLOCK]; +extern const u8 v4l2_jpeg_ref_table_chroma_qt[V4L2_JPEG_PIXELS_IN_BLOCK]; +extern const u8 v4l2_jpeg_ref_table_luma_dc_ht[V4L2_JPEG_REF_HT_DC_LEN]; +extern const u8 v4l2_jpeg_ref_table_luma_ac_ht[V4L2_JPEG_REF_HT_AC_LEN]; +extern const u8 v4l2_jpeg_ref_table_chroma_dc_ht[V4L2_JPEG_REF_HT_DC_LEN]; +extern const u8 v4l2_jpeg_ref_table_chroma_ac_ht[V4L2_JPEG_REF_HT_AC_LEN]; + #endif diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 7f1af1f7f912..0af330cf91c3 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -867,6 +867,8 @@ int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb); int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh, struct v4l2_create_buffers *create); +int v4l2_m2m_ioctl_remove_bufs(struct file *file, void *priv, + struct v4l2_remove_buffers *d); int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf); int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh, diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index a9e6b8146279..bd235d325ff9 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -450,15 +450,16 @@ enum v4l2_subdev_pre_streamon_flags { * already started or stopped subdev. Also see call_s_stream wrapper in * v4l2-subdev.c. * - * @g_pixelaspect: callback to return the pixelaspect ratio. - * - * @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. + * New drivers should instead implement &v4l2_subdev_pad_ops.enable_streams + * and &v4l2_subdev_pad_ops.disable_streams operations, and use + * v4l2_subdev_s_stream_helper for the &v4l2_subdev_video_ops.s_stream + * operation to support legacy users. * - * @g_dv_timings: Get custom dv timings in the sub device. + * Drivers should also not call the .s_stream() subdev operation directly, + * but use the v4l2_subdev_enable_streams() and + * v4l2_subdev_disable_streams() helpers. * - * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code. + * @g_pixelaspect: callback to return the pixelaspect ratio. * * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev * can adjust @size to a lower value and must not write more data to the @@ -490,12 +491,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 (*s_dv_timings)(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings); - int (*g_dv_timings)(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings); - int (*query_dv_timings)(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings); int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, unsigned int *size); int (*pre_streamon)(struct v4l2_subdev *sd, u32 flags); @@ -695,7 +690,7 @@ struct v4l2_subdev_pad_config { * * @pad: pad number * @stream: stream number - * @enabled: has the stream been enabled with v4l2_subdev_enable_stream() + * @enabled: has the stream been enabled with v4l2_subdev_enable_streams() * @fmt: &struct v4l2_mbus_framefmt * @crop: &struct v4l2_rect to be used for crop * @compose: &struct v4l2_rect to be used for compose @@ -728,12 +723,14 @@ struct v4l2_subdev_stream_configs { /** * struct v4l2_subdev_krouting - subdev routing table * + * @len_routes: length of routes array, in routes * @num_routes: number of routes * @routes: &struct v4l2_subdev_route * * This structure contains the routing table for a subdev. */ struct v4l2_subdev_krouting { + unsigned int len_routes; unsigned int num_routes; struct v4l2_subdev_route *routes; }; @@ -791,6 +788,14 @@ struct v4l2_subdev_state { * * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() 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. + * + * @g_dv_timings: Get custom dv timings in the sub device. + * + * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code. + * * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler * code. * @@ -864,6 +869,12 @@ struct v4l2_subdev_pad_ops { 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 (*s_dv_timings)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_dv_timings *timings); + int (*g_dv_timings)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_dv_timings *timings); + int (*query_dv_timings)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_dv_timings *timings); int (*dv_timings_cap)(struct v4l2_subdev *sd, struct v4l2_dv_timings_cap *cap); int (*enum_dv_timings)(struct v4l2_subdev *sd, @@ -1039,10 +1050,11 @@ struct v4l2_subdev_platform_data { * @active_state: Active state for the subdev (NULL for subdevs tracking the * state internally). Initialized by calling * v4l2_subdev_init_finalize(). - * @enabled_streams: Bitmask of enabled streams used by - * v4l2_subdev_enable_streams() and - * v4l2_subdev_disable_streams() helper functions for fallback - * cases. + * @enabled_pads: Bitmask of enabled pads used by v4l2_subdev_enable_streams() + * and v4l2_subdev_disable_streams() helper functions for + * fallback cases. + * @s_stream_enabled: Tracks whether streaming has been enabled with s_stream. + * This is only for call_s_stream() internal use. * * Each instance of a subdev driver should create this struct, either * stand-alone or embedded in a larger struct. @@ -1090,7 +1102,8 @@ struct v4l2_subdev { * doesn't support it. */ struct v4l2_subdev_state *active_state; - u64 enabled_streams; + u64 enabled_pads; + bool s_stream_enabled; }; @@ -1324,6 +1337,16 @@ void v4l2_subdev_cleanup(struct v4l2_subdev *sd); #define __v4l2_subdev_state_gen_call(NAME, _1, ARG, ...) \ __v4l2_subdev_state_get_ ## NAME ## ARG +/* + * A macro to constify the return value of the state accessors when the state + * parameter is const. + */ +#define __v4l2_subdev_state_constify_ret(state, value) \ + _Generic(state, \ + const struct v4l2_subdev_state *: (const typeof(*(value)) *)(value), \ + struct v4l2_subdev_state *: (value) \ + ) + /** * v4l2_subdev_state_get_format() - Get pointer to a stream format * @state: subdevice state @@ -1338,16 +1361,21 @@ void v4l2_subdev_cleanup(struct v4l2_subdev *sd); */ /* * 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__) + * two or three arguments. The purpose of the __v4l2_subdev_state_gen_call() + * macro 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. The + * __v4l2_subdev_state_constify_ret() macro constifies the returned pointer + * when the state is const, allowing the state accessors to guarantee + * const-correctness in all cases. + * + * A similar arrangement is used for v4l2_subdev_state_crop(), + * v4l2_subdev_state_compose() and v4l2_subdev_state_get_interval() below. + */ +#define v4l2_subdev_state_get_format(state, pad, ...) \ + __v4l2_subdev_state_constify_ret(state, \ + __v4l2_subdev_state_gen_call(format, ##__VA_ARGS__, , _pad) \ + ((struct v4l2_subdev_state *)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 * @@ -1366,9 +1394,10 @@ __v4l2_subdev_state_get_format(struct v4l2_subdev_state *state, * For stream-unaware drivers the crop rectangle for the corresponding pad is * returned. If the pad does not exist, NULL is returned. */ -#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(state, pad, ...) \ + __v4l2_subdev_state_constify_ret(state, \ + __v4l2_subdev_state_gen_call(crop, ##__VA_ARGS__, , _pad) \ + ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__)) #define __v4l2_subdev_state_get_crop_pad(state, pad) \ __v4l2_subdev_state_get_crop(state, pad, 0) struct v4l2_rect * @@ -1387,9 +1416,10 @@ __v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad, * For stream-unaware drivers the compose rectangle for the corresponding pad is * returned. If the pad does not exist, NULL is returned. */ -#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(state, pad, ...) \ + __v4l2_subdev_state_constify_ret(state, \ + __v4l2_subdev_state_gen_call(compose, ##__VA_ARGS__, , _pad) \ + ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__)) #define __v4l2_subdev_state_get_compose_pad(state, pad) \ __v4l2_subdev_state_get_compose(state, pad, 0) struct v4l2_rect * @@ -1408,9 +1438,10 @@ __v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state, * For stream-unaware drivers the frame interval for the corresponding pad is * returned. If the pad does not exist, NULL is returned. */ -#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(state, pad, ...) \ + __v4l2_subdev_state_constify_ret(state, \ + __v4l2_subdev_state_gen_call(interval, ##__VA_ARGS__, , _pad) \ + ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__)) #define __v4l2_subdev_state_get_interval_pad(state, pad) \ __v4l2_subdev_state_get_interval(state, pad, 0) struct v4l2_fract * @@ -1725,6 +1756,46 @@ static inline void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state) } /** + * v4l2_subdev_lock_states - Lock two sub-device states + * @state1: One subdevice state + * @state2: The other subdevice state + * + * Locks the state of two sub-devices. + * + * The states must be unlocked with v4l2_subdev_unlock_states() after use. + * + * This differs from calling v4l2_subdev_lock_state() on both states so that if + * the states share the same lock, the lock is acquired only once (so no + * deadlock occurs). The caller is responsible for ensuring the locks will + * always be acquired in the same order. + */ +static inline void v4l2_subdev_lock_states(struct v4l2_subdev_state *state1, + struct v4l2_subdev_state *state2) +{ + mutex_lock(state1->lock); + if (state1->lock != state2->lock) + mutex_lock(state2->lock); +} + +/** + * v4l2_subdev_unlock_states() - Unlock two sub-device states + * @state1: One subdevice state + * @state2: The other subdevice state + * + * Unlocks the state of two sub-devices. + * + * This differs from calling v4l2_subdev_unlock_state() on both states so that + * if the states share the same lock, the lock is released only once. + */ +static inline void v4l2_subdev_unlock_states(struct v4l2_subdev_state *state1, + struct v4l2_subdev_state *state2) +{ + mutex_unlock(state1->lock); + if (state1->lock != state2->lock) + mutex_unlock(state2->lock); +} + +/** * v4l2_subdev_get_unlocked_active_state() - Checks that the active subdev state * is unlocked and returns it * @sd: The subdevice @@ -1912,4 +1983,17 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers; void v4l2_subdev_notify_event(struct v4l2_subdev *sd, const struct v4l2_event *ev); +/** + * v4l2_subdev_is_streaming() - Returns if the subdevice is streaming + * @sd: The subdevice + * + * v4l2_subdev_is_streaming() tells if the subdevice is currently streaming. + * "Streaming" here means whether .s_stream() or .enable_streams() has been + * successfully called, and the streaming has not yet been disabled. + * + * If the subdevice implements .enable_streams() this function must be called + * while holding the active state lock. + */ +bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd); + #endif /* _V4L2_SUBDEV_H */ diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 8b86996b2719..955237ac503d 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -346,8 +346,8 @@ struct vb2_buffer { * describes the requested number of planes and sizes\[\] * contains the requested plane sizes. In this case * \*num_buffers are being allocated additionally to - * q->num_buffers. If either \*num_planes or the requested - * sizes are invalid callback must return %-EINVAL. + * 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 @@ -549,9 +549,21 @@ struct vb2_buf_ops { * @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 + * VIDIOC_REQBUFS will ensure at least @min_queued_buffers + 1 * buffers will be allocated. Note that VIDIOC_CREATE_BUFS will not * modify the requested buffer count. + * @min_reqbufs_allocation: the minimum number of buffers to be allocated when + * calling VIDIOC_REQBUFS. Note that VIDIOC_CREATE_BUFS will *not* + * modify the requested buffer count and does not use this field. + * Drivers can set this if there has to be a certain number of + * buffers available for the hardware to work effectively. + * This allows calling VIDIOC_REQBUFS with a buffer count of 1 and + * it will be automatically adjusted to a workable buffer count. + * If set, then @min_reqbufs_allocation must be larger than + * @min_queued_buffers + 1. + * If this field is > 3, then it is highly recommended that the + * driver implements the V4L2_CID_MIN_BUFFERS_FOR_CAPTURE/OUTPUT + * control. * @alloc_devs: &struct device memory type/allocator-specific per-plane device */ /* @@ -559,8 +571,9 @@ struct vb2_buf_ops { * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped * @memory: current memory type used * @dma_dir: DMA mapping direction. - * @bufs: videobuf2 buffer structures - * @num_buffers: number of allocated/used buffers + * @bufs: videobuf2 buffer structures. If it is non-NULL then + * bufs_bitmap is also non-NULL. + * @bufs_bitmap: bitmap tracking whether each bufs[] entry is used * @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. @@ -582,6 +595,7 @@ struct vb2_buf_ops { * 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 + * @is_busy: set if at least one buffer has been allocated at some time. * @copy_timestamp: set if vb2-core should set timestamps * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the * last decoded buffer was already dequeued. Set for capture queues @@ -621,6 +635,7 @@ struct vb2_queue { u32 timestamp_flags; gfp_t gfp_flags; u32 min_queued_buffers; + u32 min_reqbufs_allocation; struct device *alloc_devs[VB2_MAX_PLANES]; @@ -629,7 +644,7 @@ struct vb2_queue { unsigned int memory; enum dma_data_direction dma_dir; struct vb2_buffer **bufs; - unsigned int num_buffers; + unsigned long *bufs_bitmap; unsigned int max_num_buffers; struct list_head queued_list; @@ -647,6 +662,7 @@ struct vb2_queue { unsigned int waiting_in_dqbuf:1; unsigned int is_multiplanar:1; unsigned int is_output:1; + unsigned int is_busy:1; unsigned int copy_timestamp:1; unsigned int last_buffer_dequeued:1; @@ -811,6 +827,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, * @count: requested buffer count. * @requested_planes: number of planes requested. * @requested_sizes: array with the size of the planes. + * @first_index: index of the first created buffer, all allocated buffers have + * indices in the range [first_index..first_index+count-1] * * Videobuf2 core helper to implement VIDIOC_CREATE_BUFS() operation. It is * called internally by VB2 by an API-specific handler, like @@ -827,7 +845,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int flags, unsigned int *count, unsigned int requested_planes, - const unsigned int requested_sizes[]); + const unsigned int requested_sizes[], + unsigned int *first_index); /** * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace @@ -852,6 +871,16 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, int vb2_core_prepare_buf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb); /** + * vb2_core_remove_bufs() - + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @start: first index of the range of buffers to remove. + * @count: number of buffers to remove. + * + * Return: returns zero on success; an error code otherwise. + */ +int vb2_core_remove_bufs(struct vb2_queue *q, unsigned int start, unsigned int count); + +/** * vb2_core_qbuf() - Queue a buffer from userspace * * @q: pointer to &struct vb2_queue with videobuf2 queue. @@ -1155,7 +1184,10 @@ static inline bool vb2_fileio_is_active(struct vb2_queue *q) */ static inline unsigned int vb2_get_num_buffers(struct vb2_queue *q) { - return q->num_buffers; + if (q->bufs_bitmap) + return bitmap_weight(q->bufs_bitmap, q->max_num_buffers); + + return 0; } /** @@ -1166,7 +1198,7 @@ static inline unsigned int vb2_get_num_buffers(struct vb2_queue *q) */ static inline bool vb2_is_busy(struct vb2_queue *q) { - return vb2_get_num_buffers(q) > 0; + return !!q->is_busy; } /** @@ -1264,7 +1296,7 @@ static inline struct vb2_buffer *vb2_get_buffer(struct vb2_queue *q, if (index >= q->max_num_buffers) return NULL; - if (index < q->num_buffers) + if (test_bit(index, q->bufs_bitmap)) return q->bufs[index]; return NULL; } diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 5a845887850b..77ce8238ab30 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -334,6 +334,8 @@ int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i); int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i); int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p); +int vb2_ioctl_remove_bufs(struct file *file, void *priv, + struct v4l2_remove_buffers *p); /* struct v4l2_file_operations helpers */ |