cron job: media_tree daily build: ERRORS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Sat Aug 5 05:00:16 CEST 2017 media-tree git hash:da48c948c263c9d87dfc64566b3373a858cc8aa2 media_build git hash: f01a9176bb03f22e3cd3b70282bd7fd272e504ae v4l-utils git hash: 4e234b854f194eb118b476e0c76b56e4af89d5ff gcc version:i686-linux-gcc (GCC) 7.1.0 sparse version: v0.5.0 smatch version: v0.5.0-3553-g78b2ea6 host hardware: x86_64 host os:4.11.0-164 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-multi: WARNINGS linux-git-arm-pxa: OK linux-git-arm-stm32: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.36.4-i686: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-3.0.60-i686: WARNINGS linux-3.1.10-i686: WARNINGS linux-3.2.37-i686: WARNINGS linux-3.3.8-i686: WARNINGS linux-3.4.27-i686: ERRORS linux-3.5.7-i686: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.8-i686: WARNINGS linux-3.9.2-i686: WARNINGS linux-3.10.1-i686: WARNINGS linux-3.11.1-i686: WARNINGS linux-3.12.67-i686: WARNINGS linux-3.13.11-i686: WARNINGS linux-3.14.9-i686: WARNINGS linux-3.15.2-i686: WARNINGS linux-3.16.7-i686: WARNINGS linux-3.17.8-i686: ERRORS linux-3.18.7-i686: ERRORS linux-3.19-i686: WARNINGS linux-4.0.9-i686: WARNINGS linux-4.1.33-i686: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.3.6-i686: WARNINGS linux-4.4.22-i686: WARNINGS linux-4.5.7-i686: WARNINGS linux-4.6.7-i686: WARNINGS linux-4.7.5-i686: WARNINGS linux-4.8-i686: OK linux-4.9.26-i686: OK linux-4.10.14-i686: OK linux-4.11-i686: OK linux-4.12.1-i686: OK linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.37-x86_64: WARNINGS linux-3.3.8-x86_64: WARNINGS linux-3.4.27-x86_64: ERRORS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-x86_64: WARNINGS linux-3.10.1-x86_64: WARNINGS linux-3.11.1-x86_64: WARNINGS linux-3.12.67-x86_64: WARNINGS linux-3.13.11-x86_64: WARNINGS linux-3.14.9-x86_64: WARNINGS linux-3.15.2-x86_64: WARNINGS linux-3.16.7-x86_64: WARNINGS linux-3.17.8-x86_64: WARNINGS linux-3.18.7-x86_64: WARNINGS linux-3.19-x86_64: WARNINGS linux-4.0.9-x86_64: WARNINGS linux-4.1.33-x86_64: WARNINGS linux-4.2.8-x86_64: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.22-x86_64: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-x86_64: WARNINGS linux-4.7.5-x86_64: WARNINGS linux-4.8-x86_64: WARNINGS linux-4.9.26-x86_64: WARNINGS linux-4.10.14-x86_64: WARNINGS linux-4.11-x86_64: WARNINGS linux-4.12.1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Saturday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Saturday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html
[PATCH] imon: constify attribute_group structures
Functions working with attribute_groups provided by work with const attribute_group. These attribute_group structures do not change at runtime so mark them as const. File size before: text data bss dec hex filename 3698116776 960 54717d5bd drivers/media/rc/imon.o File size after: text data bss dec hex filename 3717316584 960 54717d5bd drivers/media/rc/imon.o This change was made with the help of Coccinelle. Signed-off-by: Amitoj Kaur Chawla--- drivers/media/rc/imon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index bd76534..717ba78 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -911,7 +911,7 @@ static struct attribute *imon_display_sysfs_entries[] = { NULL }; -static struct attribute_group imon_display_attr_group = { +static const struct attribute_group imon_display_attr_group = { .attrs = imon_display_sysfs_entries }; @@ -920,7 +920,7 @@ static struct attribute *imon_rf_sysfs_entries[] = { NULL }; -static struct attribute_group imon_rf_attr_group = { +static const struct attribute_group imon_rf_attr_group = { .attrs = imon_rf_sysfs_entries }; -- 2.7.4
[GIT PULL] linux-firmware: intel: Add Kabylake IPU3 firmware
Hi, Please review this PULL request to add Kabylake IPU3 firmware to the linux-firmware repository. The following changes since commit 7d2c913dcd1be083350d97a8cb1eba24cfacbc8a: ath10k: update year in license (2017-06-22 12:06:02 -0700) are available in the git repository at: https://github.com/RajmohanMani/linux-firmware.git tags/v1 for you to fetch changes up to 2c27b0cb02f18c022d8378e0e1abaf8b7ae8188f: linux-firmware: intel: Add Kabylake IPU3 firmware (2017-08-04 15:53:13 -0700) IPU3 firmware version irci_irci_ecr-master_20161208_0213_20170112_1500 Rajmohan Mani (1): linux-firmware: intel: Add Kabylake IPU3 firmware LICENSE.ipu3_firmware | 36 WHENCE | 11 +++ intel/ipu3-fw.bin | 1 + intel/irci_irci_ecr-master_20161208_0213_20170112_1500.bin | Bin 0 -> 1212984 bytes 4 files changed, 48 insertions(+) create mode 100644 LICENSE.ipu3_firmware create mode 12 intel/ipu3-fw.bin create mode 100644 intel/irci_irci_ecr-master_20161208_0213_20170112_1500.bin Thanks Raj
[PATCH v7] media: platform: Renesas IMR driver
The image renderer, or the distortion correction engine, is a drawing processor with a simple instruction system capable of referencing video capture data or data in an external memory as the 2D texture data and performing texture mapping and drawing with respect to any shape that is split into triangular objects. This V4L2 memory-to-memory device driver only supports image renderer light extended 4 (IMR-LX4) found in the R-Car gen3 SoCs; the R-Car gen2 support can be added later... Based on the original patch by Konstantin Kozhevnikov. Signed-off-by: Konstantin KozhevnikovSigned-off-by: Sergei Shtylyov Acked-by: Rob Herring --- The patch is against the 'media_tree.git' repo's 'master' branch. Changes in version 7: - switched to using 'v4l2_fh::m2m_ctx' which permitted using v4l2_m2m_fop_{poll| mmap} instead of imr_{poll|mmap}(); - moved the configuration check from imr_qbuf() to imr_buf_prepare(), replacing the former with v4l2_m2m_ioctl_qbuf(); - renamed imr_cfg_[un]ref() to imr_cfg_{get|put}(); - removed VB2_USERPTR from imr_queue_init(); - removed V4L2_CAP_VIDEO_{CAPTURE|OUTPUT} device capabilities; - replaced "luminance" with "luma" and "chrominance" with "chroma" in the driver and UAPI header comments; - fixed typo in the email address in MODULE_AUTHOR(); - added the vertex-related structures to the UAPI header; - replaced the '__packed' annotations with explicit __attribute__((packed)) in the UAPI header; - fixed/clarified the comments in the UAPI header; - added the dependence table for the vertex object variants in the driver document; - added the description of the luma/chroma correction in the driver document; - added the mesh construction code example to the driver document; - removed the fragments effectively duplicating the UAPI hearder comments in the driver document, referring a reader to that header instead; - clarified the use of the auto-generated source/destination coordinates in the driver document; - marked up the references to the code in the driver document; - fixed typo/wording in the driver document; - removed the main text indentation in the driver document; - changed the patch authorship to mine; - added Rob Herring's ACK. Changes in version 6: - fixed the bug where if imr_cfg_create() fails, 'ctx->cfg' wasn't set to NULL and so wouldn't fail the validity checks; - fixed the height minimum/alignment passed to v4l_bound_align_image(); - removed the buggy !V4L2_TYPE_IS_OUTPUT() check from imr_qbuf(); - added the driver UAPI documentation; - replaced 'imr_ctx::crop' array with the 'imr_ctx::rect' structure; - replaced imr_{g|s}_crop() with imr_{g|s}_selection(); - removed 'imr_format_info::name' and the related code; - completely rewrote imr_queue_setup(); - moved the applicable code from imr_buf_queue() to imr_buf_prepare(), moved the rest of imr_buf_queue() after imr_buf_finish(); - removed imr_start_streaming(); - assigned 'src_vq->dev' and 'dst_vq->dev' in imr_queue_init(); - clarified the math in imt_tri_type_{a|b|c}_length(); - removed useless local variables, added useful variables, avoided casts to 'void *', and clarified the pointer math in imr_tri_set_type_{a|b|c}(); - replaced kmalloc()/copy_from_user() calls with memdup_user() call; - moved the 'type' variable assignment in imr_ioctl_map() after the following comment; - merged the matrix size checks for the cases of the automatic generation pattern and the absolute coordinates in imr_ioctl_map(); - swapped the operands in the VBO size check in imr_ioctl_map(); - moved setting device capabilities from imr_querycap() to imr_probe(); - replaced imr_{reqbufs|querybuf|dqbuf|expbuf|streamon|streamoff}() with the generic helpers, implemented vidioc_{create_bufs|prepare_buf}() methods; - set the valid default queue pixel format in imr_probe(); - used tabs for indentation where possible in imr_probe(); - removed the rest of the *inline* keywords; - declared 'imr_map_desc::data' as '__u64' instead of 'void *'; - switched to '__u{16|32}' instead of 'u{16|32}' in the UAPI header; - spelled out the VBO abbreviation and removed redundancy in the UAPI header comments. Changes in version 5: - used ALIGN() macro in imr_ioctl_map(); - moved the display list #define's after the register #define's, removing the redundant comment; - uppercased the "tbd" abbreviation in the comments; - made the TRI instruction types A/B/C named consistently; - avoided quotes around the coordinate's names; - avoided some hyphens in the comments; - removed spaces around / and before ? in the comments; - reworded some comments; - reformatted some multiline comments; - fixed typos in the comments. Changes in version 4: - added/used the SUSR fields/shifts. Changes in version 3: - added/used the {UV|CP}DPOR fields/shifts; - removed unsupported LINE instruction; - replaced '*' with 'x' in the string passed to v4l2_dbg()
Re: [PATCH v4 0/7] vsp1 partition algorithm improvements
Hi Kieran, On Friday 04 Aug 2017 17:32:37 Kieran Bingham wrote: > Hans, this series should be ready for integration now. Could you pick up > these patches please? Just a note for Hans: the series merges cleanly with Dave's drm-next branch (git://people.freedesktop.org/~airlied/linux) that contains a large series of VSP patches. There should thus be no merge conflict (at least none that git won't solve automatically) when merging upstream. > Some updates and initial improvements for the VSP1 partition algorithm that > remove redundant processing and variables, reducing the processing done in > interrupt context slightly. > > Patch 1, fixes up a bug to release buffers back to vb2 if errors occur in > vsp1_video_start_streaming() > > Patches 2, 3 and 4 clean up the calculation of the partition windows such > that they are only calculated once at streamon. > > Patch 5 improves the allocations with a new vsp1_partition object to track > each window state. > > Patches 6, and 7 then go on to enhance the partition algorithm by allowing > each entity to calculate the requirements for it's pipeline predecessor to > successfully generate the requested output window. This system allows the > entity objects to specify what they need to fulfil the output for the next > entity in the pipeline. > > v2: > - Rebased to v4.12-rc1 > - Partition tables dynamically allocated > - review fixups > > v3: > - Review fixes and changes from Laurent > - v4l: vsp1: Release buffers in start_streaming error path > > v4: > - (Final) fixups from Laurent's review, and picked up his reviewed-by tags. > > Kieran Bingham (7): > v4l: vsp1: Release buffers in start_streaming error path > v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function > v4l: vsp1: Calculate partition sizes at stream start > v4l: vsp1: Remove redundant context variables > v4l: vsp1: Move partition rectangles to struct and operate directly > v4l: vsp1: Provide UDS register updates > v4l: vsp1: Allow entities to participate in the partition algorithm > > drivers/media/platform/vsp1/vsp1_entity.h | 7 +- > drivers/media/platform/vsp1/vsp1_pipe.c | 22 +++- > drivers/media/platform/vsp1/vsp1_pipe.h | 46 +- > drivers/media/platform/vsp1/vsp1_regs.h | 14 ++- > drivers/media/platform/vsp1/vsp1_rpf.c| 27 +-- > drivers/media/platform/vsp1/vsp1_sru.c| 26 +++- > drivers/media/platform/vsp1/vsp1_uds.c| 57 ++- > drivers/media/platform/vsp1/vsp1_video.c | 182 --- > drivers/media/platform/vsp1/vsp1_wpf.c| 24 ++- > 9 files changed, 289 insertions(+), 116 deletions(-) > > base-commit: 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 -- Regards, Laurent Pinchart
[PATCH v4 5/7] v4l: vsp1: Move partition rectangles to struct and operate directly
As we develop the partition algorithm, we need to store more information per partition to describe the phase and other parameters. To keep this data together, further abstract the existing v4l2_rect into a partition specific structure. As partitions only have horizontal coordinates, store the left and width values only. When generating the partition windows, operate directly on the partition struct rather than copying and duplicating the processed data Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 15 +++-- drivers/media/platform/vsp1/vsp1_rpf.c | 4 +- drivers/media/platform/vsp1/vsp1_uds.c | 18 +- drivers/media/platform/vsp1/vsp1_video.c | 43 +++-- drivers/media/platform/vsp1/vsp1_wpf.c | 14 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 9653ef5cfb0c..4e9fd96108be 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -58,6 +58,17 @@ enum vsp1_pipeline_state { }; /* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @left: horizontal coordinate of the partition start in pixels relative to the + * left edge of the image + * @width: partition width in pixels + */ +struct vsp1_partition { + unsigned int left; + unsigned int width; +}; + +/* * struct vsp1_pipeline - A VSP1 hardware pipeline * @pipe: the media pipeline * @irqlock: protects the pipeline state @@ -114,8 +125,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; unsigned int partitions; - struct v4l2_rect partition; - struct v4l2_rect *part_table; + struct vsp1_partition *partition; + struct vsp1_partition *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 8feddd59cf8d..126741f00ae3 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -108,9 +108,9 @@ static void rpf_configure(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(wpf, wpf->config, RWPF_PAD_SINK); - crop.width = pipe->partition.width * input_width + crop.width = pipe->partition->width * input_width / output->width; - crop.left += pipe->partition.left * input_width + crop.left += pipe->partition->left * input_width / output->width; } diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index 4226403ad235..4a43e7413b68 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -271,23 +271,25 @@ static void uds_configure(struct vsp1_entity *entity, unsigned int vscale; bool multitap; + input = vsp1_entity_get_pad_format(>entity, uds->entity.config, + UDS_PAD_SINK); + output = vsp1_entity_get_pad_format(>entity, uds->entity.config, + UDS_PAD_SOURCE); + if (params == VSP1_ENTITY_PARAMS_PARTITION) { - const struct v4l2_rect *clip = >partition; + struct vsp1_partition *partition = pipe->partition; vsp1_uds_write(uds, dl, VI6_UDS_CLIP_SIZE, - (clip->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | - (clip->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); + (partition->width + << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | + (output->height + << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); return; } if (params != VSP1_ENTITY_PARAMS_INIT) return; - input = vsp1_entity_get_pad_format(>entity, uds->entity.config, - UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(>entity, uds->entity.config, - UDS_PAD_SOURCE); - hscale = uds_compute_ratio(input->width, output->width); vscale = uds_compute_ratio(input->height, output->height); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 176fd4b17df5..abbdcafa7c94 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -183,19 +183,19 @@ static int __vsp1_video_try_format(struct vsp1_video *video, */ /** -
[PATCH v4 7/7] v4l: vsp1: Allow entities to participate in the partition algorithm
The configuration of the pipeline and entities directly affects the inputs required to each entity for the partition algorithm. Thus it makes sense to involve those entities in the decision making process. Extend the entity ops API to provide an optional .partition() operation. This allows entities that affect the partition window to adapt the window based on their configuration. Entities implementing this operation must update the window parameter in place, which will then be passed up the pipeline. This creates a process whereby each entity describes what is required to satisfy the required output to its predecessor in the pipeline. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_entity.h | 7 - drivers/media/platform/vsp1/vsp1_pipe.c | 22 +- drivers/media/platform/vsp1/vsp1_pipe.h | 30 -- drivers/media/platform/vsp1/vsp1_rpf.c| 27 +++- drivers/media/platform/vsp1/vsp1_sru.c| 26 +++- drivers/media/platform/vsp1/vsp1_uds.c| 41 +++- drivers/media/platform/vsp1/vsp1_video.c | 22 - drivers/media/platform/vsp1/vsp1_wpf.c| 24 +- 8 files changed, 166 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index c169a060b6d2..05c616883f4a 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h @@ -21,6 +21,8 @@ struct vsp1_device; struct vsp1_dl_list; struct vsp1_pipeline; +struct vsp1_partition; +struct vsp1_partition_window; enum vsp1_entity_type { VSP1_ENTITY_BRU, @@ -81,12 +83,17 @@ struct vsp1_route { * selection rectangles, ...) * @max_width: Return the max supported width of data that the entity can * process in a single operation. + * @partition: Process the partition construction based on this entity's + * configuration. */ struct vsp1_entity_operations { void (*destroy)(struct vsp1_entity *); void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, struct vsp1_dl_list *, enum vsp1_entity_params); unsigned int (*max_width)(struct vsp1_entity *, struct vsp1_pipeline *); + void (*partition)(struct vsp1_entity *, struct vsp1_pipeline *, + struct vsp1_partition *, unsigned int, + struct vsp1_partition_window *); }; struct vsp1_entity { diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index e817623b84e0..eff346727c72 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c @@ -382,6 +382,28 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, vsp1_uds_set_alpha(pipe->uds, dl, alpha); } +/* + * Propagate the partition calculations through the pipeline + * + * Work backwards through the pipe, allowing each entity to update the partition + * parameters based on its configuration, and the entity connected to its + * source. Each entity must produce the partition required for the previous + * entity in the pipeline. + */ +void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int index, + struct vsp1_partition_window *window) +{ + struct vsp1_entity *entity; + + list_for_each_entry_reverse(entity, >entities, list_pipe) { + if (entity->ops->partition) + entity->ops->partition(entity, pipe, partition, index, + window); + } +} + void vsp1_pipelines_suspend(struct vsp1_device *vsp1) { unsigned long flags; diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 4e9fd96108be..424e43fafaa5 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -58,17 +58,33 @@ enum vsp1_pipeline_state { }; /* - * struct vsp1_partition - A description of a slice for the partition algorithm + * struct vsp1_partition_window - Partition window coordinates * @left: horizontal coordinate of the partition start in pixels relative to the * left edge of the image * @width: partition width in pixels */ -struct vsp1_partition { +struct vsp1_partition_window { unsigned int left; unsigned int width; }; /* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @rpf: The RPF partition window configuration + * @uds_sink: The UDS input partition window configuration + * @uds_source: The UDS output partition window configuration + * @sru: The SRU partition
[PATCH v4 6/7] v4l: vsp1: Provide UDS register updates
Provide register definitions required for UDS phase and partition algorithm support. The registers and bits defined here are available on Gen3 hardware only. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_regs.h | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index cd3e32af6e3b..362f4f8b1148 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -388,6 +388,7 @@ #define VI6_UDS_CTRL_NE_RCR(1 << 18) #define VI6_UDS_CTRL_NE_GY (1 << 17) #define VI6_UDS_CTRL_NE_BCB(1 << 16) +#define VI6_UDS_CTRL_AMDSLH(1 << 2) #define VI6_UDS_CTRL_TDIPC (1 << 1) #define VI6_UDS_SCALE 0x2304 @@ -420,11 +421,24 @@ #define VI6_UDS_PASS_BWIDTH_V_MASK (0x7f << 0) #define VI6_UDS_PASS_BWIDTH_V_SHIFT0 +#define VI6_UDS_HPHASE 0x2314 +#define VI6_UDS_HPHASE_HSTP_MASK (0xfff << 16) +#define VI6_UDS_HPHASE_HSTP_SHIFT 16 +#define VI6_UDS_HPHASE_HEDP_MASK (0xfff << 0) +#define VI6_UDS_HPHASE_HEDP_SHIFT 0 + #define VI6_UDS_IPC0x2318 #define VI6_UDS_IPC_FIELD (1 << 27) #define VI6_UDS_IPC_VEDP_MASK (0xfff << 0) #define VI6_UDS_IPC_VEDP_SHIFT 0 +#define VI6_UDS_HSZCLIP0x231c +#define VI6_UDS_HSZCLIP_HCEN (1 << 28) +#define VI6_UDS_HSZCLIP_HCL_OFST_MASK (0xff << 16) +#define VI6_UDS_HSZCLIP_HCL_OFST_SHIFT 16 +#define VI6_UDS_HSZCLIP_HCL_SIZE_MASK (0x1fff << 0) +#define VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT 0 + #define VI6_UDS_CLIP_SIZE 0x2324 #define VI6_UDS_CLIP_SIZE_HSIZE_MASK (0x1fff << 16) #define VI6_UDS_CLIP_SIZE_HSIZE_SHIFT 16 -- git-series 0.9.1
[PATCH v4 4/7] v4l: vsp1: Remove redundant context variables
The vsp1_pipe object context variables for div_size and current_partition allowed state to be maintained through processing the partitions during processing. Now that the partition tables are calculated during stream on, there is no requirement to store these variables in the pipe object. Utilise local variables for the processing as required. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 4 drivers/media/platform/vsp1/vsp1_video.c | 21 +++-- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 0cfd07a187a2..9653ef5cfb0c 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -80,10 +80,8 @@ enum vsp1_pipeline_state { * @uds_input: entity at the input of the UDS, if the UDS is present * @entities: list of entities in the pipeline * @dl: display list associated with the pipeline - * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame * @partition: The current partition for configuration to process - * @current_partition: The partition number currently being configured * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { @@ -115,10 +113,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; - unsigned int div_size; unsigned int partitions; struct v4l2_rect partition; - unsigned int current_partition; struct v4l2_rect *part_table; }; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 2ac57a436811..176fd4b17df5 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -290,7 +290,6 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) } } - pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), GFP_KERNEL); @@ -379,11 +378,12 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe, } static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, - struct vsp1_dl_list *dl) + struct vsp1_dl_list *dl, + unsigned int partition) { struct vsp1_entity *entity; - pipe->partition = pipe->part_table[pipe->current_partition]; + pipe->partition = pipe->part_table[partition]; list_for_each_entry(entity, >entities, list_pipe) { if (entity->ops->configure) @@ -396,6 +396,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; struct vsp1_entity *entity; + unsigned int partition; if (!pipe->dl) pipe->dl = vsp1_dl_list_get(pipe->output->dlm); @@ -412,20 +413,12 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) } /* Run the first partition */ - pipe->current_partition = 0; - vsp1_video_pipeline_run_partition(pipe, pipe->dl); + vsp1_video_pipeline_run_partition(pipe, pipe->dl, 0); /* Process consecutive partitions as necessary */ - for (pipe->current_partition = 1; -pipe->current_partition < pipe->partitions; -pipe->current_partition++) { + for (partition = 1; partition < pipe->partitions; ++partition) { struct vsp1_dl_list *dl; - /* -* Partition configuration operations will utilise -* the pipe->current_partition variable to determine -* the work they should complete. -*/ dl = vsp1_dl_list_get(pipe->output->dlm); /* @@ -438,7 +431,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) break; } - vsp1_video_pipeline_run_partition(pipe, dl); + vsp1_video_pipeline_run_partition(pipe, dl, partition); vsp1_dl_list_add_chain(pipe->dl, dl); } -- git-series 0.9.1
[PATCH v4 3/7] v4l: vsp1: Calculate partition sizes at stream start
Previously the active window and partition sizes for each partition were calculated for each partition every frame. This data is constant and only needs to be calculated once at the start of the stream. Extend the vsp1_pipe object to dynamically store the number of partitions required and pre-calculate the partition sizes into this table. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 3 ++- drivers/media/platform/vsp1/vsp1_video.c | 44 + 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 91a784a13422..0cfd07a187a2 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -82,7 +82,9 @@ enum vsp1_pipeline_state { * @dl: display list associated with the pipeline * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame + * @partition: The current partition for configuration to process * @current_partition: The partition number currently being configured + * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { struct media_pipeline pipe; @@ -117,6 +119,7 @@ struct vsp1_pipeline { unsigned int partitions; struct v4l2_rect partition; unsigned int current_partition; + struct v4l2_rect *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index e4c0bfa0f864..2ac57a436811 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -256,12 +256,13 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; const struct v4l2_mbus_framefmt *format; struct vsp1_entity *entity; unsigned int div_size; + unsigned int i; /* * Partitions are computed on the size before rotation, use the format @@ -272,17 +273,17 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) RWPF_PAD_SINK); div_size = format->width; - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } + /* +* Only Gen3 hardware requires image partitioning, Gen2 will operate +* with a single partition that covers the whole output. +*/ + if (vsp1->info->gen == 3) { + list_for_each_entry(entity, >entities, list_pipe) { + unsigned int entity_max; - list_for_each_entry(entity, >entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + if (!entity->ops->max_width) + continue; - if (entity->ops->max_width) { entity_max = entity->ops->max_width(entity, pipe); if (entity_max) div_size = min(div_size, entity_max); @@ -291,6 +292,15 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); + pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), + GFP_KERNEL); + if (!pipe->part_table) + return -ENOMEM; + + for (i = 0; i < pipe->partitions; ++i) + pipe->part_table[i] = vsp1_video_partition(pipe, div_size, i); + + return 0; } /* - @@ -373,8 +383,7 @@ static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, { struct vsp1_entity *entity; - pipe->partition = vsp1_video_partition(pipe, pipe->div_size, - pipe->current_partition); + pipe->partition = pipe->part_table[pipe->current_partition]; list_for_each_entry(entity, >entities, list_pipe) { if (entity->ops->configure) @@ -783,9 +792,12 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb) static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) { struct vsp1_entity *entity; + int ret; /* Determine this pipelines sizes for image partitioning support.
[PATCH v4 2/7] v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function
Separate the code change from the function move so that code changes can be clearly identified. This commit has no functional change. The partition algorithm functions will be changed, and vsp1_video_pipeline_setup_partitions() will call vsp1_video_partition(). To prepare for that, move the function without any code change. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_video.c | 74 - 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index fdb135e45fea..e4c0bfa0f864 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -182,43 +182,6 @@ static int __vsp1_video_try_format(struct vsp1_video *video, * VSP1 Partition Algorithm support */ -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) -{ - struct vsp1_device *vsp1 = pipe->output->entity.vsp1; - const struct v4l2_mbus_framefmt *format; - struct vsp1_entity *entity; - unsigned int div_size; - - /* -* Partitions are computed on the size before rotation, use the format -* at the WPF sink. -*/ - format = vsp1_entity_get_pad_format(>output->entity, - pipe->output->entity.config, - RWPF_PAD_SINK); - div_size = format->width; - - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } - - list_for_each_entry(entity, >entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; - - if (entity->ops->max_width) { - entity_max = entity->ops->max_width(entity, pipe); - if (entity_max) - div_size = min(div_size, entity_max); - } - } - - pipe->div_size = div_size; - pipe->partitions = DIV_ROUND_UP(format->width, div_size); -} - /** * vsp1_video_partition - Calculate the active partition output window * @@ -293,6 +256,43 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } +static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +{ + struct vsp1_device *vsp1 = pipe->output->entity.vsp1; + const struct v4l2_mbus_framefmt *format; + struct vsp1_entity *entity; + unsigned int div_size; + + /* +* Partitions are computed on the size before rotation, use the format +* at the WPF sink. +*/ + format = vsp1_entity_get_pad_format(>output->entity, + pipe->output->entity.config, + RWPF_PAD_SINK); + div_size = format->width; + + /* Gen2 hardware doesn't require image partitioning. */ + if (vsp1->info->gen == 2) { + pipe->div_size = div_size; + pipe->partitions = 1; + return; + } + + list_for_each_entry(entity, >entities, list_pipe) { + unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + + if (entity->ops->max_width) { + entity_max = entity->ops->max_width(entity, pipe); + if (entity_max) + div_size = min(div_size, entity_max); + } + } + + pipe->div_size = div_size; + pipe->partitions = DIV_ROUND_UP(format->width, div_size); +} + /* - * Pipeline Management */ -- git-series 0.9.1
[PATCH v4 0/7] vsp1 partition algorithm improvements
Hans, this series should be ready for integration now. Could you pick up these patches please? Some updates and initial improvements for the VSP1 partition algorithm that remove redundant processing and variables, reducing the processing done in interrupt context slightly. Patch 1, fixes up a bug to release buffers back to vb2 if errors occur in vsp1_video_start_streaming() Patches 2, 3 and 4 clean up the calculation of the partition windows such that they are only calculated once at streamon. Patch 5 improves the allocations with a new vsp1_partition object to track each window state. Patches 6, and 7 then go on to enhance the partition algorithm by allowing each entity to calculate the requirements for it's pipeline predecessor to successfully generate the requested output window. This system allows the entity objects to specify what they need to fulfil the output for the next entity in the pipeline. v2: - Rebased to v4.12-rc1 - Partition tables dynamically allocated - review fixups v3: - Review fixes and changes from Laurent - v4l: vsp1: Release buffers in start_streaming error path v4: - (Final) fixups from Laurent's review, and picked up his reviewed-by tags. Kieran Bingham (7): v4l: vsp1: Release buffers in start_streaming error path v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function v4l: vsp1: Calculate partition sizes at stream start v4l: vsp1: Remove redundant context variables v4l: vsp1: Move partition rectangles to struct and operate directly v4l: vsp1: Provide UDS register updates v4l: vsp1: Allow entities to participate in the partition algorithm drivers/media/platform/vsp1/vsp1_entity.h | 7 +- drivers/media/platform/vsp1/vsp1_pipe.c | 22 +++- drivers/media/platform/vsp1/vsp1_pipe.h | 46 +- drivers/media/platform/vsp1/vsp1_regs.h | 14 ++- drivers/media/platform/vsp1/vsp1_rpf.c| 27 +-- drivers/media/platform/vsp1/vsp1_sru.c| 26 +++- drivers/media/platform/vsp1/vsp1_uds.c| 57 ++- drivers/media/platform/vsp1/vsp1_video.c | 182 --- drivers/media/platform/vsp1/vsp1_wpf.c| 24 ++- 9 files changed, 289 insertions(+), 116 deletions(-) base-commit: 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 -- git-series 0.9.1
[PATCH v4 1/7] v4l: vsp1: Release buffers in start_streaming error path
Presently any received buffers are only released back to vb2 if vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() encounters an error, we will be warned by the vb2 handlers that buffers have not been returned. Move the buffer cleanup code to its own function to prevent duplication and call from both vsp1_video_stop_streaming() and the error path in vsp1_video_start_streaming(). Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_video.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..fdb135e45fea 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -822,6 +822,20 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) return 0; } +static void vsp1_video_cleanup_pipeline(struct vsp1_pipeline *pipe) +{ + struct vsp1_video *video = pipe->output->video; + struct vsp1_vb2_buffer *buffer; + unsigned long flags; + + /* Remove all buffers from the IRQ queue. */ + spin_lock_irqsave(>irqlock, flags); + list_for_each_entry(buffer, >irqqueue, queue) + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); + INIT_LIST_HEAD(>irqqueue); + spin_unlock_irqrestore(>irqlock, flags); +} + static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vsp1_video *video = vb2_get_drv_priv(vq); @@ -835,6 +849,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); if (ret < 0) { mutex_unlock(>lock); + vsp1_video_cleanup_pipeline(pipe); return ret; } @@ -866,7 +881,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) { struct vsp1_video *video = vb2_get_drv_priv(vq); struct vsp1_pipeline *pipe = video->rwpf->pipe; - struct vsp1_vb2_buffer *buffer; unsigned long flags; int ret; @@ -891,14 +905,8 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) mutex_unlock(>lock); media_pipeline_stop(>video.entity); + vsp1_video_cleanup_pipeline(pipe); vsp1_video_pipeline_put(pipe); - - /* Remove all buffers from the IRQ queue. */ - spin_lock_irqsave(>irqlock, flags); - list_for_each_entry(buffer, >irqqueue, queue) - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(>irqqueue); - spin_unlock_irqrestore(>irqlock, flags); } static const struct vb2_ops vsp1_video_queue_qops = { -- git-series 0.9.1
Re: [PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
Hi Laurent, On 04/08/17 17:13, Laurent Pinchart wrote: > On Friday 04 Aug 2017 17:08:34 Kieran Bingham wrote: >> On 04/08/17 17:03, Laurent Pinchart wrote: >>> On Friday 04 Aug 2017 16:57:05 Kieran Bingham wrote: Presently any received buffers are only released back to vb2 if vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() encounters an error, we will be warned by the vb2 handlers that buffers have not been returned. Move the buffer cleanup code to it's own function to prevent duplication >>> >>> s/it's/its/ >> >> Ah yes - I'm always terrible with my its'y bits. >> and call from both vsp1_video_stop_streaming() and the error path in vsp1_video_start_streaming() >>> >>> s/$/./ >> >> :D >> Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..a24033429cd7 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) return 0; } +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) >>> >>> Should this function take a pipe pointer instead of a video pointer for >>> symmetry with vsp1_video_setup_pipeline() ? >> >> I passed this way because the cleanup needed a *video. >> >> Is it possible to get from a *pipe to a *video? > > Yes, pipe->output->video Ah yes of course. +{ + struct vsp1_vb2_buffer *buffer; + unsigned long flags; + + /* Remove all buffers from the IRQ queue. */ + spin_lock_irqsave(>irqlock, flags); + list_for_each_entry(buffer, >irqqueue, queue) + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); + INIT_LIST_HEAD(>irqqueue); + spin_unlock_irqrestore(>irqlock, flags); +} > > [snip] > @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) media_pipeline_stop(>video.entity); vsp1_video_pipeline_put(pipe); - /* Remove all buffers from the IRQ queue. */ - spin_lock_irqsave(>irqlock, flags); - list_for_each_entry(buffer, >irqqueue, queue) - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(>irqqueue); - spin_unlock_irqrestore(>irqlock, flags); + vsp1_video_cleanup_pipeline(video); >>> >>> The vsp1_video_cleanup_pipeline() call should go before >>> vsp1_video_pipeline_put(), as you've noticed in patch 7/7. >> >> I chose to do the move in 3/7 so that this patch did not change the existing >> functionality. >> >> There is no (explicit) need for the cleanup to happen before the >> pipeline_put() until the cleanup function references the pipe... > > Except if you pass a *pipe to the cleanup function, as > vsp1_video_pipeline_put() can free the pipe. Indeed! > >>> With all that fixed, Patch update imminent. Thanks. >>> >>> Reviewed-by: Laurent Pinchart >>> } static const struct vb2_ops vsp1_video_queue_qops = { >
Re: [PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
Hi Kieran, On Friday 04 Aug 2017 17:08:34 Kieran Bingham wrote: > On 04/08/17 17:03, Laurent Pinchart wrote: > > On Friday 04 Aug 2017 16:57:05 Kieran Bingham wrote: > >> Presently any received buffers are only released back to vb2 if > >> vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() > >> encounters an error, we will be warned by the vb2 handlers that buffers > >> have not been returned. > >> > >> Move the buffer cleanup code to it's own function to prevent duplication > > > > s/it's/its/ > > Ah yes - I'm always terrible with my its'y bits. > > >> and call from both vsp1_video_stop_streaming() and the error path in > >> vsp1_video_start_streaming() > > > > s/$/./ > > :D > > >> Signed-off-by: Kieran Bingham> >> --- > >> > >> drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- > >> 1 file changed, 15 insertions(+), 7 deletions(-) > >> > >> diff --git a/drivers/media/platform/vsp1/vsp1_video.c > >> b/drivers/media/platform/vsp1/vsp1_video.c index > >> 5af3486afe07..a24033429cd7 > >> 100644 > >> --- a/drivers/media/platform/vsp1/vsp1_video.c > >> +++ b/drivers/media/platform/vsp1/vsp1_video.c > >> @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct > >> vsp1_pipeline *pipe) > >>return 0; > >> } > >> > >> +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) > > > > Should this function take a pipe pointer instead of a video pointer for > > symmetry with vsp1_video_setup_pipeline() ? > > I passed this way because the cleanup needed a *video. > > Is it possible to get from a *pipe to a *video? Yes, pipe->output->video > >> +{ > >> + struct vsp1_vb2_buffer *buffer; > >> + unsigned long flags; > >> + > >> + /* Remove all buffers from the IRQ queue. */ > >> + spin_lock_irqsave(>irqlock, flags); > >> + list_for_each_entry(buffer, >irqqueue, queue) > >> + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > >> + INIT_LIST_HEAD(>irqqueue); > >> + spin_unlock_irqrestore(>irqlock, flags); > >> +} [snip] > >> @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct > >> vb2_queue > >> *vq) media_pipeline_stop(>video.entity); > >> > >>vsp1_video_pipeline_put(pipe); > >> > >> - /* Remove all buffers from the IRQ queue. */ > >> - spin_lock_irqsave(>irqlock, flags); > >> - list_for_each_entry(buffer, >irqqueue, queue) > >> - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > >> - INIT_LIST_HEAD(>irqqueue); > >> - spin_unlock_irqrestore(>irqlock, flags); > >> + vsp1_video_cleanup_pipeline(video); > > > > The vsp1_video_cleanup_pipeline() call should go before > > vsp1_video_pipeline_put(), as you've noticed in patch 7/7. > > I chose to do the move in 3/7 so that this patch did not change the existing > functionality. > > There is no (explicit) need for the cleanup to happen before the > pipeline_put() until the cleanup function references the pipe... Except if you pass a *pipe to the cleanup function, as vsp1_video_pipeline_put() can free the pipe. > > With all that fixed, > > > > Reviewed-by: Laurent Pinchart > > > >> } > >> > >> static const struct vb2_ops vsp1_video_queue_qops = { -- Regards, Laurent Pinchart
Re: [PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
Hi Laurent, Thankyou for the speedy review. On 04/08/17 17:03, Laurent Pinchart wrote: > Hi Kieran, > > Thank you for the patch. > > On Friday 04 Aug 2017 16:57:05 Kieran Bingham wrote: >> Presently any received buffers are only released back to vb2 if >> vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() >> encounters an error, we will be warned by the vb2 handlers that buffers >> have not been returned. >> >> Move the buffer cleanup code to it's own function to prevent duplication > > s/it's/its/ Ah yes - I'm always terrible with my its'y bits. > >> and call from both vsp1_video_stop_streaming() and the error path in >> vsp1_video_start_streaming() > > s/$/./ :D > >> >> Signed-off-by: Kieran Bingham>> --- >> drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- >> 1 file changed, 15 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/media/platform/vsp1/vsp1_video.c >> b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..a24033429cd7 >> 100644 >> --- a/drivers/media/platform/vsp1/vsp1_video.c >> +++ b/drivers/media/platform/vsp1/vsp1_video.c >> @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct >> vsp1_pipeline *pipe) return 0; >> } >> >> +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) > > Should this function take a pipe pointer instead of a video pointer for > symmetry with vsp1_video_setup_pipeline() ? I passed this way because the cleanup needed a *video. Is it possible to get from a *pipe to a *video? >> +{ >> +struct vsp1_vb2_buffer *buffer; >> +unsigned long flags; >> + >> +/* Remove all buffers from the IRQ queue. */ >> +spin_lock_irqsave(>irqlock, flags); >> +list_for_each_entry(buffer, >irqqueue, queue) >> +vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); >> +INIT_LIST_HEAD(>irqqueue); >> +spin_unlock_irqrestore(>irqlock, flags); >> +} >> + >> static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int >> count) { >> struct vsp1_video *video = vb2_get_drv_priv(vq); >> @@ -835,6 +848,7 @@ static int vsp1_video_start_streaming(struct vb2_queue >> *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); >> if (ret < 0) { >> mutex_unlock(>lock); >> +vsp1_video_cleanup_pipeline(video); >> return ret; >> } >> >> @@ -866,7 +880,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue >> *vq) { >> struct vsp1_video *video = vb2_get_drv_priv(vq); >> struct vsp1_pipeline *pipe = video->rwpf->pipe; >> -struct vsp1_vb2_buffer *buffer; >> unsigned long flags; >> int ret; >> >> @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue >> *vq) media_pipeline_stop(>video.entity); >> vsp1_video_pipeline_put(pipe); >> >> -/* Remove all buffers from the IRQ queue. */ >> -spin_lock_irqsave(>irqlock, flags); >> -list_for_each_entry(buffer, >irqqueue, queue) >> -vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); >> -INIT_LIST_HEAD(>irqqueue); >> -spin_unlock_irqrestore(>irqlock, flags); >> +vsp1_video_cleanup_pipeline(video); > > The vsp1_video_cleanup_pipeline() call should go before > vsp1_video_pipeline_put(), as you've noticed in patch 7/7. I chose to do the move in 3/7 so that this patch did not change the existing functionality. There is no (explicit) need for the cleanup to happen before the pipeline_put() until the cleanup function references the pipe... > > With all that fixed, > > Reviewed-by: Laurent Pinchart > >> } >> >> static const struct vb2_ops vsp1_video_queue_qops = { >
Re: [PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
On Friday 04 Aug 2017 19:03:28 Laurent Pinchart wrote: > Hi Kieran, > > Thank you for the patch. > > On Friday 04 Aug 2017 16:57:05 Kieran Bingham wrote: > > Presently any received buffers are only released back to vb2 if > > vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() > > encounters an error, we will be warned by the vb2 handlers that buffers > > have not been returned. > > > > Move the buffer cleanup code to it's own function to prevent duplication > > s/it's/its/ > > > and call from both vsp1_video_stop_streaming() and the error path in > > vsp1_video_start_streaming() > > s/$/./ > > > Signed-off-by: Kieran Bingham> > --- > > > > drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- > > 1 file changed, 15 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/media/platform/vsp1/vsp1_video.c > > b/drivers/media/platform/vsp1/vsp1_video.c index > > 5af3486afe07..a24033429cd7 > > 100644 > > --- a/drivers/media/platform/vsp1/vsp1_video.c > > +++ b/drivers/media/platform/vsp1/vsp1_video.c > > @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct > > vsp1_pipeline *pipe) return 0; > > > > } > > > > +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) > > Should this function take a pipe pointer instead of a video pointer for > symmetry with vsp1_video_setup_pipeline() ? > > > +{ > > + struct vsp1_vb2_buffer *buffer; > > + unsigned long flags; > > + > > + /* Remove all buffers from the IRQ queue. */ > > + spin_lock_irqsave(>irqlock, flags); > > + list_for_each_entry(buffer, >irqqueue, queue) > > + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > > + INIT_LIST_HEAD(>irqqueue); > > + spin_unlock_irqrestore(>irqlock, flags); > > +} > > + > > > > static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int > > > > count) { > > > > struct vsp1_video *video = vb2_get_drv_priv(vq); > > > > @@ -835,6 +848,7 @@ static int vsp1_video_start_streaming(struct vb2_queue > > *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); > > > > if (ret < 0) { > > > > mutex_unlock(>lock); > > > > + vsp1_video_cleanup_pipeline(video); > > > > return ret; > > > > } > > > > @@ -866,7 +880,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue > > *vq) { > > > > struct vsp1_video *video = vb2_get_drv_priv(vq); > > struct vsp1_pipeline *pipe = video->rwpf->pipe; > > > > - struct vsp1_vb2_buffer *buffer; > > > > unsigned long flags; > > int ret; > > > > @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct > > vb2_queue > > *vq) media_pipeline_stop(>video.entity); > > > > vsp1_video_pipeline_put(pipe); > > > > - /* Remove all buffers from the IRQ queue. */ > > - spin_lock_irqsave(>irqlock, flags); > > - list_for_each_entry(buffer, >irqqueue, queue) > > - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > > - INIT_LIST_HEAD(>irqqueue); > > - spin_unlock_irqrestore(>irqlock, flags); > > + vsp1_video_cleanup_pipeline(video); > > The vsp1_video_cleanup_pipeline() call should go before > vsp1_video_pipeline_put(), as you've noticed in patch 7/7. I meant 3/7. > > With all that fixed, > > Reviewed-by: Laurent Pinchart > > > } > > > > static const struct vb2_ops vsp1_video_queue_qops = { -- Regards, Laurent Pinchart
Re: [PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
Hi Kieran, Thank you for the patch. On Friday 04 Aug 2017 16:57:05 Kieran Bingham wrote: > Presently any received buffers are only released back to vb2 if > vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() > encounters an error, we will be warned by the vb2 handlers that buffers > have not been returned. > > Move the buffer cleanup code to it's own function to prevent duplication s/it's/its/ > and call from both vsp1_video_stop_streaming() and the error path in > vsp1_video_start_streaming() s/$/./ > > Signed-off-by: Kieran Bingham> --- > drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- > 1 file changed, 15 insertions(+), 7 deletions(-) > > diff --git a/drivers/media/platform/vsp1/vsp1_video.c > b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..a24033429cd7 > 100644 > --- a/drivers/media/platform/vsp1/vsp1_video.c > +++ b/drivers/media/platform/vsp1/vsp1_video.c > @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct > vsp1_pipeline *pipe) return 0; > } > > +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) Should this function take a pipe pointer instead of a video pointer for symmetry with vsp1_video_setup_pipeline() ? > +{ > + struct vsp1_vb2_buffer *buffer; > + unsigned long flags; > + > + /* Remove all buffers from the IRQ queue. */ > + spin_lock_irqsave(>irqlock, flags); > + list_for_each_entry(buffer, >irqqueue, queue) > + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > + INIT_LIST_HEAD(>irqqueue); > + spin_unlock_irqrestore(>irqlock, flags); > +} > + > static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int > count) { > struct vsp1_video *video = vb2_get_drv_priv(vq); > @@ -835,6 +848,7 @@ static int vsp1_video_start_streaming(struct vb2_queue > *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); > if (ret < 0) { > mutex_unlock(>lock); > + vsp1_video_cleanup_pipeline(video); > return ret; > } > > @@ -866,7 +880,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue > *vq) { > struct vsp1_video *video = vb2_get_drv_priv(vq); > struct vsp1_pipeline *pipe = video->rwpf->pipe; > - struct vsp1_vb2_buffer *buffer; > unsigned long flags; > int ret; > > @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue > *vq) media_pipeline_stop(>video.entity); > vsp1_video_pipeline_put(pipe); > > - /* Remove all buffers from the IRQ queue. */ > - spin_lock_irqsave(>irqlock, flags); > - list_for_each_entry(buffer, >irqqueue, queue) > - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); > - INIT_LIST_HEAD(>irqqueue); > - spin_unlock_irqrestore(>irqlock, flags); > + vsp1_video_cleanup_pipeline(video); The vsp1_video_cleanup_pipeline() call should go before vsp1_video_pipeline_put(), as you've noticed in patch 7/7. With all that fixed, Reviewed-by: Laurent Pinchart > } > > static const struct vb2_ops vsp1_video_queue_qops = { -- Regards, Laurent Pinchart
[PATCH v3 5/7] v4l: vsp1: Move partition rectangles to struct and operate directly
As we develop the partition algorithm, we need to store more information per partition to describe the phase and other parameters. To keep this data together, further abstract the existing v4l2_rect into a partition specific structure. As partitions only have horizontal coordinates, store the left and width values only. When generating the partition windows, operate directly on the partition struct rather than copying and duplicating the processed data Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 15 +++-- drivers/media/platform/vsp1/vsp1_rpf.c | 4 +- drivers/media/platform/vsp1/vsp1_uds.c | 18 +- drivers/media/platform/vsp1/vsp1_video.c | 43 +++-- drivers/media/platform/vsp1/vsp1_wpf.c | 14 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 9653ef5cfb0c..4e9fd96108be 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -58,6 +58,17 @@ enum vsp1_pipeline_state { }; /* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @left: horizontal coordinate of the partition start in pixels relative to the + * left edge of the image + * @width: partition width in pixels + */ +struct vsp1_partition { + unsigned int left; + unsigned int width; +}; + +/* * struct vsp1_pipeline - A VSP1 hardware pipeline * @pipe: the media pipeline * @irqlock: protects the pipeline state @@ -114,8 +125,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; unsigned int partitions; - struct v4l2_rect partition; - struct v4l2_rect *part_table; + struct vsp1_partition *partition; + struct vsp1_partition *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 8feddd59cf8d..126741f00ae3 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -108,9 +108,9 @@ static void rpf_configure(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(wpf, wpf->config, RWPF_PAD_SINK); - crop.width = pipe->partition.width * input_width + crop.width = pipe->partition->width * input_width / output->width; - crop.left += pipe->partition.left * input_width + crop.left += pipe->partition->left * input_width / output->width; } diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index 4226403ad235..4a43e7413b68 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -271,23 +271,25 @@ static void uds_configure(struct vsp1_entity *entity, unsigned int vscale; bool multitap; + input = vsp1_entity_get_pad_format(>entity, uds->entity.config, + UDS_PAD_SINK); + output = vsp1_entity_get_pad_format(>entity, uds->entity.config, + UDS_PAD_SOURCE); + if (params == VSP1_ENTITY_PARAMS_PARTITION) { - const struct v4l2_rect *clip = >partition; + struct vsp1_partition *partition = pipe->partition; vsp1_uds_write(uds, dl, VI6_UDS_CLIP_SIZE, - (clip->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | - (clip->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); + (partition->width + << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | + (output->height + << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); return; } if (params != VSP1_ENTITY_PARAMS_INIT) return; - input = vsp1_entity_get_pad_format(>entity, uds->entity.config, - UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(>entity, uds->entity.config, - UDS_PAD_SOURCE); - hscale = uds_compute_ratio(input->width, output->width); vscale = uds_compute_ratio(input->height, output->height); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index f8c3186c0fb6..5522595e9323 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -183,19 +183,19 @@ static int __vsp1_video_try_format(struct vsp1_video *video, */ /** -
[PATCH v3 1/7] v4l: vsp1: Release buffers in start_streaming error path
Presently any received buffers are only released back to vb2 if vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() encounters an error, we will be warned by the vb2 handlers that buffers have not been returned. Move the buffer cleanup code to it's own function to prevent duplication and call from both vsp1_video_stop_streaming() and the error path in vsp1_video_start_streaming() Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_video.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..a24033429cd7 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -822,6 +822,19 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) return 0; } +static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) +{ + struct vsp1_vb2_buffer *buffer; + unsigned long flags; + + /* Remove all buffers from the IRQ queue. */ + spin_lock_irqsave(>irqlock, flags); + list_for_each_entry(buffer, >irqqueue, queue) + vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); + INIT_LIST_HEAD(>irqqueue); + spin_unlock_irqrestore(>irqlock, flags); +} + static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vsp1_video *video = vb2_get_drv_priv(vq); @@ -835,6 +848,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); if (ret < 0) { mutex_unlock(>lock); + vsp1_video_cleanup_pipeline(video); return ret; } @@ -866,7 +880,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) { struct vsp1_video *video = vb2_get_drv_priv(vq); struct vsp1_pipeline *pipe = video->rwpf->pipe; - struct vsp1_vb2_buffer *buffer; unsigned long flags; int ret; @@ -893,12 +906,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) media_pipeline_stop(>video.entity); vsp1_video_pipeline_put(pipe); - /* Remove all buffers from the IRQ queue. */ - spin_lock_irqsave(>irqlock, flags); - list_for_each_entry(buffer, >irqqueue, queue) - vb2_buffer_done(>buf.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(>irqqueue); - spin_unlock_irqrestore(>irqlock, flags); + vsp1_video_cleanup_pipeline(video); } static const struct vb2_ops vsp1_video_queue_qops = { -- git-series 0.9.1
[PATCH v3 3/7] v4l: vsp1: Calculate partition sizes at stream start
Previously the active window and partition sizes for each partition were calculated for each partition every frame. This data is constant and only needs to be calculated once at the start of the stream. Extend the vsp1_pipe object to dynamically store the number of partitions required and pre-calculate the partition sizes into this table. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 3 ++- drivers/media/platform/vsp1/vsp1_video.c | 48 + 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 91a784a13422..0cfd07a187a2 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -82,7 +82,9 @@ enum vsp1_pipeline_state { * @dl: display list associated with the pipeline * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame + * @partition: The current partition for configuration to process * @current_partition: The partition number currently being configured + * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { struct media_pipeline pipe; @@ -117,6 +119,7 @@ struct vsp1_pipeline { unsigned int partitions; struct v4l2_rect partition; unsigned int current_partition; + struct v4l2_rect *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 097e4db572a9..447597f1b758 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -256,12 +256,13 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; const struct v4l2_mbus_framefmt *format; struct vsp1_entity *entity; unsigned int div_size; + unsigned int i; /* * Partitions are computed on the size before rotation, use the format @@ -272,17 +273,17 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) RWPF_PAD_SINK); div_size = format->width; - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } + /* +* Only Gen3 hardware requires image partitioning, Gen2 will operate +* with a single partition that covers the whole output. +*/ + if (vsp1->info->gen == 3) { + list_for_each_entry(entity, >entities, list_pipe) { + unsigned int entity_max; - list_for_each_entry(entity, >entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + if (!entity->ops->max_width) + continue; - if (entity->ops->max_width) { entity_max = entity->ops->max_width(entity, pipe); if (entity_max) div_size = min(div_size, entity_max); @@ -291,6 +292,15 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); + pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), + GFP_KERNEL); + if (!pipe->part_table) + return -ENOMEM; + + for (i = 0; i < pipe->partitions; ++i) + pipe->part_table[i] = vsp1_video_partition(pipe, div_size, i); + + return 0; } /* - @@ -373,8 +383,7 @@ static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, { struct vsp1_entity *entity; - pipe->partition = vsp1_video_partition(pipe, pipe->div_size, - pipe->current_partition); + pipe->partition = pipe->part_table[pipe->current_partition]; list_for_each_entry(entity, >entities, list_pipe) { if (entity->ops->configure) @@ -783,9 +792,12 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb) static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) { struct vsp1_entity *entity; + int ret; /* Determine this pipelines sizes for image partitioning support.
[PATCH v3 2/7] v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function
Separate the code change from the function move so that code changes can be clearly identified. This commit has no functional change. The partition algorithm functions will be changed, and vsp1_video_pipeline_setup_partitions() will call vsp1_video_partition(). To prepare for that, move the function without any code change. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_video.c | 74 - 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index a24033429cd7..097e4db572a9 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -182,43 +182,6 @@ static int __vsp1_video_try_format(struct vsp1_video *video, * VSP1 Partition Algorithm support */ -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) -{ - struct vsp1_device *vsp1 = pipe->output->entity.vsp1; - const struct v4l2_mbus_framefmt *format; - struct vsp1_entity *entity; - unsigned int div_size; - - /* -* Partitions are computed on the size before rotation, use the format -* at the WPF sink. -*/ - format = vsp1_entity_get_pad_format(>output->entity, - pipe->output->entity.config, - RWPF_PAD_SINK); - div_size = format->width; - - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } - - list_for_each_entry(entity, >entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; - - if (entity->ops->max_width) { - entity_max = entity->ops->max_width(entity, pipe); - if (entity_max) - div_size = min(div_size, entity_max); - } - } - - pipe->div_size = div_size; - pipe->partitions = DIV_ROUND_UP(format->width, div_size); -} - /** * vsp1_video_partition - Calculate the active partition output window * @@ -293,6 +256,43 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } +static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +{ + struct vsp1_device *vsp1 = pipe->output->entity.vsp1; + const struct v4l2_mbus_framefmt *format; + struct vsp1_entity *entity; + unsigned int div_size; + + /* +* Partitions are computed on the size before rotation, use the format +* at the WPF sink. +*/ + format = vsp1_entity_get_pad_format(>output->entity, + pipe->output->entity.config, + RWPF_PAD_SINK); + div_size = format->width; + + /* Gen2 hardware doesn't require image partitioning. */ + if (vsp1->info->gen == 2) { + pipe->div_size = div_size; + pipe->partitions = 1; + return; + } + + list_for_each_entry(entity, >entities, list_pipe) { + unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + + if (entity->ops->max_width) { + entity_max = entity->ops->max_width(entity, pipe); + if (entity_max) + div_size = min(div_size, entity_max); + } + } + + pipe->div_size = div_size; + pipe->partitions = DIV_ROUND_UP(format->width, div_size); +} + /* - * Pipeline Management */ -- git-series 0.9.1
[PATCH v3 6/7] v4l: vsp1: Provide UDS register updates
Provide register definitions required for UDS phase and partition algorithm support. The registers and bits defined here are available on Gen3 hardware only. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_regs.h | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index cd3e32af6e3b..362f4f8b1148 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -388,6 +388,7 @@ #define VI6_UDS_CTRL_NE_RCR(1 << 18) #define VI6_UDS_CTRL_NE_GY (1 << 17) #define VI6_UDS_CTRL_NE_BCB(1 << 16) +#define VI6_UDS_CTRL_AMDSLH(1 << 2) #define VI6_UDS_CTRL_TDIPC (1 << 1) #define VI6_UDS_SCALE 0x2304 @@ -420,11 +421,24 @@ #define VI6_UDS_PASS_BWIDTH_V_MASK (0x7f << 0) #define VI6_UDS_PASS_BWIDTH_V_SHIFT0 +#define VI6_UDS_HPHASE 0x2314 +#define VI6_UDS_HPHASE_HSTP_MASK (0xfff << 16) +#define VI6_UDS_HPHASE_HSTP_SHIFT 16 +#define VI6_UDS_HPHASE_HEDP_MASK (0xfff << 0) +#define VI6_UDS_HPHASE_HEDP_SHIFT 0 + #define VI6_UDS_IPC0x2318 #define VI6_UDS_IPC_FIELD (1 << 27) #define VI6_UDS_IPC_VEDP_MASK (0xfff << 0) #define VI6_UDS_IPC_VEDP_SHIFT 0 +#define VI6_UDS_HSZCLIP0x231c +#define VI6_UDS_HSZCLIP_HCEN (1 << 28) +#define VI6_UDS_HSZCLIP_HCL_OFST_MASK (0xff << 16) +#define VI6_UDS_HSZCLIP_HCL_OFST_SHIFT 16 +#define VI6_UDS_HSZCLIP_HCL_SIZE_MASK (0x1fff << 0) +#define VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT 0 + #define VI6_UDS_CLIP_SIZE 0x2324 #define VI6_UDS_CLIP_SIZE_HSIZE_MASK (0x1fff << 16) #define VI6_UDS_CLIP_SIZE_HSIZE_SHIFT 16 -- git-series 0.9.1
[PATCH v3 7/7] v4l: vsp1: Allow entities to participate in the partition algorithm
The configuration of the pipeline and entities directly affects the inputs required to each entity for the partition algorithm. Thus it makes sense to involve those entities in the decision making process. Extend the entity ops API to provide an optional .partition() operation. This allows entities that affect the partition window to adapt the window based on their configuration. Entities implementing this operation must update the window parameter in place, which will then be passed up the pipeline. This creates a process whereby each entity describes what is required to satisfy the required output to its predecessor in the pipeline. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_entity.h | 7 - drivers/media/platform/vsp1/vsp1_pipe.c | 22 +- drivers/media/platform/vsp1/vsp1_pipe.h | 30 -- drivers/media/platform/vsp1/vsp1_rpf.c| 27 +++- drivers/media/platform/vsp1/vsp1_sru.c| 26 +++- drivers/media/platform/vsp1/vsp1_uds.c| 41 +++- drivers/media/platform/vsp1/vsp1_video.c | 22 - drivers/media/platform/vsp1/vsp1_wpf.c| 24 +- 8 files changed, 166 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index c169a060b6d2..05c616883f4a 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h @@ -21,6 +21,8 @@ struct vsp1_device; struct vsp1_dl_list; struct vsp1_pipeline; +struct vsp1_partition; +struct vsp1_partition_window; enum vsp1_entity_type { VSP1_ENTITY_BRU, @@ -81,12 +83,17 @@ struct vsp1_route { * selection rectangles, ...) * @max_width: Return the max supported width of data that the entity can * process in a single operation. + * @partition: Process the partition construction based on this entity's + * configuration. */ struct vsp1_entity_operations { void (*destroy)(struct vsp1_entity *); void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, struct vsp1_dl_list *, enum vsp1_entity_params); unsigned int (*max_width)(struct vsp1_entity *, struct vsp1_pipeline *); + void (*partition)(struct vsp1_entity *, struct vsp1_pipeline *, + struct vsp1_partition *, unsigned int, + struct vsp1_partition_window *); }; struct vsp1_entity { diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index e817623b84e0..eff346727c72 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c @@ -382,6 +382,28 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, vsp1_uds_set_alpha(pipe->uds, dl, alpha); } +/* + * Propagate the partition calculations through the pipeline + * + * Work backwards through the pipe, allowing each entity to update the partition + * parameters based on its configuration, and the entity connected to its + * source. Each entity must produce the partition required for the previous + * entity in the pipeline. + */ +void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int index, + struct vsp1_partition_window *window) +{ + struct vsp1_entity *entity; + + list_for_each_entry_reverse(entity, >entities, list_pipe) { + if (entity->ops->partition) + entity->ops->partition(entity, pipe, partition, index, + window); + } +} + void vsp1_pipelines_suspend(struct vsp1_device *vsp1) { unsigned long flags; diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 4e9fd96108be..424e43fafaa5 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -58,17 +58,33 @@ enum vsp1_pipeline_state { }; /* - * struct vsp1_partition - A description of a slice for the partition algorithm + * struct vsp1_partition_window - Partition window coordinates * @left: horizontal coordinate of the partition start in pixels relative to the * left edge of the image * @width: partition width in pixels */ -struct vsp1_partition { +struct vsp1_partition_window { unsigned int left; unsigned int width; }; /* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @rpf: The RPF partition window configuration + * @uds_sink: The UDS input partition window configuration + * @uds_source: The UDS output partition window configuration + * @sru: The SRU partition
[PATCH v3 4/7] v4l: vsp1: Remove redundant context variables
The vsp1_pipe object context variables for div_size and current_partition allowed state to be maintained through processing the partitions during processing. Now that the partition tables are calculated during stream on, there is no requirement to store these variables in the pipe object. Utilise local variables for the processing as required. Signed-off-by: Kieran BinghamReviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 4 drivers/media/platform/vsp1/vsp1_video.c | 21 +++-- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 0cfd07a187a2..9653ef5cfb0c 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -80,10 +80,8 @@ enum vsp1_pipeline_state { * @uds_input: entity at the input of the UDS, if the UDS is present * @entities: list of entities in the pipeline * @dl: display list associated with the pipeline - * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame * @partition: The current partition for configuration to process - * @current_partition: The partition number currently being configured * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { @@ -115,10 +113,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; - unsigned int div_size; unsigned int partitions; struct v4l2_rect partition; - unsigned int current_partition; struct v4l2_rect *part_table; }; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 447597f1b758..f8c3186c0fb6 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -290,7 +290,6 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) } } - pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), GFP_KERNEL); @@ -379,11 +378,12 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe, } static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, - struct vsp1_dl_list *dl) + struct vsp1_dl_list *dl, + unsigned int partition) { struct vsp1_entity *entity; - pipe->partition = pipe->part_table[pipe->current_partition]; + pipe->partition = pipe->part_table[partition]; list_for_each_entry(entity, >entities, list_pipe) { if (entity->ops->configure) @@ -396,6 +396,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; struct vsp1_entity *entity; + unsigned int partition; if (!pipe->dl) pipe->dl = vsp1_dl_list_get(pipe->output->dlm); @@ -412,20 +413,12 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) } /* Run the first partition */ - pipe->current_partition = 0; - vsp1_video_pipeline_run_partition(pipe, pipe->dl); + vsp1_video_pipeline_run_partition(pipe, pipe->dl, 0); /* Process consecutive partitions as necessary */ - for (pipe->current_partition = 1; -pipe->current_partition < pipe->partitions; -pipe->current_partition++) { + for (partition = 1; partition < pipe->partitions; ++partition) { struct vsp1_dl_list *dl; - /* -* Partition configuration operations will utilise -* the pipe->current_partition variable to determine -* the work they should complete. -*/ dl = vsp1_dl_list_get(pipe->output->dlm); /* @@ -438,7 +431,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) break; } - vsp1_video_pipeline_run_partition(pipe, dl); + vsp1_video_pipeline_run_partition(pipe, dl, partition); vsp1_dl_list_add_chain(pipe->dl, dl); } -- git-series 0.9.1
[PATCH v3 0/7] vsp1 partition algorithm improvements
Some updates and initial improvements for the VSP1 partition algorithm that remove redundant processing and variables, reducing the processing done in interrupt context slightly. Patch 1, fixes up a bug to release buffers back to vb2 if errors occur in vsp1_video_start_streaming() Patches 2, 3 and 4 clean up the calculation of the partition windows such that they are only calculated once at streamon. Patch 5 improves the allocations with a new vsp1_partition object to track each window state. Patches 6, and 7 then go on to enhance the partition algorithm by allowing each entity to calculate the requirements for it's pipeline predecessor to successfully generate the requested output window. This system allows the entity objects to specify what they need to fulfil the output for the next entity in the pipeline. v2: - Rebased to v4.12-rc1 - Partition tables dynamically allocated - review fixups v3: - Review fixes and changes from Laurent - v4l: vsp1: Release buffers in start_streaming error path Kieran Bingham (7): v4l: vsp1: Release buffers in start_streaming error path v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function v4l: vsp1: Calculate partition sizes at stream start v4l: vsp1: Remove redundant context variables v4l: vsp1: Move partition rectangles to struct and operate directly v4l: vsp1: Provide UDS register updates v4l: vsp1: Allow entities to participate in the partition algorithm drivers/media/platform/vsp1/vsp1_entity.h | 7 +- drivers/media/platform/vsp1/vsp1_pipe.c | 22 +++- drivers/media/platform/vsp1/vsp1_pipe.h | 46 +- drivers/media/platform/vsp1/vsp1_regs.h | 14 ++- drivers/media/platform/vsp1/vsp1_rpf.c| 27 +-- drivers/media/platform/vsp1/vsp1_sru.c| 26 +++- drivers/media/platform/vsp1/vsp1_uds.c| 57 ++- drivers/media/platform/vsp1/vsp1_video.c | 182 --- drivers/media/platform/vsp1/vsp1_wpf.c| 24 ++- 9 files changed, 289 insertions(+), 116 deletions(-) base-commit: 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 -- git-series 0.9.1
[GIT PULL FOR v4.14] RC changes (part #1)
Hi Mauro, This is missing David Härdeman lirc cleanups, since they conflict with a revert for v4.13. What we do have is three new RC drivers: ZTE ZX family SoCs, and two GPIO drivers for IR TX (one using pwm and another bit banging). These two drivers are useful for the Raspberry Pi. Also RC core no longer has any dependency on CONFIG_MEDIA_SUPPORT. Thanks Sean The following changes since commit da48c948c263c9d87dfc64566b3373a858cc8aa2: media: fix warning on v4l2_subdev_call() result interpreted as bool (2017-07-26 13:43:17 -0400) are available in the git repository at: git://linuxtv.org/syoung/media_tree.git for-v4.14a for you to fetch changes up to 7af1952a935c062490dd697cd2cf7c65ee75dc19: [media] winbond-cir: buffer overrun during transmit (2017-08-04 15:59:50 +0100) Arvind Yadav (2): [media] imon: constify attribute_group structures [media] rc: constify attribute_group structures David Härdeman (1): [media] rc-core: consistent use of rc_repeat() Gustavo A. R. Silva (1): [media] sir_ir: remove unnecessary static in sir_interrupt() Heiner Kallweit (1): [media] rc: nuvoton: remove rudimentary transmit functionality Philipp Zabel (2): [media] st-rc: explicitly request exclusive reset control [media] rc: sunxi-cir: explicitly request exclusive reset control Sean Wang (4): [media] dt-bindings: media: mtk-cir: Add support for MT7622 SoC [media] rc: mtk-cir: add platform data to adapt into various hardware [media] rc: mtk-cir: add support for MediaTek MT7622 SoC [media] rc: mtk-cir: add MAINTAINERS entry for MediaTek CIR driver Sean Young (10): [media] rc-core: do not depend on MEDIA_SUPPORT [media] rc-core: rename input_name to device_name [media] rc: mce kbd decoder not needed for IR TX drivers [media] rc: gpio-ir-tx: add new driver [media] rc: pwm-ir-tx: add new driver [media] dt-bindings: pwm-ir-tx: Add support for PWM IR Transmitter [media] dt-bindings: gpio-ir-tx: add support for GPIO IR Transmitter [media] lirc_zilog: driver only sends LIRCCODE [media] mceusb: do not read data parameters unless required [media] winbond-cir: buffer overrun during transmit Shawn Guo (3): [media] rc: ir-nec-decoder: move scancode composing code into a shared function [media] dt-bindings: add bindings document for zx-irdec [media] rc: add zx-irdec remote control driver Yves Lemée (1): [media] lirc_zilog: Clean up lirc zilog error codes .../devicetree/bindings/leds/irled/gpio-ir-tx.txt | 14 ++ .../devicetree/bindings/leds/irled/pwm-ir-tx.txt | 13 ++ .../devicetree/bindings/media/mtk-cir.txt | 8 +- .../devicetree/bindings/media/zx-irdec.txt | 14 ++ MAINTAINERS| 17 ++ arch/arm/configs/imx_v6_v7_defconfig | 2 +- arch/arm/configs/omap2plus_defconfig | 2 +- arch/arm/configs/sunxi_defconfig | 2 +- arch/mips/configs/pistachio_defconfig | 2 +- drivers/hid/hid-picolcd_cir.c | 2 +- drivers/media/Kconfig | 17 +- drivers/media/cec/cec-core.c | 4 +- drivers/media/common/siano/smsir.c | 4 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 2 +- drivers/media/pci/cx88/cx88-input.c| 2 +- drivers/media/pci/dm1105/dm1105.c | 2 +- drivers/media/pci/mantis/mantis_common.h | 2 +- drivers/media/pci/mantis/mantis_input.c| 4 +- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 4 +- drivers/media/pci/smipcie/smipcie.h| 2 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/rc/Kconfig | 53 - drivers/media/rc/Makefile | 3 + drivers/media/rc/ati_remote.c | 2 +- drivers/media/rc/ene_ir.c | 4 +- drivers/media/rc/fintek-cir.c | 2 +- drivers/media/rc/gpio-ir-recv.c| 2 +- drivers/media/rc/gpio-ir-tx.c | 174 +++ drivers/media/rc/igorplugusb.c | 2 +- drivers/media/rc/iguanair.c| 2 +- drivers/media/rc/img-ir/img-ir-hw.c| 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 2 +- drivers/media/rc/imon.c| 6 +- drivers/media/rc/ir-hix5hd2.c | 2 +- drivers/media/rc/ir-mce_kbd-decoder.c | 6 + drivers/media/rc/ir-nec-decoder.c | 42
[GIT FIXES FOR v4.13] RC use-after-free fix
Hi Mauro, While testing with kasan I discovered a regression in v4.13. The change is a simple revert. Thanks Sean The following changes since commit da48c948c263c9d87dfc64566b3373a858cc8aa2: media: fix warning on v4l2_subdev_call() result interpreted as bool (2017-07-26 13:43:17 -0400) are available in the git repository at: git://linuxtv.org/syoung/media_tree.git for-v4.13e for you to fetch changes up to db50cbd947104f14e06ec107c098800b7442af3e: Revert "[media] lirc_dev: remove superfluous get/put_device() calls" (2017-08-04 15:48:46 +0100) Sean Young (1): Revert "[media] lirc_dev: remove superfluous get/put_device() calls" drivers/media/rc/lirc_dev.c | 4 1 file changed, 4 insertions(+)
[PATCH] Staging: bcm2048: fix bare use of 'unsigned' in radio-bcm2048.c
This is a patch to the radio-bcm2048.c file that fixes up a warning found by the checkpatch.pl tool. Signed-off-by: Branislav Radocaj--- drivers/staging/media/bcm2048/radio-bcm2048.c | 50 +-- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 38f72d069e27..90b8f05201ba 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2000,9 +2000,9 @@ static ssize_t bcm2048_##prop##_read(struct device *dev, \ return sprintf(buf, mask "\n", value); \ } -#define DEFINE_SYSFS_PROPERTY(prop, signal, size, mask, check) \ -property_write(prop, signal size, mask, check) \ -property_read(prop, size, mask) +#define DEFINE_SYSFS_PROPERTY(prop, signal_size, size, mask, check)\ +property_write(prop, signal_size, mask, check) \ +property_read(prop, size, mask) \ #define property_str_read(prop, size) \ static ssize_t bcm2048_##prop##_read(struct device *dev, \ @@ -2028,27 +2028,27 @@ static ssize_t bcm2048_##prop##_read(struct device *dev,\ return count; \ } -DEFINE_SYSFS_PROPERTY(power_state, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(mute, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(audio_route, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(dac_output, unsigned, int, "%u", 0) - -DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned, int, "%u", value > 3) - -DEFINE_SYSFS_PROPERTY(rds, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned, int, "%u", 0) -DEFINE_SYSFS_PROPERTY(rds_wline, unsigned, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(power_state, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(mute, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(audio_route, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(dac_output, unsigned int, int, "%u", 0) + +DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned int, int, "%u", value > 3) + +DEFINE_SYSFS_PROPERTY(rds, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned int, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(rds_wline, unsigned int, int, "%u", 0) property_read(rds_pi, unsigned int, "%x") property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1)) property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1)) @@ -2060,7 +2060,7 @@ property_read(region_bottom_frequency, unsigned int, "%u") property_read(region_top_frequency, unsigned int, "%u") property_signed_read(fm_carrier_error, int, "%d") property_signed_read(fm_rssi, int, "%d") -DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0) +DEFINE_SYSFS_PROPERTY(region, unsigned int, int, "%u", 0) static struct device_attribute attrs[] = { __ATTR(power_state, 0644, bcm2048_power_state_read, -- 2.11.0
[PATCH] Revert "[media] lirc_dev: remove superfluous get/put_device() calls"
This reverts commit 5be2b76a9ca4ea5fd3e221114d62eeb0d78267ca. Only when the lirc device is freed, should we drop our reference to rc_dev, else we the rc_dev is freed to early. If userspace has a file descriptor open during unplug, it goes bang. == BUG: KASAN: use-after-free in __lock_acquire+0x7bb/0x1e10 Read of size 8 at addr 8801d7d61ed0 by task ir-rec/2609 -snip- mutex_lock_nested+0x1b/0x20 ? mutex_lock_nested+0x1b/0x20 rc_close.part.6+0x20/0x60 [rc_core] rc_close+0x13/0x20 [rc_core] lirc_dev_fop_close+0x62/0xd0 [lirc_dev] __fput+0x236/0x410 ? fput+0xb0/0xb0 ? do_raw_spin_trylock+0x110/0x110 ? set_rq_offline.part.70+0xa0/0xa0 fput+0xe/0x10 task_work_run+0x116/0x180 ? task_work_cancel+0x170/0x170 ? _raw_spin_unlock+0x27/0x40 ? switch_task_namespaces+0x5f/0x90 do_exit+0x68b/0xe80 Signed-off-by: Sean Young--- drivers/media/rc/lirc_dev.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index db1e7b70c998..9080e39ea391 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -59,6 +59,8 @@ static void lirc_release(struct device *ld) { struct irctl *ir = container_of(ld, struct irctl, dev); + put_device(ir->dev.parent); + if (ir->buf_internal) { lirc_buffer_free(ir->buf); kfree(ir->buf); @@ -218,6 +220,8 @@ int lirc_register_driver(struct lirc_driver *d) mutex_unlock(_dev_lock); + get_device(ir->dev.parent); + dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", ir->d.name, ir->d.minor); -- 2.13.3
[PATCH 1/5] [media] cx18: constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall--- drivers/media/pci/cx18/cx18-streams.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 3c45e007..81d06c1 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -240,7 +240,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) list_add_tail(>vb.queue, >vb_capture); } -static struct videobuf_queue_ops cx18_videobuf_qops = { +static const struct videobuf_queue_ops cx18_videobuf_qops = { .buf_setup= buffer_setup, .buf_prepare = buffer_prepare, .buf_queue= buffer_queue,
[PATCH 2/5] [media] atomisp: constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall--- drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c index c151c84..d8cfed3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c @@ -643,14 +643,14 @@ static void atomisp_buf_release_output(struct videobuf_queue *vq, vb->state = VIDEOBUF_NEEDS_INIT; } -static struct videobuf_queue_ops videobuf_qops = { +static const struct videobuf_queue_ops videobuf_qops = { .buf_setup = atomisp_buf_setup, .buf_prepare= atomisp_buf_prepare, .buf_queue = atomisp_buf_queue, .buf_release= atomisp_buf_release, }; -static struct videobuf_queue_ops videobuf_qops_output = { +static const struct videobuf_queue_ops videobuf_qops_output = { .buf_setup = atomisp_buf_setup_output, .buf_prepare= atomisp_buf_prepare_output, .buf_queue = atomisp_buf_queue_output,
[PATCH 0/5] constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. --- drivers/media/pci/cx18/cx18-streams.c |2 +- drivers/media/usb/cx231xx/cx231xx-417.c |2 +- drivers/media/usb/cx231xx/cx231xx-video.c |2 +- drivers/media/usb/tm6000/tm6000-video.c |2 +- drivers/media/usb/zr364xx/zr364xx.c |2 +- drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c |4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-)
[PATCH 3/5] [media] cx231xx: constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // In the first case, there is a second commented call to videobuf_queue_sg_init with the structure as the second argument. If that code will be uncommented, the const will remain correct, because the second parameter of that function is also const. Signed-off-by: Julia Lawall--- drivers/media/usb/cx231xx/cx231xx-417.c |2 +- drivers/media/usb/cx231xx/cx231xx-video.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 8d5eb99..d538fa4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1490,7 +1490,7 @@ static void bb_buf_release(struct videobuf_queue *q, free_buffer(q, buf); } -static struct videobuf_queue_ops cx231xx_qops = { +static const struct videobuf_queue_ops cx231xx_qops = { .buf_setup= bb_buf_setup, .buf_prepare = bb_buf_prepare, .buf_queue= bb_buf_queue, diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index f67f868..179b848 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -859,7 +859,7 @@ static void buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -static struct videobuf_queue_ops cx231xx_video_qops = { +static const struct videobuf_queue_ops cx231xx_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue,
[PATCH 4/5] [media] tm6000: constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall--- drivers/media/usb/tm6000/tm6000-video.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index cec1321..ec8c4d2 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -801,7 +801,7 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb free_buffer(vq, buf); } -static struct videobuf_queue_ops tm6000_video_qops = { +static const struct videobuf_queue_ops tm6000_video_qops = { .buf_setup = buffer_setup, .buf_prepare= buffer_prepare, .buf_queue = buffer_queue,
[PATCH 5/5] [media] zr364xx: constify videobuf_queue_ops structures
These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall--- drivers/media/usb/zr364xx/zr364xx.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index efdcd5b..24d5860 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -439,7 +439,7 @@ static void buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -static struct videobuf_queue_ops zr364xx_video_qops = { +static const struct videobuf_queue_ops zr364xx_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue,
Re: [PATCH v1 5/5] [media] stm32-dcmi: g_/s_selection crop support
On 28/07/17 12:05, Hugues Fruchet wrote: > Implements g_/s_selection crop support by using DCMI crop > hardware feature. > User can first get the maximum supported resolution of the sensor > by calling g_selection(V4L2_SEL_TGT_CROP_BOUNDS). > Then user call to s_selection(V4L2_SEL_TGT_CROP) will reset sensor > to its maximum resolution and crop request is saved for later usage > in s_fmt(). > Next call to s_fmt() will check if sensor can do frame size request > with crop request. If sensor supports only discrete frame sizes, > the frame size which is larger than user request is selected in > order to be able to match the crop request. Then s_fmt() resolution > user request is adjusted to match crop request resolution. > > Signed-off-by: Hugues Fruchet> --- > drivers/media/platform/stm32/stm32-dcmi.c | 367 > +- > 1 file changed, 363 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/stm32/stm32-dcmi.c > b/drivers/media/platform/stm32/stm32-dcmi.c > index 2be56b6..f1fb0b3 100644 > --- a/drivers/media/platform/stm32/stm32-dcmi.c > +++ b/drivers/media/platform/stm32/stm32-dcmi.c > @@ -33,6 +33,7 @@ > #include > #include > #include > +#include > #include > > #define DRV_NAME "stm32-dcmi" > @@ -107,6 +108,11 @@ struct dcmi_format { > u8 bpp; > }; > > +struct dcmi_framesize { > + u32 width; > + u32 height; > +}; > + > struct dcmi_buf { > struct vb2_v4l2_buffer vb; > boolprepared; > @@ -131,10 +137,16 @@ struct stm32_dcmi { > struct v4l2_async_notifier notifier; > struct dcmi_graph_entityentity; > struct v4l2_format fmt; > + struct v4l2_rectcrop; > + booldo_crop; > > const struct dcmi_format**sd_formats; > unsigned intnb_of_sd_formats; > const struct dcmi_format*sd_format; > + struct dcmi_framesize *sd_framesizes; > + unsigned intnb_of_sd_framesizes; num_of_sd_framesizes is better. > + struct dcmi_framesize sd_framesize; > + struct v4l2_rectsd_bounds; > > /* Protect this data structure */ > struct mutexlock; > @@ -325,6 +337,28 @@ static int dcmi_start_capture(struct stm32_dcmi *dcmi) > return 0; > } > > +static void dcmi_set_crop(struct stm32_dcmi *dcmi) > +{ > + u32 size, start; > + > + /* Crop resolution */ > + size = ((dcmi->crop.height - 1) << 16) | > + ((dcmi->crop.width << 1) - 1); > + reg_write(dcmi->regs, DCMI_CWSIZE, size); > + > + /* Crop start point */ > + start = ((dcmi->crop.top) << 16) | > + ((dcmi->crop.left << 1)); > + reg_write(dcmi->regs, DCMI_CWSTRT, start); > + > + dev_dbg(dcmi->dev, "Cropping to %ux%u@%u:%u\n", > + dcmi->crop.width, dcmi->crop.height, > + dcmi->crop.left, dcmi->crop.top); > + > + /* Enable crop */ > + reg_set(dcmi->regs, DCMI_CR, CR_CROP); > +} > + > static irqreturn_t dcmi_irq_thread(int irq, void *arg) > { > struct stm32_dcmi *dcmi = arg; > @@ -540,6 +574,10 @@ static int dcmi_start_streaming(struct vb2_queue *vq, > unsigned int count) > > reg_write(dcmi->regs, DCMI_CR, val); > > + /* Set crop */ > + if (dcmi->do_crop) > + dcmi_set_crop(dcmi); > + > /* Enable dcmi */ > reg_set(dcmi->regs, DCMI_CR, CR_ENABLE); > > @@ -697,10 +735,37 @@ static const struct dcmi_format > *find_format_by_fourcc(struct stm32_dcmi *dcmi, > return NULL; > } > > +static void __find_outer_frame_size(struct stm32_dcmi *dcmi, > + struct v4l2_pix_format *pix, > + struct dcmi_framesize *framesize) > +{ > + struct dcmi_framesize *match = NULL; > + unsigned int i; > + unsigned int min_err = UINT_MAX; > + > + for (i = 0; i < dcmi->nb_of_sd_framesizes; i++) { > + struct dcmi_framesize *fsize = >sd_framesizes[i]; > + int w_err = (fsize->width - pix->width); > + int h_err = (fsize->height - pix->height); > + int err = w_err + h_err; > + > + if ((w_err >= 0) && (h_err >= 0) && (err < min_err)) { > + min_err = err; > + match = fsize; > + } > + } > + if (!match) > + match = >sd_framesizes[0]; > + > + *framesize = *match; > +} > + > static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, > - const struct dcmi_format **sd_format) > + const struct dcmi_format **sd_format, > + struct dcmi_framesize *sd_framesize) > { > const struct dcmi_format *sd_fmt; > + struct dcmi_framesize sd_fsize; > struct v4l2_pix_format *pix = >fmt.pix; > struct
Re: [PATCH v1 4/5] [media] stm32-dcmi: set default format at open()
On 28/07/17 12:05, Hugues Fruchet wrote: > Ensure that we start with default pixel format and resolution > when opening a new instance. Why? The format is persistent in V4L2 and (re)opening the video device shouldn't change the format. Suppose you use v4l2-ctl to set up a format. E.g. v4l2-ctl -v width=320,height-240. Now run v4l2-ctl -V to get the format and with this code it would suddenly be back to the default! You set up the default format in the dcmi_graph_notify_complete, but after that it is only changed if userspace explicitly requests it. Regards, Hans > > Signed-off-by: Hugues Fruchet> --- > drivers/media/platform/stm32/stm32-dcmi.c | 49 > ++- > 1 file changed, 28 insertions(+), 21 deletions(-) > > diff --git a/drivers/media/platform/stm32/stm32-dcmi.c > b/drivers/media/platform/stm32/stm32-dcmi.c > index 4733d1f..2be56b6 100644 > --- a/drivers/media/platform/stm32/stm32-dcmi.c > +++ b/drivers/media/platform/stm32/stm32-dcmi.c > @@ -890,6 +890,28 @@ static int dcmi_enum_frameintervals(struct file *file, > void *fh, > return 0; > } > > +static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) > +{ > + struct v4l2_format f = { > + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, > + .fmt.pix = { > + .width = CIF_WIDTH, > + .height = CIF_HEIGHT, > + .field = V4L2_FIELD_NONE, > + .pixelformat= dcmi->sd_formats[0]->fourcc, > + }, > + }; > + int ret; > + > + ret = dcmi_try_fmt(dcmi, , NULL); > + if (ret) > + return ret; > + dcmi->sd_format = dcmi->sd_formats[0]; > + dcmi->fmt = f; > + > + return 0; > +} > + > static const struct of_device_id stm32_dcmi_of_match[] = { > { .compatible = "st,stm32-dcmi"}, > { /* end node */ }, > @@ -916,7 +938,13 @@ static int dcmi_open(struct file *file) > if (ret < 0 && ret != -ENOIOCTLCMD) > goto fh_rel; > > + ret = dcmi_set_default_fmt(dcmi); > + if (ret) > + goto power_off; > + > ret = dcmi_set_fmt(dcmi, >fmt); > + > +power_off: > if (ret) > v4l2_subdev_call(sd, core, s_power, 0); > fh_rel: > @@ -991,27 +1019,6 @@ static int dcmi_release(struct file *file) > .read = vb2_fop_read, > }; > > -static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) > -{ > - struct v4l2_format f = { > - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, > - .fmt.pix = { > - .width = CIF_WIDTH, > - .height = CIF_HEIGHT, > - .field = V4L2_FIELD_NONE, > - .pixelformat= dcmi->sd_formats[0]->fourcc, > - }, > - }; > - int ret; > - > - ret = dcmi_try_fmt(dcmi, , NULL); > - if (ret) > - return ret; > - dcmi->sd_format = dcmi->sd_formats[0]; > - dcmi->fmt = f; > - return 0; > -} > - > static const struct dcmi_format dcmi_formats[] = { > { > .fourcc = V4L2_PIX_FMT_RGB565, >
Re: [PATCH v3 04/23] dt-bindings: media: Binding document for Qualcomm Camera subsystem driver
Hi Sakari, Thank you for the review. On 20.07.2017 13:13, Sakari Ailus wrote: > Hi Todor, > > On Mon, Jul 17, 2017 at 01:33:30PM +0300, Todor Tomov wrote: >> Add DT binding document for Qualcomm Camera subsystem driver. >> >> CC: Rob Herring>> CC: devicet...@vger.kernel.org >> Signed-off-by: Todor Tomov >> --- >> .../devicetree/bindings/media/qcom,camss.txt | 191 >> + >> 1 file changed, 191 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/media/qcom,camss.txt >> >> diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt >> b/Documentation/devicetree/bindings/media/qcom,camss.txt >> new file mode 100644 >> index 000..f698498 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt >> @@ -0,0 +1,191 @@ >> +Qualcomm Camera Subsystem >> + >> +* Properties >> + >> +- compatible: >> +Usage: required >> +Value type: >> +Definition: Should contain: >> +- "qcom,msm8916-camss" >> +- reg: >> +Usage: required >> +Value type: >> +Definition: Register ranges as listed in the reg-names property. >> +- reg-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "csiphy0" >> +- "csiphy0_clk_mux" >> +- "csiphy1" >> +- "csiphy1_clk_mux" >> +- "csid0" >> +- "csid1" >> +- "ispif" >> +- "csi_clk_mux" >> +- "vfe0" >> +- interrupts: >> +Usage: required >> +Value type: >> +Definition: Interrupts as listed in the interrupt-names property. >> +- interrupt-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "csiphy0" >> +- "csiphy1" >> +- "csid0" >> +- "csid1" >> +- "ispif" >> +- "vfe0" >> +- power-domains: >> +Usage: required >> +Value type: >> +Definition: A phandle and power domain specifier pairs to the >> +power domain which is responsible for collapsing >> +and restoring power to the peripheral. >> +- clocks: >> +Usage: required >> +Value type: >> +Definition: A list of phandle and clock specifier pairs as listed >> +in clock-names property. >> +- clock-names: >> +Usage: required >> +Value type: >> +Definition: Should contain the following entries: >> +- "camss_top_ahb" >> +- "ispif_ahb" >> +- "csiphy0_timer" >> +- "csiphy1_timer" >> +- "csi0_ahb" >> +- "csi0" >> +- "csi0_phy" >> +- "csi0_pix" >> +- "csi0_rdi" >> +- "csi1_ahb" >> +- "csi1" >> +- "csi1_phy" >> +- "csi1_pix" >> +- "csi1_rdi" >> +- "camss_ahb" >> +- "camss_vfe_vfe" >> +- "camss_csi_vfe" >> +- "iface" >> +- "bus" >> +- vdda-supply: >> +Usage: required >> +Value type: >> +Definition: A phandle to voltage supply for CSI2. >> +- iommus: >> +Usage: required >> +Value type: >> +Definition: A list of phandle and IOMMU specifier pairs. >> + >> +* Nodes >> + >> +- ports: >> +Usage: required >> +Definition: As described in video-interfaces.txt in same directory. >> +Properties: >> +- reg: >> +Usage: required >> +Value type: >> +Definition: Selects CSI2 PHY interface - PHY0 or PHY1. >> +Endpoint node properties: >> +- clock-lanes: >> +Usage: required >> +Value type: >> +Definition: The clock lane. >> +- data-lanes: >> +Usage: required >> +Value type: >> +Definition: An array of data lanes. >> + >> +* An Example >> + >> +camss: camss@1b0 { >> +compatible = "qcom,msm8916-camss"; >> +reg = <0x1b0ac00 0x200>, >> +<0x1b00030 0x4>, >> +<0x1b0b000 0x200>, >> +<0x1b00038 0x4>, >> +<0x1b08000 0x100>, >> +<0x1b08400 0x100>, >> +<0x1b0a000 0x500>, >> +<0x1b00020 0x10>, >> +<0x1b1 0x1000>; >> +reg-names = "csiphy0", >> +"csiphy0_clk_mux", >> +"csiphy1", >> +"csiphy1_clk_mux", >> +"csid0", >> +"csid1", >> +"ispif", >> +"csi_clk_mux", >> +"vfe0"; >> +interrupts = , >> +
Re: [PATCH v1 3/5] [media] stm32-dcmi: cleanup variable/fields namings
On 28/07/17 12:05, Hugues Fruchet wrote: > Uniformize "pixfmt" variables to "pix". > Change "current_fmt" & "dcmi_fmt" variables to variables > with "sd_" prefix to explicitly refer to subdev format. > > Signed-off-by: Hugues Fruchet> --- > drivers/media/platform/stm32/stm32-dcmi.c | 103 > -- > 1 file changed, 54 insertions(+), 49 deletions(-) > > diff --git a/drivers/media/platform/stm32/stm32-dcmi.c > b/drivers/media/platform/stm32/stm32-dcmi.c > index 526e354..4733d1f 100644 > --- a/drivers/media/platform/stm32/stm32-dcmi.c > +++ b/drivers/media/platform/stm32/stm32-dcmi.c > @@ -132,9 +132,9 @@ struct stm32_dcmi { > struct dcmi_graph_entityentity; > struct v4l2_format fmt; > > - const struct dcmi_format**user_formats; > - unsigned intnum_user_formats; > - const struct dcmi_format*current_fmt; > + const struct dcmi_format**sd_formats; > + unsigned intnb_of_sd_formats; Please rename this to num_of_sd_formats. 'nb' is non-standard and non-obvious. Other than that this patch looks good and is a nice improvement. Regards, Hans > + const struct dcmi_format*sd_format; > > /* Protect this data structure */ > struct mutexlock; > @@ -684,12 +684,12 @@ static int dcmi_g_fmt_vid_cap(struct file *file, void > *priv, > static const struct dcmi_format *find_format_by_fourcc(struct stm32_dcmi > *dcmi, > unsigned int fourcc) > { > - unsigned int num_formats = dcmi->num_user_formats; > + unsigned int num_formats = dcmi->nb_of_sd_formats; > const struct dcmi_format *fmt; > unsigned int i; > > for (i = 0; i < num_formats; i++) { > - fmt = dcmi->user_formats[i]; > + fmt = dcmi->sd_formats[i]; > if (fmt->fourcc == fourcc) > return fmt; > } > @@ -698,40 +698,42 @@ static const struct dcmi_format > *find_format_by_fourcc(struct stm32_dcmi *dcmi, > } > > static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, > - const struct dcmi_format **current_fmt) > + const struct dcmi_format **sd_format) > { > - const struct dcmi_format *dcmi_fmt; > - struct v4l2_pix_format *pixfmt = >fmt.pix; > + const struct dcmi_format *sd_fmt; > + struct v4l2_pix_format *pix = >fmt.pix; > struct v4l2_subdev_pad_config pad_cfg; > struct v4l2_subdev_format format = { > .which = V4L2_SUBDEV_FORMAT_TRY, > }; > int ret; > > - dcmi_fmt = find_format_by_fourcc(dcmi, pixfmt->pixelformat); > - if (!dcmi_fmt) { > - dcmi_fmt = dcmi->user_formats[dcmi->num_user_formats - 1]; > - pixfmt->pixelformat = dcmi_fmt->fourcc; > + sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); > + if (!sd_fmt) { > + sd_fmt = dcmi->sd_formats[dcmi->nb_of_sd_formats - 1]; > + pix->pixelformat = sd_fmt->fourcc; > } > > /* Limit to hardware capabilities */ > - pixfmt->width = clamp(pixfmt->width, MIN_WIDTH, MAX_WIDTH); > - pixfmt->height = clamp(pixfmt->height, MIN_HEIGHT, MAX_HEIGHT); > + pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); > + pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT); > > - v4l2_fill_mbus_format(, pixfmt, dcmi_fmt->mbus_code); > + v4l2_fill_mbus_format(, pix, sd_fmt->mbus_code); > ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, > _cfg, ); > if (ret < 0) > return ret; > > - v4l2_fill_pix_format(pixfmt, ); > + /* Update pix regarding to what sensor can do */ > + v4l2_fill_pix_format(pix, ); > > - pixfmt->field = V4L2_FIELD_NONE; > - pixfmt->bytesperline = pixfmt->width * dcmi_fmt->bpp; > - pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; > > - if (current_fmt) > - *current_fmt = dcmi_fmt; > + pix->field = V4L2_FIELD_NONE; > + pix->bytesperline = pix->width * sd_fmt->bpp; > + pix->sizeimage = pix->bytesperline * pix->height; > + > + if (sd_format) > + *sd_format = sd_fmt; > > return 0; > } > @@ -741,22 +743,25 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct > v4l2_format *f) > struct v4l2_subdev_format format = { > .which = V4L2_SUBDEV_FORMAT_ACTIVE, > }; > - const struct dcmi_format *current_fmt; > + const struct dcmi_format *sd_format; > + struct v4l2_mbus_framefmt *mf = > + struct v4l2_pix_format *pix = >fmt.pix; > int ret; > > - ret = dcmi_try_fmt(dcmi, f, _fmt); > + ret = dcmi_try_fmt(dcmi, f, _format); > if (ret) > return ret; > > - v4l2_fill_mbus_format(, >fmt.pix, > -
[GIT PULL FOR v4.14] Fixes, fixes, ever more fixes :-)
Lots of constify patches and some random other fixes. Except for the solo patch which is an actual feature enhancement. Regards, Hans The following changes since commit da48c948c263c9d87dfc64566b3373a858cc8aa2: media: fix warning on v4l2_subdev_call() result interpreted as bool (2017-07-26 13:43:17 -0400) are available in the git repository at: git://linuxtv.org/hverkuil/media_tree.git for-v4.14e for you to fetch changes up to 09408627c4d001f4df6ede6d22eb27c2945c455c: v4l2-compat-ioctl32: Fix timespec conversion (2017-08-04 13:27:18 +0200) Anton Sviridenko (1): solo6x10: export hardware GPIO pins 8:31 to gpiolib interface Arvind Yadav (27): marvell-ccic: constify pci_device_id. netup_unidvb: constify pci_device_id. cx23885: constify pci_device_id. meye: constify pci_device_id. pluto2: constify pci_device_id. dm1105: constify pci_device_id. zoran: constify pci_device_id. bt8xx: constify pci_device_id. bt8xx: bttv: constify pci_device_id. ivtv: constify pci_device_id. cobalt: constify pci_device_id. b2c2: constify pci_device_id. saa7164: constify pci_device_id. pt1: constify pci_device_id. mantis: constify pci_device_id. mantis: hopper_cards: constify pci_device_id. cx18: constify pci_device_id. radio: constify pci_device_id. drv-intf: saa7146: constify pci_device_id. ttpci: budget: constify pci_device_id. ttpci: budget-patch: constify pci_device_id. ttpci: budget-ci: constify pci_device_id. ttpci: budget-av: constify pci_device_id. ttpci: av7110: constify pci_device_id. saa7146: mxb: constify pci_device_id. saa7146: hexium_orion: constify pci_device_id. saa7146: hexium_gemini: constify pci_device_id. Dan Carpenter (1): adv7604: Prevent out of bounds access Daniel Mentz (2): v4l2-compat-ioctl32: Copy v4l2_window->global_alpha v4l2-compat-ioctl32: Fix timespec conversion Julia Lawall (1): DaVinci-VPBE: constify vpbe_dev_ops Peter Rosin (3): cx231xx: fail probe if i2c_add_adapter fails cx231xx: drop return value of cx231xx_i2c_unregister cx231xx: only unregister successfully registered i2c adapters drivers/media/i2c/adv7604.c| 4 +-- drivers/media/pci/b2c2/flexcop-pci.c | 2 +- drivers/media/pci/bt8xx/bt878.c| 2 +- drivers/media/pci/bt8xx/bttv-driver.c | 2 +- drivers/media/pci/cobalt/cobalt-driver.c | 2 +- drivers/media/pci/cx18/cx18-driver.c | 2 +- drivers/media/pci/cx23885/cx23885-core.c | 2 +- drivers/media/pci/dm1105/dm1105.c | 2 +- drivers/media/pci/ivtv/ivtv-driver.c | 2 +- drivers/media/pci/mantis/hopper_cards.c| 2 +- drivers/media/pci/mantis/mantis_cards.c| 2 +- drivers/media/pci/meye/meye.c | 2 +- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 2 +- drivers/media/pci/pluto2/pluto2.c | 2 +- drivers/media/pci/pt1/pt1.c| 2 +- drivers/media/pci/saa7146/hexium_gemini.c | 2 +- drivers/media/pci/saa7146/hexium_orion.c | 2 +- drivers/media/pci/saa7146/mxb.c| 2 +- drivers/media/pci/saa7164/saa7164-core.c | 2 +- drivers/media/pci/solo6x10/solo6x10-gpio.c | 97 + drivers/media/pci/solo6x10/solo6x10.h | 5 +++ drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/budget-av.c| 2 +- drivers/media/pci/ttpci/budget-ci.c| 2 +- drivers/media/pci/ttpci/budget-patch.c | 2 +- drivers/media/pci/ttpci/budget.c | 2 +- drivers/media/pci/zoran/zoran_card.c | 2 +- drivers/media/platform/davinci/vpbe.c | 2 +- drivers/media/platform/marvell-ccic/cafe-driver.c | 2 +- drivers/media/radio/radio-maxiradio.c | 2 +- drivers/media/usb/cx231xx/cx231xx-core.c | 3 ++ drivers/media/usb/cx231xx/cx231xx-i2c.c| 8 ++--- drivers/media/usb/cx231xx/cx231xx.h| 4 +-- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 10 -- include/media/drv-intf/saa7146.h | 2 +- 35 files changed, 148 insertions(+), 39 deletions(-)
[PATCH] v4l2-compat-ioctl32.c: add missing controls to, ctrl_is_pointer
We need to find a better method for this. But for now just add the missing pointer controls to this list. Also properly mask the id. The high flag bits shouldn't be used with these ioctls, but it certainly doesn't hurt. Signed-off-by: Hans Verkuil--- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 90827073066f..afae914b8099 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -674,9 +674,14 @@ struct v4l2_ext_control32 { type STRING is a pointer type. */ static inline int ctrl_is_pointer(u32 id) { - switch (id) { + switch (id & V4L2_CTRL_ID_MASK) { case V4L2_CID_RDS_TX_PS_NAME: case V4L2_CID_RDS_TX_RADIO_TEXT: + case V4L2_CID_RDS_RX_PS_NAME: + case V4L2_CID_RDS_RX_RADIO_TEXT: + case V4L2_CID_DETECT_MD_REGION_GRID: + case V4L2_CID_DETECT_MD_THRESHOLD_GRID: + case V4L2_CID_RDS_TX_ALT_FREQS: return 1; default: return 0; -- 2.13.2
[PATCH] v4l2-compat-ioctl32.c: add capabilities field to, v4l2_input32
The v4l2_input32 struct wasn't updated when this field was added. It didn't cause a failure in the compat code, but it is better to keep it in sync with v4l2_input to avoid confusion. Signed-off-by: Hans Verkuil--- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 6f52970f8b54..90827073066f 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -627,7 +627,8 @@ struct v4l2_input32 { __u32tuner; /* Associated tuner */ compat_u64 std; __u32status; - __u32reserved[4]; + __u32capabilities; + __u32reserved[3]; }; /* The 64-bit v4l2_input struct has extra padding at the end of the struct. -- 2.13.2
[PATCH 2/2] [media] winbond-cir: buffer overrun during transmit
We're reading beyond the buffer before checking its length. BUG: KASAN: slab-out-of-bounds in wbcir_irq_tx Signed-off-by: Sean Young--- drivers/media/rc/winbond-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index ea7be6d35ff8..a18eb232ed81 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -429,7 +429,7 @@ wbcir_irq_tx(struct wbcir_data *data) bytes[used] = byte; } - while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen) + while (data->txoff != data->txlen && data->txbuf[data->txoff] == 0) data->txoff++; if (used == 0) { -- 2.13.3
[PATCH 1/2] [media] mceusb: do not read data parameters unless required
This causes out-of-bounds read on device probe. BUG: KASAN: slab-out-of-bounds in mceusb_dev_printdata+0xdc/0x830 [mceusb] Signed-off-by: Sean Young--- drivers/media/rc/mceusb.c | 36 +--- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index d9c7bbd25253..60258889b162 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -538,12 +538,12 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd) return datasize; } -static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, -int buf_len, int offset, int len, bool out) +static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, +int offset, int len, bool out) { #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) char *inout; - u8 cmd, subcmd, data1, data2, data3, data4; + u8 cmd, subcmd, *data; struct device *dev = ir->dev; int start, skip = 0; u32 carrier, period; @@ -564,17 +564,14 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, start = offset + skip; cmd= buf[start] & 0xff; subcmd = buf[start + 1] & 0xff; - data1 = buf[start + 2] & 0xff; - data2 = buf[start + 3] & 0xff; - data3 = buf[start + 4] & 0xff; - data4 = buf[start + 5] & 0xff; + data = buf + start + 2; switch (cmd) { case MCE_CMD_NULL: if (subcmd == MCE_CMD_NULL) break; if ((subcmd == MCE_CMD_PORT_SYS) && - (data1 == MCE_CMD_RESUME)) + (data[0] == MCE_CMD_RESUME)) dev_dbg(dev, "Device resume requested"); else dev_dbg(dev, "Unknown command 0x%02x 0x%02x", @@ -585,7 +582,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, case MCE_RSP_EQEMVER: if (!out) dev_dbg(dev, "Emulator interface version %x", -data1); +data[0]); break; case MCE_CMD_G_REVISION: if (len == 2) @@ -603,13 +600,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, case MCE_RSP_EQWAKEVERSION: if (!out) dev_dbg(dev, "Wake version, proto: 0x%02x, payload: 0x%02x, address: 0x%02x, version: 0x%02x", -data1, data2, data3, data4); + data[0], data[1], data[2], data[3]); break; case MCE_RSP_GETPORTSTATUS: if (!out) /* We use data1 + 1 here, to match hw labels */ dev_dbg(dev, "TX port %d: blaster is%s connected", -data1 + 1, data4 ? " not" : ""); +data[0] + 1, data[3] ? " not" : ""); break; case MCE_CMD_FLASHLED: dev_dbg(dev, "Attempting to flash LED"); @@ -630,11 +627,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_CMD_UNKNOWN: dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x", -data1, data2); + data[0], data[1]); break; case MCE_RSP_EQIRCFS: - period = DIV_ROUND_CLOSEST( - (1U << data1 * 2) * (data2 + 1), 10); + period = DIV_ROUND_CLOSEST((1U << data[0] * 2) * + (data[1] + 1), 10); if (!period) break; carrier = (1000 * 1000) / period; @@ -646,11 +643,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_RSP_EQIRTXPORTS: dev_dbg(dev, "%s transmit blaster mask of 0x%02x", -inout, data1); +inout, data[0]); break; case MCE_RSP_EQIRTIMEOUT: /* value is in units of 50us, so x*50/1000 ms */ - period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000; + period = ((data[0] << 8) | data[1]) * + MCE_TIME_UNIT / 1000; dev_dbg(dev, "%s receive timeout of %d ms", inout, period);
[PATCH 5/5] stm32-cec: use CEC_CAP_DEFAULTS
From: Hans VerkuilUse the new CEC_CAP_DEFAULTS define in this driver. Signed-off-by: Hans Verkuil --- drivers/media/platform/stm32/stm32-cec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c index 89904096d0a9..ed332a1a39b1 100644 --- a/drivers/media/platform/stm32/stm32-cec.c +++ b/drivers/media/platform/stm32/stm32-cec.c @@ -246,9 +246,7 @@ static const struct regmap_config stm32_cec_regmap_cfg = { static int stm32_cec_probe(struct platform_device *pdev) { - u32 caps = CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | - CEC_CAP_TRANSMIT | CEC_CAP_RC | CEC_CAP_PHYS_ADDR | - CEC_MODE_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL; struct resource *res; struct stm32_cec *cec; void __iomem *mmio; -- 2.13.2
[PATCH 1/5] media/cec.h: add CEC_CAP_DEFAULTS
From: Hans VerkuilThe CEC_CAP_LOG_ADDRS, CEC_CAP_TRANSMIT, CEC_CAP_PASSTHROUGH and CEC_CAP_RC capabilities are normally always present. Add a CEC_CAP_DEFAULTS define that ORs these four caps to simplify drivers. Signed-off-by: Hans Verkuil --- include/media/cec.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/media/cec.h b/include/media/cec.h index 224a6e225c52..1bec7bde4792 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -31,6 +31,9 @@ #include #include +#define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \ + CEC_CAP_PASSTHROUGH | CEC_CAP_RC) + /** * struct cec_devnode - cec device node * @dev: cec device -- 2.13.2
[PATCH 2/5] adv*/vivid/pulse8/rainshadow: cec: use CEC_CAP_DEFAULTS
From: Hans VerkuilUse the new CEC_CAP_DEFAULTS define in the adv, vivid, pulse8 and rainshadow CEC drivers. Signed-off-by: Hans Verkuil --- drivers/media/i2c/adv7511.c | 3 +-- drivers/media/i2c/adv7604.c | 3 +-- drivers/media/i2c/adv7842.c | 3 +-- drivers/media/platform/vivid/vivid-cec.c | 3 +-- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +-- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index ec100fbf7c4d..0cdfc2b14121 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1927,8 +1927,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * #if IS_ENABLED(CONFIG_VIDEO_ADV7511_CEC) state->cec_adap = cec_allocate_adapter(_cec_adap_ops, - state, dev_name(>dev), CEC_CAP_TRANSMIT | - CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | CEC_CAP_RC, + state, dev_name(>dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); if (IS_ERR(state->cec_adap)) { err = PTR_ERR(state->cec_adap); diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index de0207b3d63d..1430b706cdf1 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3515,8 +3515,7 @@ static int adv76xx_probe(struct i2c_client *client, #if IS_ENABLED(CONFIG_VIDEO_ADV7604_CEC) state->cec_adap = cec_allocate_adapter(_cec_adap_ops, state, dev_name(>dev), - CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV76XX_MAX_ADDRS); + CEC_CAP_DEFAULTS, ADV76XX_MAX_ADDRS); if (IS_ERR(state->cec_adap)) { err = PTR_ERR(state->cec_adap); goto err_entity; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 6d01f9c82b8f..63ac5a09c587 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3568,8 +3568,7 @@ static int adv7842_probe(struct i2c_client *client, #if IS_ENABLED(CONFIG_VIDEO_ADV7842_CEC) state->cec_adap = cec_allocate_adapter(_cec_adap_ops, state, dev_name(>dev), - CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV7842_MAX_ADDRS); + CEC_CAP_DEFAULTS, ADV7842_MAX_ADDRS); if (IS_ERR(state->cec_adap)) { err = PTR_ERR(state->cec_adap); goto err_entity; diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index e15705758969..43992fa92a88 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -219,8 +219,7 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, bool is_source) { char name[sizeof(dev->vid_out_dev.name) + 2]; - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL; snprintf(name, sizeof(name), "%s%d", is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index 3b0ee8c9bc26..7d880441b0eb 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -642,8 +642,7 @@ static const struct cec_adap_ops pulse8_cec_adap_ops = { static int pulse8_connect(struct serio *serio, struct serio_driver *drv) { - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; struct pulse8 *pulse8; int err = -ENOMEM; struct cec_log_addrs log_addrs = {}; diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index c63f318752fd..650eab7e79b2 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -309,8 +309,7 @@ static const struct cec_adap_ops rain_cec_adap_ops = { static int rain_connect(struct serio *serio, struct serio_driver *drv) { - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; struct rain *rain; int err = -ENOMEM; struct cec_log_addrs log_addrs = {}; -- 2.13.2
[PATCH 0/5] cec: add CEC_CAP_DEFAULTS define
From: Hans VerkuilFour CEC capabilities are normally always used. So combine them in a single CEC_CAP_DEFAULTS define. This also avoids missing one of these caps as happened in the stih-cec driver. Regards, Hans Hans Verkuil (5): media/cec.h: add CEC_CAP_DEFAULTS adv*/vivid/pulse8/rainshadow: cec: use CEC_CAP_DEFAULTS s5p-cec: use CEC_CAP_DEFAULTS stih-cec: use CEC_CAP_DEFAULTS stm32-cec: use CEC_CAP_DEFAULTS drivers/media/i2c/adv7511.c | 3 +-- drivers/media/i2c/adv7604.c | 3 +-- drivers/media/i2c/adv7842.c | 3 +-- drivers/media/platform/s5p-cec/s5p_cec.c | 7 ++- drivers/media/platform/sti/cec/stih-cec.c | 4 +--- drivers/media/platform/stm32/stm32-cec.c | 4 +--- drivers/media/platform/vivid/vivid-cec.c | 3 +-- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +-- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 3 +-- include/media/cec.h | 3 +++ 10 files changed, 13 insertions(+), 23 deletions(-) -- 2.13.2
[PATCH 3/5] s5p-cec: use CEC_CAP_DEFAULTS
From: Hans VerkuilUse the new CEC_CAP_DEFAULTS define in the s5p-cec driver. Signed-off-by: Hans Verkuil --- drivers/media/platform/s5p-cec/s5p_cec.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c index b2a5694192fa..0347d1740c27 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.c +++ b/drivers/media/platform/s5p-cec/s5p_cec.c @@ -219,11 +219,8 @@ static int s5p_cec_probe(struct platform_device *pdev) if (IS_ERR(cec->notifier)) return PTR_ERR(cec->notifier); - cec->adap = cec_allocate_adapter(_cec_adap_ops, cec, - CEC_NAME, - CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | - (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1); + cec->adap = cec_allocate_adapter(_cec_adap_ops, cec, CEC_NAME, + CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1); if (IS_ERR(cec->adap)) return PTR_ERR(cec->adap); -- 2.13.2
[PATCH 4/5] stih-cec: use CEC_CAP_DEFAULTS
From: Hans VerkuilUse the new CEC_CAP_DEFAULTS define in this driver. This also adds the CEC_CAP_RC capability which was missing here (and this is also the reason for this new define, to avoid missing such capabilities). Signed-off-by: Hans Verkuil --- drivers/media/platform/sti/cec/stih-cec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c index ce7964c71b50..dc221527fd05 100644 --- a/drivers/media/platform/sti/cec/stih-cec.c +++ b/drivers/media/platform/sti/cec/stih-cec.c @@ -351,9 +351,7 @@ static int stih_cec_probe(struct platform_device *pdev) } cec->adap = cec_allocate_adapter(_cec_adap_ops, cec, - CEC_NAME, - CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | - CEC_CAP_TRANSMIT, CEC_MAX_LOG_ADDRS); + CEC_NAME, CEC_CAP_DEFAULTS, CEC_MAX_LOG_ADDRS); if (IS_ERR(cec->adap)) return PTR_ERR(cec->adap); -- 2.13.2
Koch
Ishmeal Camara, presently working under the central bank of Togo, i have financier offer for both of us 2.5 M USD deal.
[PATCH] [media] adv7604: Prevent out of bounds access
These can only be accessed with CAP_SYS_ADMIN so it's not a critical security issue. The problem is that "page" is controlled by the user in the ioctl(). The test to see if the bit is set in state->info->page_mask is not sufficient because "page" can be very high and shift wrap around to a bit which is set. Signed-off-by: Dan Carpenterdiff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 660bacb8f7d9..8c633b8f30e7 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -618,7 +618,7 @@ static int adv76xx_read_reg(struct v4l2_subdev *sd, unsigned int reg) unsigned int val; int err; - if (!(BIT(page) & state->info->page_mask)) + if (page >= ADV76XX_PAGE_MAX || !(BIT(page) & state->info->page_mask)) return -EINVAL; reg &= 0xff; @@ -633,7 +633,7 @@ static int adv76xx_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) struct adv76xx_state *state = to_state(sd); unsigned int page = reg >> 8; - if (!(BIT(page) & state->info->page_mask)) + if (page >= ADV76XX_PAGE_MAX || !(BIT(page) & state->info->page_mask)) return -EINVAL; reg &= 0xff;