aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/s5p-mfc/s5p_mfc.c (follow)
AgeCommit message (Collapse)AuthorFilesLines
2022-03-18media: platform: rename s5p-mfc/ to samsung/s5p-mfc/Mauro Carvalho Chehab1-1680/+0
As the end goal is to have platform drivers split by vendor, rename s5p-mfc/ to samsung/s5p-mfc/. Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-01-28media: s5p-mfc: Use platform_get_irq() to get the interruptLad Prabhakar1-7/+4
platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static allocation of IRQ resources in DT core code, this causes an issue when using hierarchical interrupt domains using "interrupts" property in the node as this bypasses the hierarchical setup and messes up the irq chaining. In preparation for removal of static setup of IRQ resource from DT core code use platform_get_irq(). Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2021-11-15media: s5p-mfc: Use 'bitmap_zalloc()' when applicableChristophe JAILLET1-6/+3
'mfc_dev->mem_bitmap' is a bitmap. So use 'bitmap_zalloc()' to simplify code and improve the semantic. Also change the corresponding 'kfree()' into 'bitmap_free()' to keep consistency. Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-09-30media: s5p-mfc: Add checking to s5p_mfc_probe().Nadezda Lutovinova1-0/+4
If of_device_get_match_data() return NULL, then null pointer dereference occurs in s5p_mfc_init_pm(). The patch adds checking if dev->variant is NULL. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Nadezda Lutovinova <lutovinova@ispras.ru> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-09-30media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe()Tuo Li1-1/+1
The variable pdev is assigned to dev->plat_dev, and dev->plat_dev is checked in: if (!dev->plat_dev) This indicates both dev->plat_dev and pdev can be NULL. If so, the function dev_err() is called to print error information. dev_err(&pdev->dev, "No platform data specified\n"); However, &pdev->dev is an illegal address, and it is dereferenced in dev_err(). To fix this possible null-pointer dereference, replace dev_err() with mfc_err(). Reported-by: TOTE Robot <oslab@tsinghua.edu.cn> Signed-off-by: Tuo Li <islituo@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-09-30media: s5p-mfc: Make use of the helper function devm_platform_ioremap_resource()Cai Huoqing1-2/+1
Use the devm_platform_ioremap_resource() helper instead of calling platform_get_resource() and devm_ioremap_resource() separately Signed-off-by: Cai Huoqing <caihuoqing@baidu.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-11media: s5p-mfc: Properly handle dma_parms for the allocated devicesMarek Szyprowski1-1/+5
Commit 9495b7e92f71 ("driver core: platform: Initialize dma_parms for platform devices") in v5.7-rc5 added allocation of dma_parms structure to all platform devices. Then vb2_dma_contig_set_max_seg_size() have been changed not to allocate dma_parms structure and rely on the one allocated by the device core. Lets allocate the needed structure also for the devices created for the 2 MFC device memory ports. Reported-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Suggested-by: Ulf Hansson <ulf.hansson@linaro.org> Fixes: 9495b7e92f71 ("driver core: platform: Initialize dma_parms for platform devices") Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-02-24media: media/platform: rename VFL_TYPE_GRABBER to _VIDEOHans Verkuil1-2/+2
'GRABBER' is a weird name, all other types map to the /dev device names. Rename to 'VIDEO' to be consistent with the other types. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2019-06-12media: s5p-mfc: fix reading min scratch buffer size on MFC v6/v7Marek Szyprowski1-1/+2
MFC v6 and v7 has no register to read min scratch buffer size, so it has to be read conditionally only if hardware supports it. This fixes following NULL pointer exception on SoCs with MFC v6/v7: 8<--- cut here --- Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = f25837f9 [00000000] *pgd=bd93d835 Internal error: Oops: 17 [#1] PREEMPT SMP ARM Modules linked in: btmrvl_sdio btmrvl bluetooth mwifiex_sdio mwifiex ecdh_generic ecc Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) PC is at s5p_mfc_get_min_scratch_buf_size+0x30/0x3c LR is at s5p_mfc_get_min_scratch_buf_size+0x28/0x3c ... [<c074f998>] (s5p_mfc_get_min_scratch_buf_size) from [<c0745bc0>] (s5p_mfc_irq+0x814/0xa5c) [<c0745bc0>] (s5p_mfc_irq) from [<c019a218>] (__handle_irq_event_percpu+0x64/0x3f8) [<c019a218>] (__handle_irq_event_percpu) from [<c019a5d8>] (handle_irq_event_percpu+0x2c/0x7c) [<c019a5d8>] (handle_irq_event_percpu) from [<c019a660>] (handle_irq_event+0x38/0x5c) [<c019a660>] (handle_irq_event) from [<c019ebc4>] (handle_fasteoi_irq+0xc4/0x180) [<c019ebc4>] (handle_fasteoi_irq) from [<c0199270>] (generic_handle_irq+0x24/0x34) [<c0199270>] (generic_handle_irq) from [<c0199888>] (__handle_domain_irq+0x7c/0xec) [<c0199888>] (__handle_domain_irq) from [<c04ac298>] (gic_handle_irq+0x58/0x9c) [<c04ac298>] (gic_handle_irq) from [<c0101ab0>] (__irq_svc+0x70/0xb0) Exception stack(0xe73ddc60 to 0xe73ddca8) ... [<c0101ab0>] (__irq_svc) from [<c01967d8>] (console_unlock+0x5a8/0x6a8) [<c01967d8>] (console_unlock) from [<c01981d0>] (vprintk_emit+0x118/0x2d8) [<c01981d0>] (vprintk_emit) from [<c01983b0>] (vprintk_default+0x20/0x28) [<c01983b0>] (vprintk_default) from [<c01989b4>] (printk+0x30/0x54) [<c01989b4>] (printk) from [<c07500b8>] (s5p_mfc_init_decode_v6+0x1d4/0x284) [<c07500b8>] (s5p_mfc_init_decode_v6) from [<c07230d0>] (vb2_start_streaming+0x24/0x150) [<c07230d0>] (vb2_start_streaming) from [<c0724e4c>] (vb2_core_streamon+0x11c/0x15c) [<c0724e4c>] (vb2_core_streamon) from [<c07478b8>] (vidioc_streamon+0x64/0xa0) [<c07478b8>] (vidioc_streamon) from [<c0709640>] (__video_do_ioctl+0x28c/0x45c) [<c0709640>] (__video_do_ioctl) from [<c0709bc8>] (video_usercopy+0x260/0x8a4) [<c0709bc8>] (video_usercopy) from [<c02b3820>] (do_vfs_ioctl+0xb0/0x9fc) [<c02b3820>] (do_vfs_ioctl) from [<c02b41a0>] (ksys_ioctl+0x34/0x58) [<c02b41a0>] (ksys_ioctl) from [<c0101000>] (ret_fast_syscall+0x0/0x28) Exception stack(0xe73ddfa8 to 0xe73ddff0) ... ---[ end trace 376cf5ba6e0bee93 ]--- Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2019-06-11Merge tag 'v5.2-rc4' into media/masterMauro Carvalho Chehab1-5/+1
There are some conflicts due to SPDX changes. We also have more patches being merged via media tree touching them. So, let's merge back from upstream and address those. Linux 5.2-rc4 * tag 'v5.2-rc4': (767 commits) Linux 5.2-rc4 MAINTAINERS: Karthikeyan Ramasubramanian is MIA i2c: xiic: Add max_read_len quirk lockref: Limit number of cmpxchg loop retries uaccess: add noop untagged_addr definition x86/insn-eval: Fix use-after-free access to LDT entry kbuild: use more portable 'command -v' for cc-cross-prefix s390/unwind: correct stack switching during unwind block, bfq: add weight symlink to the bfq.weight cgroup parameter cgroup: let a symlink too be created with a cftype file drm/nouveau/secboot/gp10[2467]: support newer FW to fix SEC2 failures on some boards drm/nouveau/secboot: enable loading of versioned LS PMU/SEC2 ACR msgqueue FW drm/nouveau/secboot: split out FW version-specific LS function pointers drm/nouveau/secboot: pass max supported FW version to LS load funcs drm/nouveau/core: support versioned firmware loading drm/nouveau/core: pass subdev into nvkm_firmware_get, rather than device block: free sched's request pool in blk_cleanup_queue pktgen: do not sleep with the thread lock held. net: mvpp2: Use strscpy to handle stat strings net: rds: fix memory leak in rds_ib_flush_mr_pool ... Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2019-06-05media: v4l2: Make sure all drivers set _MPLANE caps in vdev->device_capsBoris Brezillon1-0/+2
This is needed if we want the core to be able to check _MPLANE support without having to call the ->vidioc_querycap() hook. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2019-05-30treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152Thomas Gleixner1-5/+1
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 3029 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-10Merge tag 'devicetree-for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linuxLinus Torvalds1-0/+7
Pull Devicetree updates from Rob Herring: - Fix a unittest failure on UML. Preparation for converting to kunit test framework. - Add annotations to dtx_diff output - Fix unittest reporting of expected error - Move DMA configuration for virtual devices into the driver that needs it (s5p-mfc) - Vendor prefixes for feiyang and techstar - Convert ARM GIC, GICv3, and L2x0 to DT schema - Add r8a7778/9 HSCIF serial bindings * tag 'devicetree-for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: of: unittest: unflatten device tree on UML when testing dt-bindings: Add vendor prefix for feiyang dt-bindings: Add vendor prefix for techstar dt-bindings: display: add missing semicolon in example of: mark early_init_dt_alloc_reserved_memory_arch static of: add dtc annotations functionality to dtx_diff of: unittest: add caution to function header comment of: unittest: remove report of expected error dt-bindings: interrupt-controller: Convert ARM GICv3 to json-schema dt-bindings: interrupt-controller: Convert ARM GIC to json-schema dt-bindings: arm: l2x0: Convert L2 cache to json-schema media: s5p-mfc: Fix memdev DMA configuration dt-bindings: serial: sh-sci: Document r8a7778/9 HSCIF bindings
2019-01-21media: s5p-mfc: Fix memdev DMA configurationRobin Murphy1-0/+7
Having of_reserved_mem_device_init() forcibly reconfigure DMA for all callers, potentially overriding the work done by a bus-specific .dma_configure method earlier, is at best a bad idea and at worst actively harmful. If drivers really need virtual devices to own dma-coherent memory, they should explicitly configure those devices based on the appropriate firmware node as they create them. It looks like the only driver not passing in a proper OF platform device is s5p-mfc, so move the rogue of_dma_configure() call into that driver where it logically belongs. Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Rob Herring <robh@kernel.org>
2019-01-07media: s5p-mfc: fix incorrect bus assignment in virtual child deviceMarek Szyprowski1-1/+0
Virtual MFC codec's child devices must not be assigned to platform bus, because they are allocated as raw 'struct device' and don't have the corresponding 'platform' part. This fixes NULL pointer access revealed recently by commit a66d972465d1 ("devres: Align data[] to ARCH_KMALLOC_MINALIGN"). Fixes: c79667dd93b0 ("media: s5p-mfc: replace custom reserved memory handling code with generic one") Reported-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2018-11-20media: s5p_mfc_dec.c: convert g_crop to g_selectionHans Verkuil1-0/+1
The g_crop really implemented composition for the CAPTURE stream. Replace g_crop by g_selection and set the V4L2_FL_QUIRK_INVERTED_CROP flag since this is one of the old drivers that predates the selection API. Those old drivers allowed g_crop when it really shouldn't have since g_crop returns a compose rectangle instead of a crop rectangle. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2018-07-27media: s5p-mfc: Fix buffer look up in s5p_mfc_handle_frame_{new, copy_time} functionsSylwester Nawrocki1-11/+12
Look up of buffers in s5p_mfc_handle_frame_new, s5p_mfc_handle_frame_copy_time functions is not working properly for DMA addresses above 2 GiB. As a result flags and timestamp of returned buffers are not set correctly and it breaks operation of GStreamer/OMX plugins which rely on the CAPTURE buffer queue flags. Due to improper return type of the get_dec_y_adr, get_dspl_y_adr callbacks and sign bit extension these callbacks return incorrect address values, e.g. 0xfffffffffefc0000 instead of 0x00000000fefc0000. Then the statement: "if (vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0) == dec_y_addr)" is always false, which breaks looking up capture queue buffers. To ensure proper matching by address u32 type is used for the DMA addresses. This should work on all related SoCs, since the MFC DMA address width is not larger than 32-bit. Changes done in this patch are minimal as there is a larger patch series pending refactoring the whole driver. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2018-07-04media: platform: s5p-mfc: simplify getting .drvdataWolfram Sang1-4/+2
We should get drvdata from struct device directly. Going via platform_device is an unneeded step back and forth. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2018-03-22media: s5p-mfc: Add support for HEVC encoderSmitha T Murthy1-0/+1
Add HEVC encoder support and necessary registers, V4L2 CIDs, and hevc encoder parameters Signed-off-by: Smitha T Murthy <smitha.t@samsung.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-03-22media: s5p-mfc: Use min scratch buffer size as provided by F/WSmitha T Murthy1-0/+2
After MFC v8.0, mfc f/w lets the driver know how much scratch buffer size is required for decoder. If mfc f/w has the functionality, E_MIN_SCRATCH_BUFFER_SIZE, driver can know how much scratch buffer size is required for encoder too. Signed-off-by: Smitha T Murthy <smitha.t@samsung.com> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-03-22media: s5p-mfc: Adding initial support for MFC v10.10Smitha T Murthy1-0/+25
Adding the support for MFC v10.10, with new register file and necessary hw control, decoder, encoder and structural changes. Signed-off-by: Smitha T Murthy <smitha.t@samsung.com> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-02-11vfs: do bulk POLL* -> EPOLL* replacementLinus Torvalds1-4/+4
This is the mindless scripted replacement of kernel use of POLL* variables as described by Al, done by this script: for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP NVAL MSG; do L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'` for f in $L; do sed -i "-es/^\([^\"]*\)\(\<POLL$V\>\)/\\1E\\2/" $f; done done with de-mangling cleanups yet to come. NOTE! On almost all architectures, the EPOLL* constants have the same values as the POLL* constants do. But they keyword here is "almost". For various bad reasons they aren't the same, and epoll() doesn't actually work quite correctly in some cases due to this on Sparc et al. The next patch from Al will sort out the final differences, and we should be all done. Scripted-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-02-06Merge tag 'media/v4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-mediaLinus Torvalds1-0/+6
Pull media updates from Mauro Carvalho Chehab: - videobuf2 was moved to a media/common dir, as it is now used by the DVB subsystem too - Digital TV core memory mapped support interface - new sensor driver: ov7740 - several improvements at ddbridge driver - new V4L2 driver: IPU3 CIO2 CSI-2 receiver unit, found on some Intel SoCs - new tuner driver: tda18250 - finally got rid of all LIRC staging drivers - as we don't have old lirc drivers anymore, restruct the lirc device code - add support for UVC metadata - add a new staging driver for NVIDIA Tegra Video Decoder Engine - DVB kAPI headers moved to include/media - synchronize the kAPI and uAPI for the DVB subsystem, removing the gap for non-legacy APIs - reduce the kAPI gap for V4L2 - lots of other driver enhancements, cleanups, etc. * tag 'media/v4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (407 commits) media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32 media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32 media: v4l2-compat-ioctl32.c: avoid sizeof(type) media: v4l2-compat-ioctl32.c: move 'helper' functions to __get/put_v4l2_format32 media: v4l2-compat-ioctl32.c: fix the indentation media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF media: v4l2-ioctl.c: don't copy back the result for -ENOTTY media: v4l2-ioctl.c: use check_fmt for enum/g/s/try_fmt media: vivid: fix module load error when enabling fb and no_error_inj=1 media: dvb_demux: improve debug messages media: dvb_demux: Better handle discontinuity errors media: cxusb, dib0700: ignore XC2028_I2C_FLUSH media: ts2020: avoid integer overflows on 32 bit machines media: i2c: ov7740: use gpio/consumer.h instead of gpio.h media: entity: Add a nop variant of media_entity_cleanup ...
2017-12-18media: s5p-mfc: Fix lock contention - request_firmware() onceShuah Khan1-0/+6
Driver calls request_firmware() whenever the device is opened for the first time. As the device gets opened and closed, dev->num_inst == 1 is true several times. This is not necessary since the firmware is saved in the fw_buf. s5p_mfc_load_firmware() copies the buffer returned by the request_firmware() to dev->fw_buf. fw_buf sticks around until it gets released from s5p_mfc_remove(), hence there is no need to keep requesting firmware and copying it to fw_buf. This might have been overlooked when changes are made to free fw_buf from the device release interface s5p_mfc_release(). Fix s5p_mfc_load_firmware() to call request_firmware() once and keep state. Change _probe() to load firmware once fw_buf has been allocated. s5p_mfc_open() and it continues to call s5p_mfc_load_firmware() and init hardware which is the step where firmware is written to the device. This addresses the mfc_mutex contention due to repeated request_firmware() calls from open() in the following circular locking warning: [ 552.194115] qtdemux0:sink/2710 is trying to acquire lock: [ 552.199488] (&dev->mfc_mutex){+.+.}, at: [<bf145544>] s5p_mfc_mmap+0x28/0xd4 [s5p_mfc] [ 552.207459] but task is already holding lock: [ 552.213264] (&mm->mmap_sem){++++}, at: [<c01df2e4>] vm_mmap_pgoff+0x44/0xb8 [ 552.220284] which lock already depends on the new lock. [ 552.228429] the existing dependency chain (in reverse order) is: [ 552.235881] -> #2 (&mm->mmap_sem){++++}: [ 552.241259] __might_fault+0x80/0xb0 [ 552.245331] filldir64+0xc0/0x2f8 [ 552.249144] call_filldir+0xb0/0x14c [ 552.253214] ext4_readdir+0x768/0x90c [ 552.257374] iterate_dir+0x74/0x168 [ 552.261360] SyS_getdents64+0x7c/0x1a0 [ 552.265608] ret_fast_syscall+0x0/0x28 [ 552.269850] -> #1 (&type->i_mutex_dir_key#2){++++}: [ 552.276180] down_read+0x48/0x90 [ 552.279904] lookup_slow+0x74/0x178 [ 552.283889] walk_component+0x1a4/0x2e4 [ 552.288222] link_path_walk+0x174/0x4a0 [ 552.292555] path_openat+0x68/0x944 [ 552.296541] do_filp_open+0x60/0xc4 [ 552.300528] file_open_name+0xe4/0x114 [ 552.304772] filp_open+0x28/0x48 [ 552.308499] kernel_read_file_from_path+0x30/0x78 [ 552.313700] _request_firmware+0x3ec/0x78c [ 552.318291] request_firmware+0x3c/0x54 [ 552.322642] s5p_mfc_load_firmware+0x54/0x150 [s5p_mfc] [ 552.328358] s5p_mfc_open+0x4e4/0x550 [s5p_mfc] [ 552.333394] v4l2_open+0xa0/0x104 [videodev] [ 552.338137] chrdev_open+0xa4/0x18c [ 552.342121] do_dentry_open+0x208/0x310 [ 552.346454] path_openat+0x28c/0x944 [ 552.350526] do_filp_open+0x60/0xc4 [ 552.354512] do_sys_open+0x118/0x1c8 [ 552.358586] ret_fast_syscall+0x0/0x28 [ 552.362830] -> #0 (&dev->mfc_mutex){+.+.}: -> #0 (&dev->mfc_mutex){+.+.}: [ 552.368379] lock_acquire+0x6c/0x88 [ 552.372364] __mutex_lock+0x68/0xa34 [ 552.376437] mutex_lock_interruptible_nested+0x1c/0x24 [ 552.382086] s5p_mfc_mmap+0x28/0xd4 [s5p_mfc] [ 552.386939] v4l2_mmap+0x54/0x88 [videodev] [ 552.391601] mmap_region+0x3a8/0x638 [ 552.395673] do_mmap+0x330/0x3a4 [ 552.399400] vm_mmap_pgoff+0x90/0xb8 [ 552.403472] SyS_mmap_pgoff+0x90/0xc0 [ 552.407632] ret_fast_syscall+0x0/0x28 [ 552.411876] other info that might help us debug this: [ 552.419848] Chain exists of: &dev->mfc_mutex --> &type->i_mutex_dir_key#2 --> &mm->mmap_sem [ 552.431200] Possible unsafe locking scenario: [ 552.437092] CPU0 CPU1 [ 552.441598] ---- ---- [ 552.446104] lock(&mm->mmap_sem); [ 552.449484] lock(&type->i_mutex_dir_key#2); [ 552.456329] lock(&mm->mmap_sem); [ 552.462222] lock(&dev->mfc_mutex); [ 552.465775] *** DEADLOCK *** Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-11-27media: annotate ->poll() instancesAl Viro1-2/+2
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2017-11-21treewide: setup_timer() -> timer_setup()Kees Cook1-4/+3
This converts all remaining cases of the old setup_timer() API into using timer_setup(), where the callback argument is the structure already holding the struct timer_list. These should have no behavioral changes, since they just change which pointer is passed into the callback with the same available pointers after conversion. It handles the following examples, in addition to some other variations. Casting from unsigned long: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... setup_timer(&ptr->my_timer, my_callback, ptr); and forced object casts: void my_callback(struct something *ptr) { ... } ... setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr); become: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... timer_setup(&ptr->my_timer, my_callback, 0); Direct function assignments: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... ptr->my_timer.function = my_callback; have a temporary cast added, along with converting the args: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback; And finally, callbacks without a data assignment: void my_callback(unsigned long data) { ... } ... setup_timer(&ptr->my_timer, my_callback, 0); have their argument renamed to verify they're unused during conversion: void my_callback(struct timer_list *unused) { ... } ... timer_setup(&ptr->my_timer, my_callback, 0); The conversion is done with the following Coccinelle script: spatch --very-quiet --all-includes --include-headers \ -I ./arch/x86/include -I ./arch/x86/include/generated \ -I ./include -I ./arch/x86/include/uapi \ -I ./arch/x86/include/generated/uapi -I ./include/uapi \ -I ./include/generated/uapi --include ./include/linux/kconfig.h \ --dir . \ --cocci-file ~/src/data/timer_setup.cocci @fix_address_of@ expression e; @@ setup_timer( -&(e) +&e , ...) // Update any raw setup_timer() usages that have a NULL callback, but // would otherwise match change_timer_function_usage, since the latter // will update all function assignments done in the face of a NULL // function initialization in setup_timer(). @change_timer_function_usage_NULL@ expression _E; identifier _timer; type _cast_data; @@ ( -setup_timer(&_E->_timer, NULL, _E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E->_timer, NULL, (_cast_data)_E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E._timer, NULL, &_E); +timer_setup(&_E._timer, NULL, 0); | -setup_timer(&_E._timer, NULL, (_cast_data)&_E); +timer_setup(&_E._timer, NULL, 0); ) @change_timer_function_usage@ expression _E; identifier _timer; struct timer_list _stl; identifier _callback; type _cast_func, _cast_data; @@ ( -setup_timer(&_E->_timer, _callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | _E->_timer@_stl.function = _callback; | _E->_timer@_stl.function = &_callback; | _E->_timer@_stl.function = (_cast_func)_callback; | _E->_timer@_stl.function = (_cast_func)&_callback; | _E._timer@_stl.function = _callback; | _E._timer@_stl.function = &_callback; | _E._timer@_stl.function = (_cast_func)_callback; | _E._timer@_stl.function = (_cast_func)&_callback; ) // callback(unsigned long arg) @change_callback_handle_cast depends on change_timer_function_usage@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; identifier _handle; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { ( ... when != _origarg _handletype *_handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg ) } // callback(unsigned long arg) without existing variable @change_callback_handle_cast_no_arg depends on change_timer_function_usage && !change_callback_handle_cast@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { + _handletype *_origarg = from_timer(_origarg, t, _timer); + ... when != _origarg - (_handletype *)_origarg + _origarg ... when != _origarg } // Avoid already converted callbacks. @match_callback_converted depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier t; @@ void _callback(struct timer_list *t) { ... } // callback(struct something *handle) @change_callback_handle_arg depends on change_timer_function_usage && !match_callback_converted && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; @@ void _callback( -_handletype *_handle +struct timer_list *t ) { + _handletype *_handle = from_timer(_handle, t, _timer); ... } // If change_callback_handle_arg ran on an empty function, remove // the added handler. @unchange_callback_handle_arg depends on change_timer_function_usage && change_callback_handle_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; identifier t; @@ void _callback(struct timer_list *t) { - _handletype *_handle = from_timer(_handle, t, _timer); } // We only want to refactor the setup_timer() data argument if we've found // the matching callback. This undoes changes in change_timer_function_usage. @unchange_timer_function_usage depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg && !change_callback_handle_arg@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type change_timer_function_usage._cast_data; @@ ( -timer_setup(&_E->_timer, _callback, 0); +setup_timer(&_E->_timer, _callback, (_cast_data)_E); | -timer_setup(&_E._timer, _callback, 0); +setup_timer(&_E._timer, _callback, (_cast_data)&_E); ) // If we fixed a callback from a .function assignment, fix the // assignment cast now. @change_timer_function_assignment depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_func; typedef TIMER_FUNC_TYPE; @@ ( _E->_timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -&_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)_callback; +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -&_callback; +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; ) // Sometimes timer functions are called directly. Replace matched args. @change_timer_function_calls depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression _E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_data; @@ _callback( ( -(_cast_data)_E +&_E->_timer | -(_cast_data)&_E +&_E._timer | -_E +&_E->_timer ) ) // If a timer has been configured without a data argument, it can be // converted without regard to the callback argument, since it is unused. @match_timer_function_unused_data@ expression _E; identifier _timer; identifier _callback; @@ ( -setup_timer(&_E->_timer, _callback, 0); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0L); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0UL); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0L); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0UL); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_timer, _callback, 0); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0L); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0UL); +timer_setup(&_timer, _callback, 0); | -setup_timer(_timer, _callback, 0); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0L); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0UL); +timer_setup(_timer, _callback, 0); ) @change_callback_unused_data depends on match_timer_function_unused_data@ identifier match_timer_function_unused_data._callback; type _origtype; identifier _origarg; @@ void _callback( -_origtype _origarg +struct timer_list *unused ) { ... when != _origarg } Signed-off-by: Kees Cook <keescook@chromium.org>
2017-11-21treewide: init_timer() -> setup_timer()Kees Cook1-3/+2
This mechanically converts all remaining cases of ancient open-coded timer setup with the old setup_timer() API, which is the first step in timer conversions. This has no behavioral changes, since it ultimately just changes the order of assignment to fields of struct timer_list when finding variations of: init_timer(&t); f.function = timer_callback; t.data = timer_callback_arg; to be converted into: setup_timer(&t, timer_callback, timer_callback_arg); The conversion is done with the following Coccinelle script, which is an improved version of scripts/cocci/api/setup_timer.cocci, in the following ways: - assignments-before-init_timer() cases - limit the .data case removal to the specific struct timer_list instance - handling calls by dereference (timer->field vs timer.field) spatch --very-quiet --all-includes --include-headers \ -I ./arch/x86/include -I ./arch/x86/include/generated \ -I ./include -I ./arch/x86/include/uapi \ -I ./arch/x86/include/generated/uapi -I ./include/uapi \ -I ./include/generated/uapi --include ./include/linux/kconfig.h \ --dir . \ --cocci-file ~/src/data/setup_timer.cocci @fix_address_of@ expression e; @@ init_timer( -&(e) +&e , ...) // Match the common cases first to avoid Coccinelle parsing loops with // "... when" clauses. @match_immediate_function_data_after_init_timer@ expression e, func, da; @@ -init_timer +setup_timer ( \(&e\|e\) +, func, da ); ( -\(e.function\|e->function\) = func; -\(e.data\|e->data\) = da; | -\(e.data\|e->data\) = da; -\(e.function\|e->function\) = func; ) @match_immediate_function_data_before_init_timer@ expression e, func, da; @@ ( -\(e.function\|e->function\) = func; -\(e.data\|e->data\) = da; | -\(e.data\|e->data\) = da; -\(e.function\|e->function\) = func; ) -init_timer +setup_timer ( \(&e\|e\) +, func, da ); @match_function_and_data_after_init_timer@ expression e, e2, e3, e4, e5, func, da; @@ -init_timer +setup_timer ( \(&e\|e\) +, func, da ); ... when != func = e2 when != da = e3 ( -e.function = func; ... when != da = e4 -e.data = da; | -e->function = func; ... when != da = e4 -e->data = da; | -e.data = da; ... when != func = e5 -e.function = func; | -e->data = da; ... when != func = e5 -e->function = func; ) @match_function_and_data_before_init_timer@ expression e, e2, e3, e4, e5, func, da; @@ ( -e.function = func; ... when != da = e4 -e.data = da; | -e->function = func; ... when != da = e4 -e->data = da; | -e.data = da; ... when != func = e5 -e.function = func; | -e->data = da; ... when != func = e5 -e->function = func; ) ... when != func = e2 when != da = e3 -init_timer +setup_timer ( \(&e\|e\) +, func, da ); @r1 exists@ expression t; identifier f; position p; @@ f(...) { ... when any init_timer@p(\(&t\|t\)) ... when any } @r2 exists@ expression r1.t; identifier g != r1.f; expression e8; @@ g(...) { ... when any \(t.data\|t->data\) = e8 ... when any } // It is dangerous to use setup_timer if data field is initialized // in another function. @script:python depends on r2@ p << r1.p; @@ cocci.include_match(False) @r3@ expression r1.t, func, e7; position r1.p; @@ ( -init_timer@p(&t); +setup_timer(&t, func, 0UL); ... when != func = e7 -t.function = func; | -t.function = func; ... when != func = e7 -init_timer@p(&t); +setup_timer(&t, func, 0UL); | -init_timer@p(t); +setup_timer(t, func, 0UL); ... when != func = e7 -t->function = func; | -t->function = func; ... when != func = e7 -init_timer@p(t); +setup_timer(t, func, 0UL); ) Signed-off-by: Kees Cook <keescook@chromium.org>
2017-11-07media: s5p-mfc: fix lockdep warningShuah Khan1-4/+0
The driver mmap functions shouldn't take lock when calling vb2_mmap(). Fix it to not take the lock. The following lockdep warning is fixed with this change. [ 2106.181412] ====================================================== [ 2106.187563] WARNING: possible circular locking dependency detected [ 2106.193718] 4.14.0-rc2-00002-gfab205f-dirty #4 Not tainted [ 2106.199175] ------------------------------------------------------ [ 2106.205328] qtdemux0:sink/2614 is trying to acquire lock: [ 2106.210701] (&dev->mfc_mutex){+.+.}, at: [<bf175544>] s5p_mfc_mmap+0x28/0xd4 [s5p_mfc] [ 2106.218672] [ 2106.218672] but task is already holding lock: [ 2106.224477] (&mm->mmap_sem){++++}, at: [<c01df2e4>] vm_mmap_pgoff+0x44/0xb8 [ 2106.231497] [ 2106.231497] which lock already depends on the new lock. [ 2106.231497] [ 2106.239642] [ 2106.239642] the existing dependency chain (in reverse order) is: [ 2106.247095] [ 2106.247095] -> #1 (&mm->mmap_sem){++++}: [ 2106.252473] __might_fault+0x80/0xb0 [ 2106.256567] video_usercopy+0x1cc/0x510 [videodev] [ 2106.261845] v4l2_ioctl+0xa4/0xdc [videodev] [ 2106.266596] do_vfs_ioctl+0xa0/0xa18 [ 2106.270667] SyS_ioctl+0x34/0x5c [ 2106.274395] ret_fast_syscall+0x0/0x28 [ 2106.278637] [ 2106.278637] -> #0 (&dev->mfc_mutex){+.+.}: [ 2106.284186] lock_acquire+0x6c/0x88 [ 2106.288173] __mutex_lock+0x68/0xa34 [ 2106.292244] mutex_lock_interruptible_nested+0x1c/0x24 [ 2106.297893] s5p_mfc_mmap+0x28/0xd4 [s5p_mfc] [ 2106.302747] v4l2_mmap+0x54/0x88 [videodev] [ 2106.307409] mmap_region+0x3a8/0x638 [ 2106.311480] do_mmap+0x330/0x3a4 [ 2106.315207] vm_mmap_pgoff+0x90/0xb8 [ 2106.319279] SyS_mmap_pgoff+0x90/0xc0 [ 2106.323439] ret_fast_syscall+0x0/0x28 [ 2106.327683] [ 2106.327683] other info that might help us debug this: [ 2106.327683] [ 2106.335656] Possible unsafe locking scenario: [ 2106.335656] [ 2106.341548] CPU0 CPU1 [ 2106.346053] ---- ---- [ 2106.350559] lock(&mm->mmap_sem); [ 2106.353939] lock(&dev->mfc_mutex); [ 2106.353939] lock(&dev->mfc_mutex); [ 2106.365897] lock(&dev->mfc_mutex); [ 2106.369450] [ 2106.369450] *** DEADLOCK *** [ 2106.369450] [ 2106.375344] 1 lock held by qtdemux0:sink/2614: [ 2106.379762] #0: (&mm->mmap_sem){++++}, at: [<c01df2e4>] vm_mmap_pgoff+0x44/0xb8 [ 2106.387214] [ 2106.387214] stack backtrace: [ 2106.391550] CPU: 7 PID: 2614 Comm: qtdemux0:sink Not tainted 4.14.0-rc2-00002-gfab205f-dirty #4 [ 2106.400213] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 2106.406285] [<c01102c8>] (unwind_backtrace) from [<c010cabc>] (show_stack+0x10/0x14) [ 2106.413995] [<c010cabc>] (show_stack) from [<c08543a4>] (dump_stack+0x98/0xc4) [ 2106.421187] [<c08543a4>] (dump_stack) from [<c016b2fc>] (print_circular_bug+0x254/0x410) [ 2106.429245] [<c016b2fc>] (print_circular_bug) from [<c016c580>] (check_prev_add+0x468/0x938) [ 2106.437651] [<c016c580>] (check_prev_add) from [<c016f4dc>] (__lock_acquire+0x1314/0x14fc) [ 2106.445883] [<c016f4dc>] (__lock_acquire) from [<c016fefc>] (lock_acquire+0x6c/0x88) [ 2106.453596] [<c016fefc>] (lock_acquire) from [<c0869fb4>] (__mutex_lock+0x68/0xa34) [ 2106.461221] [<c0869fb4>] (__mutex_lock) from [<c086aa08>] (mutex_lock_interruptible_nested+0x1c/0x24) [ 2106.470425] [<c086aa08>] (mutex_lock_interruptible_nested) from [<bf175544>] (s5p_mfc_mmap+0x28/0xd4 [s5p_mfc]) [ 2106.480494] [<bf175544>] (s5p_mfc_mmap [s5p_mfc]) from [<bf037120>] (v4l2_mmap+0x54/0x88 [videodev]) [ 2106.489575] [<bf037120>] (v4l2_mmap [videodev]) from [<c01f4798>] (mmap_region+0x3a8/0x638) [ 2106.497875] [<c01f4798>] (mmap_region) from [<c01f4d58>] (do_mmap+0x330/0x3a4) [ 2106.505068] [<c01f4d58>] (do_mmap) from [<c01df330>] (vm_mmap_pgoff+0x90/0xb8) [ 2106.512260] [<c01df330>] (vm_mmap_pgoff) from [<c01f28cc>] (SyS_mmap_pgoff+0x90/0xc0) [ 2106.520059] [<c01f28cc>] (SyS_mmap_pgoff) from [<c0108820>] (ret_fast_syscall+0x0/0x28) Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com> Suggested-by: Hans Verkuil <hansverk@cisco.com> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Hans Verkuil <hansverk@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-10-16media: s5p-mfc: Adjust a null pointer check in four functionsMarkus Elfring1-4/+4
The script “checkpatch.pl” pointed information out like the following. Comparison to NULL could be written... Thus fix the affected source code places. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2017-10-16media: s5p-mfc: Improve a size determination in s5p_mfc_alloc_memdev()Markus Elfring1-1/+1
Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2017-10-16media: s5p-mfc: Delete an error message for a failed memory allocationMarkus Elfring1-3/+1
Omit an extra message for a memory allocation failure in s5p_mfc_probe() function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2017-04-05[media] s5p-mfc: Fix unbalanced call to clock managementMarek Szyprowski1-0/+1
Clock should be turned off after calling s5p_mfc_init_hw() from the watchdog worker, like it is already done in the s5p_mfc_open() which also calls this function. Fixes: af93574678108 ("[media] MFC: Add MFC 5.1 V4L2 driver") Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Cc: stable@vger.kernel.org # v3.7+ Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Rename BANK1/2 to BANK_L/R to better match documentationMarek Szyprowski1-27/+27
Documentation for MFC hardware still uses 'left' and 'right' names for the memory channel/banks, so replace BANK1/2 defines with more appropriate BANK_L/R names. Suggested-by: Shuah Khan <shuahkhan@gmail.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Use preallocated block allocator always for MFC v6+Marek Szyprowski1-3/+6
It turned out that all versions of MFC v6+ hardware doesn't have a strict requirement for ALL buffers to be allocated on higher addresses than the firmware base like it was documented for MFC v5. This requirement is true only for the device and per-context buffers. All video data buffers can be allocated anywhere for all MFC v6+ versions. Basing on this fact, the special DMA configuration based on two reserved memory regions is not really needed for MFC v6+ devices, because the memory requirements for the firmware, device and per-context buffers can be fulfilled by the simple probe-time pre-allocated block allocator introduced in previous patch. This patch enables support for such pre-allocated block based allocator always for MFC v6+ devices. Due to the limitations of the memory management subsystem the largest supported size of the pre-allocated buffer when no CMA (Contiguous Memory Allocator) is enabled is 4 MiB. This patch also removes the requirement to provide two reserved memory regions for MFC v6+ devices in device tree. Now the driver is fully functional without them. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Remove special configuration of IOMMU domainMarek Szyprowski1-17/+13
The main reason for using special configuration of IOMMU domain was the problem with MFC firmware, which failed to operate properly when placed at 0 DMA address. Instead of adding custom code for configuring each variant of IOMMU domain and architecture specific glue code, simply use what arch code provides and if the DMA base address equals zero, skip first 128 KiB to keep required alignment. This patch also make the driver operational on ARM64 architecture, because it no longer depends on ARM specific DMA-mapping and IOMMU glue code functions. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Add support for probe-time preallocated block based allocatorMarek Szyprowski1-6/+37
Current MFC driver depends on the fact that when IOMMU is available, the DMA-mapping framework and its IOMMU glue will use first-fit allocator. This was true for ARM architecture, but its not for ARM64 arch. However, in case of MFC v6+ hardware and latest firmware, it turned out that there is no strict requirement for ALL buffers to be allocated on higher addresses than the firmware base. This requirement is true only for the device and per-context buffers. All video data buffers can be allocated anywhere for all MFC v6+ versions. Such relaxed requirements for the memory buffers can be easily fulfilled by allocating firmware, device and per-context buffers from the probe-time preallocated larger buffer. This patch adds support for it. This way the driver finally works fine on ARM64 architecture. The size of the preallocated buffer is 8 MiB, what is enough for three instances H264 decoders or encoders (other codecs have smaller memory requirements). If one needs more for particular use case, one can use "mem" module parameter to force larger (or smaller) buffer (for example by adding "s5p_mfc.mem=16M" to kernel command line). [mchehab@s-opensource.com: fix two checkpatch warnings: don't initialize static to NULL; don't use S_foo permisions] Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Split variant DMA memory configuration into separate functionsMarek Szyprowski1-41/+61
Move code for DMA memory configuration with IOMMU into separate function to make it easier to compare what is being done in each case. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Move firmware allocation to DMA configure functionMarek Szyprowski1-13/+49
To complete DMA memory configuration for MFC device, allocation of the firmware buffer is needed, because some parameters are dependant on its base address. Till now, this has been handled in the s5p_mfc_alloc_firmware() function. This patch moves that logic to s5p_mfc_configure_dma_memory() to keep DMA memory related operations in a single place. This way s5p_mfc_alloc_firmware() is simplified and does what it name says. The other consequence of this change is moving s5p_mfc_alloc_firmware() call from the s5p_mfc_probe() function to the s5p_mfc_configure_dma_memory(). Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Move setting DMA max segment size to DMA configure functionMarek Szyprowski1-8/+13
Setting DMA max segment size to 32 bit mask is a part of DMA memory configuration, so move those calls to s5p_mfc_configure_dma_memory() function. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Replace mem_dev_* entries with an arrayMarek Szyprowski1-14/+17
Internal MFC driver device structure contains two pointers to devices used for DMA memory allocation: mem_dev_l and mem_dev_r. Replace them with the mem_dev[] array and use defines for accessing particular banks. This will help to simplify code in the next patches. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Use generic of_device_get_match_data helperMarek Szyprowski1-15/+2
Replace custom code with generic helper to retrieve driver data. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Reviewed-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Remove unused structures and dead codeMarek Szyprowski1-21/+0
Remove unused structures, definitions and functions that are no longer called from the driver code. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Tested-by: Smitha T Murthy <smitha.t@samsung.com> Reviewed-by: Smitha T Murthy <smitha.t@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Fix race between interrupt routine and device functionsMarek Szyprowski1-8/+4
Interrupt routine must wake process waiting for given interrupt AFTER updating driver's internal structures and contexts. Doing it in-between is a serious bug. This patch moves all calls to the wake() function to the end of the interrupt processing block to avoid potential and real races, especially on multi-core platforms. This also fixes following issue reported from clock core (clocks were disabled in interrupt after being unprepared from the other place in the driver, the stack trace however points to the different place than s5p_mfc driver because of the race): WARNING: CPU: 1 PID: 18 at drivers/clk/clk.c:544 clk_core_unprepare+0xc8/0x108 Modules linked in: CPU: 1 PID: 18 Comm: kworker/1:0 Not tainted 4.10.0-next-20170223-00070-g04e18bc99ab9-dirty #2154 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) Workqueue: pm pm_runtime_work [<c010d8b0>] (unwind_backtrace) from [<c010a534>] (show_stack+0x10/0x14) [<c010a534>] (show_stack) from [<c033292c>] (dump_stack+0x74/0x94) [<c033292c>] (dump_stack) from [<c011cef4>] (__warn+0xd4/0x100) [<c011cef4>] (__warn) from [<c011cf40>] (warn_slowpath_null+0x20/0x28) [<c011cf40>] (warn_slowpath_null) from [<c0387a84>] (clk_core_unprepare+0xc8/0x108) [<c0387a84>] (clk_core_unprepare) from [<c0389d84>] (clk_unprepare+0x24/0x2c) [<c0389d84>] (clk_unprepare) from [<c03d4660>] (exynos_sysmmu_suspend+0x48/0x60) [<c03d4660>] (exynos_sysmmu_suspend) from [<c042b9b0>] (pm_generic_runtime_suspend+0x2c/0x38) [<c042b9b0>] (pm_generic_runtime_suspend) from [<c0437580>] (genpd_runtime_suspend+0x94/0x220) [<c0437580>] (genpd_runtime_suspend) from [<c042e240>] (__rpm_callback+0x134/0x208) [<c042e240>] (__rpm_callback) from [<c042e334>] (rpm_callback+0x20/0x80) [<c042e334>] (rpm_callback) from [<c042d3b8>] (rpm_suspend+0xdc/0x458) [<c042d3b8>] (rpm_suspend) from [<c042ea24>] (pm_runtime_work+0x80/0x90) [<c042ea24>] (pm_runtime_work) from [<c01322c4>] (process_one_work+0x120/0x318) [<c01322c4>] (process_one_work) from [<c0132520>] (worker_thread+0x2c/0x4ac) [<c0132520>] (worker_thread) from [<c0137ab0>] (kthread+0xfc/0x134) [<c0137ab0>] (kthread) from [<c0107978>] (ret_from_fork+0x14/0x3c) ---[ end trace 1ead49a7bb83f0d8 ]--- Fixes: af93574678108 ("[media] MFC: Add MFC 5.1 V4L2 driver") Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> CC: stable@vger.kernel.org # v4.5+ Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p_mfc: Remove unneeded io_modes initialization in s5p_mfc_open()Shuah Khan1-1/+0
Remove unneeded io_modes initialization in s5p_mfc_open(). It gets done right below in vdev == dev->vfd_dec conditional. Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-04-05[media] s5p-mfc: Fix initialization of internal structuresMarek Szyprowski1-9/+8
Initialize members of the internal device and context structures as early as possible to avoid access to uninitialized objects on initialization failures. If loading firmware or creating of the hardware instance fails, driver will access device or context queue in error handling path, which might not be initialized yet, what causes kernel panic. Fix this by moving initialization of all static members as early as possible. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Andrzej Hajda <a.hajda@samsung.com> Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-30[media] s5p-mfc: Add support for MFC v8 available in Exynos 5433 SoCsMarek Szyprowski1-0/+14
Exynos5433 SoC has MFC v8 hardware module, but it has more complex clock hierarchy, so a new compatible is added. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-30[media] s5p-mfc: Rework clock handlingMarek Szyprowski1-0/+8
This patch changes the code for handling clocks. Now clocks are defined per each device variant, what is a preparation for adding support for Exynos 5433 MFC V8, which has more clocks than all previous versions. Also use devm_clk_get() to simplify cleanup path. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-30[media] s5p-mfc: Remove dead conditional codeMarek Szyprowski1-22/+0
CONFIG_PM is always enabled on Exynos platforms, so remove dead code related to early development of MFC driver on platform without PM support. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-30[media] s5p-mfc: Ensure that clock is disabled before turning power offMarek Szyprowski1-2/+4
Move clock disabling before turning power off. This will enable later to add calls to clk_prepare/unprepare in the s5p_mfc_power_off() function to avoid keeping clocks prepared all the time when driver is bound. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-30[media] s5p-mfc: Set DMA_ATTR_ALLOC_SINGLE_PAGESDouglas Anderson1-0/+11
We do video allocation all the time and we need it to be fast. Plus TLB efficiency isn't terribly important for video. That means we want to set DMA_ATTR_ALLOC_SINGLE_PAGES. See also the previous change (commit 14d3ae2efeed "ARM: dma-mapping: Use DMA_ATTR_ALLOC_SINGLE_PAGES hint to optimize allocation"). [m.szyprowski: rebased patch onto v4.9-rc1 and adapted changes to latest videbuf2 changes, this simplifies code changes to only set proper dma attribute flag and comment the reason for it, added commit id of arch/arm/mm patch] Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>