From 5017e1b15d4ca8dcc170dc6914f6b2d8cd492bdf Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 19 Jan 2016 11:45:12 -0200 Subject: [media] v4l: vsp1: Fix wrong entities links creation The Media Control framework now requires entities to be registered with the media device before creating links so commit c7621b3044f7 ("[media] v4l: vsp1: separate links creation from entities init") separated link creation from entities init. But unfortunately that patch introduced a regression since wrong links were created causing a boot failure on Renesas boards. This patch fixes the boot issue and also the media graph was compared by Geert Uytterhoeven to make sure that the driver changes required by the Media Control framework next generation did not affect the graph. Reported-by: Geert Uytterhoeven Signed-off-by: Javier Martinez Canillas Tested-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 42dff9d020af..533bc796391e 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -256,7 +256,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) /* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { - if (entity->type == VSP1_ENTITY_LIF) { + if (entity->type == VSP1_ENTITY_WPF) { ret = vsp1_wpf_create_links(vsp1, entity); if (ret < 0) goto done; @@ -264,7 +264,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) ret = vsp1_rpf_create_links(vsp1, entity); if (ret < 0) goto done; - } else { + } + + if (entity->type != VSP1_ENTITY_LIF && + entity->type != VSP1_ENTITY_RPF) { ret = vsp1_create_links(vsp1, entity); if (ret < 0) goto done; -- cgit v1.2.3 From e920ebc2f85848f7c21b2fe27a6ea9e798c63568 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 4 Jan 2016 10:48:24 -0200 Subject: [media] soc_camera: cleanup control device on async_unbind I got the following WARN on a simple unbind/bind cycle: root@Lager:/sys/bus/i2c/drivers/adv7180# echo 6-0020 > unbind root@Lager:/sys/bus/i2c/drivers/adv7180# echo 6-0020 > bind [ 31.097652] adv7180 6-0020: chip found @ 0x20 (e6520000.i2c) [ 31.123744] ------------[ cut here ]------------ [ 31.128413] WARNING: CPU: 3 PID: 873 at drivers/media/platform/soc_camera/soc_camera.c:1463 soc_camera_async_bound+0x40/0xa0() [ 31.139896] CPU: 3 PID: 873 Comm: sh Not tainted 4.4.0-rc3-00062-ge8ae2c0b6bca2a #172 [ 31.147815] Hardware name: Generic R8A7790 (Flattened Device Tree) [ 31.154056] Backtrace: [ 31.156575] [] (dump_backtrace) from [] (show_stack+0x20/0x24) [ 31.164233] r6:c05c5b33 r5:00000009 r4:00000000 r3:00404100 [ 31.170017] [] (show_stack) from [] (dump_stack+0x78/0x94) [ 31.177344] [] (dump_stack) from [] (warn_slowpath_common+0x98/0xc4) [ 31.185518] r4:00000000 r3:00000000 [ 31.189172] [] (warn_slowpath_common) from [] (warn_slowpath_null+0x2c/0x34) [ 31.198043] r8:eb38df28 r7:eb38c5d0 r6:eb38de80 r5:e6962810 r4:eb38de80 [ 31.204898] [] (warn_slowpath_null) from [] (soc_camera_async_bound+0x40/0xa0) [ 31.213955] [] (soc_camera_async_bound) from [] (v4l2_async_test_notify+0x9c/0x108) [ 31.223430] r5:eb38c5ec r4:eb38de80 [ 31.227084] [] (v4l2_async_test_notify) from [] (v4l2_async_register_subdev+0x88/0xd0) [ 31.236822] r7:c07115c8 r6:c071160c r5:eb38c5ec r4:eb38de80 [ 31.242622] [] (v4l2_async_register_subdev) from [] (adv7180_probe+0x2c8/0x3a4) [ 31.251753] r8:00000000 r7:00000001 r6:eb38de80 r5:ea973400 r4:eb38de10 r3:00000000 [ 31.259660] [] (adv7180_probe) from [] (i2c_device_probe+0x1a0/0x1e4) This gets fixed by clearing the control device pointer on async_unbind. Signed-off-by: Wolfram Sang Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/soc_camera.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index cc84c6d6a701..46c7186f7867 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1493,6 +1493,8 @@ static void soc_camera_async_unbind(struct v4l2_async_notifier *notifier, struct soc_camera_async_client, notifier); struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev); + icd->control = NULL; + if (icd->clk) { v4l2_clk_unregister(icd->clk); icd->clk = NULL; -- cgit v1.2.3 From 9b4b92645c5edf16b9e77c5956e13b040ba5ed0f Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 30 Nov 2015 07:20:15 -0200 Subject: [media] atmel-isi: fix debug message which only show the first format Correct the debug output message to show correct format. Signed-off-by: Josh Wu Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/atmel-isi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c398b285180c..1af779ee3c74 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -795,7 +795,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, xlate->host_fmt = &isi_camera_formats[i]; xlate->code = code.code; dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code.code); + xlate->host_fmt->name, xlate->code); } break; default: -- cgit v1.2.3 From 1b4ca5aa9e0867f5cec40f9508dac7414f3b6998 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Thu, 14 Jan 2016 22:09:43 -0200 Subject: [media] drivers/media: vsp1_video: fix compile error This was found with the -RT patch enabled, but the fix should apply to non-RT also. Compilation error without this fix: ../drivers/media/platform/vsp1/vsp1_video.c: In function 'vsp1_pipeline_stopped': ../drivers/media/platform/vsp1/vsp1_video.c:524:2: error: expected expression before 'do' spin_unlock_irqrestore(&pipe->irqlock, flags); ^ Signed-off-by: Anders Roxell Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 637d0d6f79fb..b4dca57d1ae3 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -515,7 +515,7 @@ static bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe) bool stopped; spin_lock_irqsave(&pipe->irqlock, flags); - stopped = pipe->state == VSP1_PIPELINE_STOPPED, + stopped = pipe->state == VSP1_PIPELINE_STOPPED; spin_unlock_irqrestore(&pipe->irqlock, flags); return stopped; -- cgit v1.2.3 From 76a563675485849f6f9ad5b30df220438b3628c1 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 8 Dec 2015 12:15:54 -0200 Subject: [media] exynos4-is: fix a format string bug Ironically, 7d4020c3c400 ("[media] exynos4-is: fix some warnings when compiling on arm64") fixed some format string bugs but introduced a new one. buf_index is a simple int, so it should be printed with %d, not %pad (which is correctly used for dma_addr_t). Fixes: 7d4020c3c400 ("[media] exynos4-is: fix some warnings when compiling on arm64") Signed-off-by: Rasmus Villemoes Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-isp-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index bf9261eb57a1..c0816728cbfe 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -218,8 +218,8 @@ static void isp_video_capture_buffer_queue(struct vb2_buffer *vb) ivb->dma_addr[i]; isp_dbg(2, &video->ve.vdev, - "dma_buf %pad (%d/%d/%d) addr: %pad\n", - &buf_index, ivb->index, i, vb->index, + "dma_buf %d (%d/%d/%d) addr: %pad\n", + buf_index, ivb->index, i, vb->index, &ivb->dma_addr[i]); } -- cgit v1.2.3 From 4e63959e3773276cc49b488238bd583c53cf54e8 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 18 Jan 2016 14:10:25 -0200 Subject: [media] s5k6a3: Fix VIDIOC_SUBDEV_G_FMT ioctl for TRY format VIDIOC_SUBDEV_G_FMT ioctl should return TRY format previously set with VIDIOC_SUBDEV_S_FMT. Currently it is not the case as only ACTIVE formats are saved in the driver. Since the driver doesn't alter hardware state in the set_fmt op anyway, the op can save the format in both TRY and ACTIVE case. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5k6a3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index b9e43ffa5085..cbe4711e9b31 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -144,8 +144,7 @@ static int s5k6a3_set_fmt(struct v4l2_subdev *sd, mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which); if (mf) { mutex_lock(&sensor->lock); - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) - *mf = fmt->format; + *mf = fmt->format; mutex_unlock(&sensor->lock); } return 0; -- cgit v1.2.3 From 76775776a6e3dbe2dc8a84345dca4540969bc014 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 18 Jan 2016 14:10:26 -0200 Subject: [media] exynos4-is: Open shouldn't fail when sensor entity is not linked In order to allow for automatic media device entities linking from the level of libv4l plugin the open system call shouldn't fail, as the libv4l plugins can begin their job not until it succeeds. This patch allows for leaving the pipeline not linked on open and postpones verifying it to the moment when streamon callback is called. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 95 +++++++++++++++++++++------ 1 file changed, 76 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index f3b2dd30ec77..e79ddbb1e14f 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -185,6 +185,37 @@ error: return ret; } +/** + * __fimc_pipeline_enable - enable power of all pipeline subdevs + * and the sensor clock + * @ep: video pipeline structure + * @fmd: fimc media device + * + * Called with the graph mutex held. + */ +static int __fimc_pipeline_enable(struct exynos_media_pipeline *ep, + struct fimc_md *fmd) +{ + struct fimc_pipeline *p = to_fimc_pipeline(ep); + int ret; + + /* Enable PXLASYNC clock if this pipeline includes FIMC-IS */ + if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) { + ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]); + if (ret < 0) + return ret; + } + + ret = fimc_pipeline_s_power(p, 1); + if (!ret) + return 0; + + if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) + clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); + + return ret; +} + /** * __fimc_pipeline_open - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock @@ -199,7 +230,6 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, struct fimc_md *fmd = entity_to_fimc_mdev(me); struct fimc_pipeline *p = to_fimc_pipeline(ep); struct v4l2_subdev *sd; - int ret; if (WARN_ON(p == NULL || me == NULL)) return -EINVAL; @@ -208,24 +238,16 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, fimc_pipeline_prepare(p, me); sd = p->subdevs[IDX_SENSOR]; - if (sd == NULL) - return -EINVAL; - - /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */ - if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) { - ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]); - if (ret < 0) - return ret; - } - - ret = fimc_pipeline_s_power(p, 1); - if (!ret) + if (sd == NULL) { + pr_warn("%s(): No sensor subdev\n", __func__); + /* + * Pipeline open cannot fail so as to make it possible + * for the user space to configure the pipeline. + */ return 0; + } - if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) - clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); - - return ret; + return __fimc_pipeline_enable(ep, fmd); } /** @@ -269,10 +291,43 @@ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on) { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, }; struct fimc_pipeline *p = to_fimc_pipeline(ep); + struct fimc_md *fmd = entity_to_fimc_mdev(&p->subdevs[IDX_CSIS]->entity); + enum fimc_subdev_index sd_id; int i, ret = 0; - if (p->subdevs[IDX_SENSOR] == NULL) - return -ENODEV; + if (p->subdevs[IDX_SENSOR] == NULL) { + if (!fmd->user_subdev_api) { + /* + * Sensor must be already discovered if we + * aren't in the user_subdev_api mode + */ + return -ENODEV; + } + + /* Get pipeline sink entity */ + if (p->subdevs[IDX_FIMC]) + sd_id = IDX_FIMC; + else if (p->subdevs[IDX_IS_ISP]) + sd_id = IDX_IS_ISP; + else if (p->subdevs[IDX_FLITE]) + sd_id = IDX_FLITE; + else + return -ENODEV; + + /* + * Sensor could have been linked between open and STREAMON - + * check if this is the case. + */ + fimc_pipeline_prepare(p, &p->subdevs[sd_id]->entity); + + if (p->subdevs[IDX_SENSOR] == NULL) + return -ENODEV; + + ret = __fimc_pipeline_enable(ep, fmd); + if (ret < 0) + return ret; + + } for (i = 0; i < IDX_MAX; i++) { unsigned int idx = seq[on][i]; @@ -282,8 +337,10 @@ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on) if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) goto error; } + return 0; error: + fimc_pipeline_s_power(p, !on); for (; i >= 0; i--) { unsigned int idx = seq[on][i]; v4l2_subdev_call(p->subdevs[idx], video, s_stream, !on); -- cgit v1.2.3 From a13ddcae4f0bc5e1de761895d0cae2010e1934af Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 18 Jan 2016 14:10:27 -0200 Subject: [media] exynos4-is: Wait for 100us before opening sensor Some user space use cases result in kernel hangup on the HIC_OPEN_SENSOR command write. In case when a minimalistic application is used for setting up the streaming, the hangups occur only occasionally. In case of GStreamer use cases it is always the case. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-is.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 49658ca39e51..979c388ebf60 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -631,6 +631,12 @@ static int fimc_is_hw_open_sensor(struct fimc_is *is, fimc_is_mem_barrier(); + /* + * Some user space use cases hang up here without this + * empirically chosen delay. + */ + udelay(100); + mcuctl_write(HIC_OPEN_SENSOR, is, MCUCTL_REG_ISSR(0)); mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1)); mcuctl_write(sensor->drvdata->id, is, MCUCTL_REG_ISSR(2)); -- cgit v1.2.3 From 420520766a796d36076111139ba1e4fb1aadeadd Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 30 Dec 2015 11:26:03 -0200 Subject: [media] media: Kconfig: add dependency of HAS_DMA The build of m32r allmodconfig fails with the error: drivers/media/v4l2-core/videobuf2-dma-contig.c:484:2: error: implicit declaration of function 'dma_get_cache_alignment' The build of videobuf2-dma-contig.c depends on HAS_DMA and it is correctly mentioned in the Kconfig but the symbol VIDEO_STI_BDISP also selects VIDEOBUF2_DMA_CONTIG, so it is trying to compile videobuf2-dma-contig.c even though HAS_DMA is not defined. Signed-off-by: Sudip Mukherjee Acked-by: Sakari Ailus Acked-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 526359447ff9..8b89ebe16d94 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -215,6 +215,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_STI_BDISP tristate "STMicroelectronics BDISP 2D blitter driver" depends on VIDEO_DEV && VIDEO_V4L2 + depends on HAS_DMA depends on ARCH_STI || COMPILE_TEST select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV -- cgit v1.2.3 From a63abe389d56f6f7b1541c2084b453c9dfdb89dc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 4 Dec 2015 20:20:09 -0200 Subject: [media] exynos4-is: make VIDEO_SAMSUNG_EXYNOS4_IS tristate With CONFIG_V4L2=m and VIDEO_SAMSUNG_EXYNOS4_IS=y, we can select the individual drivers as built-in code when that should not be possible: drivers/built-in.o: In function `s5pcsis_set_fmt': policy.c:(.text+0x13afdc): undefined reference to `v4l_bound_align_image' drivers/built-in.o: In function `s5pcsis_probe': policy.c:(.text+0x13b440): undefined reference to `v4l2_of_parse_endpoint' policy.c:(.text+0x13b72c): undefined reference to `v4l2_subdev_init' Changing VIDEO_SAMSUNG_EXYNOS4_IS to tristate means that the dependency from CONFIG_V4L2 propates to the individual Kconfig symbols and they can only be built as loadable modules if V4L2 or any other of the dependencies itself is a module. Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index 40423c6c5324..57d42c6172c5 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SAMSUNG_EXYNOS4_IS - bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" + tristate "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on OF && COMMON_CLK -- cgit v1.2.3 From 329d88da4df9a96da43018aceabd3a06e6a7e7ae Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 27 Jan 2016 12:03:23 -0200 Subject: [media] media: i2c: Don't export ir-kbd-i2c module alias This is a partial revert of commit ed8d1cf07cb16d ("[media] Export I2C module alias information in missing drivers") that exported the module aliases for the I2C drivers that were missing to make autoload to work. But there is a bug report [0] that auto load of the ir-kbd-i2c driver cause the Hauppauge HD-PVR driver to not behave correctly. This is a hdpvr latent bug that was just exposed by ir-kbd-i2c module autoloading working and will also happen if the I2C driver is built-in or a user calls modprobe to load the module and register the driver. But there is a regression experimented by users so until the real bug is fixed, let's not export the module alias for the ir-kbd-i2c driver even when this just masks the actual issue. [0]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=810726 Fixes: ed8d1cf07cb1 ("[media] Export I2C module alias information in missing drivers") Cc: # 4.3+ Signed-off-by: Javier Martinez Canillas --- drivers/media/i2c/ir-kbd-i2c.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index 830491960add..bf82726fd3f4 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -478,7 +478,6 @@ static const struct i2c_device_id ir_kbd_id[] = { { "ir_rx_z8f0811_hdpvr", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, ir_kbd_id); static struct i2c_driver ir_kbd_driver = { .driver = { -- cgit v1.2.3 From e8beb02343e7582980c6705816cd957cf4f74c7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 3 Feb 2016 17:33:48 -0200 Subject: [media] tda1004x: only update the frontend properties if locked The tda1004x was updating the properties cache before locking. If the device is not locked, the data at the registers are just random values with no real meaning. This caused the driver to fail with libdvbv5, as such library calls GET_PROPERTY from time to time, in order to return the DVB stats. Tested with a saa7134 card 78: ASUSTeK P7131 Dual, vendor PCI ID: 1043:4862 Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/tda1004x.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c index 0e209b56c76c..c6abeb4fba9d 100644 --- a/drivers/media/dvb-frontends/tda1004x.c +++ b/drivers/media/dvb-frontends/tda1004x.c @@ -903,9 +903,18 @@ static int tda1004x_get_fe(struct dvb_frontend *fe) { struct dtv_frontend_properties *fe_params = &fe->dtv_property_cache; struct tda1004x_state* state = fe->demodulator_priv; + int status; dprintk("%s\n", __func__); + status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); + if (status == -1) + return -EIO; + + /* Only update the properties cache if device is locked */ + if (!(status & 8)) + return 0; + // inversion status fe_params->inversion = INVERSION_OFF; if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) -- cgit v1.2.3 From fac710e45d0b12443acd4d905c9acec27ab4ca14 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 27 Jan 2016 10:08:42 -0200 Subject: [media] vb2: fix nasty vb2_thread regression The vb2_thread implementation was made generic and was moved from videobuf2-v4l2.c to videobuf2-core.c in commit af3bac1a. Unfortunately that clearly was never tested since it broke read() causing NULL address references. The root cause was confused handling of vb2_buffer vs v4l2_buffer (the pb pointer in various core functions). The v4l2_buffer no longer exists after moving the code into the core and it is no longer needed. However, the vb2_thread code passed a pointer to a vb2_buffer to the core functions were a v4l2_buffer pointer was expected and vb2_thread expected that the vb2_buffer fields would be filled in correctly. This is obviously wrong since v4l2_buffer != vb2_buffer. Note that the pb pointer is a void pointer, so no type-checking took place. This patch fixes this problem: 1) allow pb to be NULL for vb2_core_(d)qbuf. The vb2_thread code will use a NULL pointer here since they don't care about v4l2_buffer anyway. 2) let vb2_core_dqbuf pass back the index of the received buffer. This is all vb2_thread needs: this index is the index into the q->bufs array and vb2_thread just gets the vb2_buffer from there. 3) the fileio->b pointer (that originally contained a v4l2_buffer) is removed altogether since it is no longer needed. Tested with vivid and the cobalt driver. Cc: stable@vger.kernel.org # Kernel >= 4.3 Signed-off-by: Hans Verkuil Reported-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 95 +++++++++++++++----------------- drivers/media/v4l2-core/videobuf2-v4l2.c | 2 +- include/media/videobuf2-core.h | 3 +- 3 files changed, 46 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index c5d49d7a0d76..b53e42c329cb 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1063,8 +1063,11 @@ EXPORT_SYMBOL_GPL(vb2_discard_done); */ static int __qbuf_mmap(struct vb2_buffer *vb, const void *pb) { - int ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, - vb, pb, vb->planes); + int ret = 0; + + if (pb) + ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, + vb, pb, vb->planes); return ret ? ret : call_vb_qop(vb, buf_prepare, vb); } @@ -1077,14 +1080,16 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb) struct vb2_queue *q = vb->vb2_queue; void *mem_priv; unsigned int plane; - int ret; + int ret = 0; enum dma_data_direction dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); /* Copy relevant information provided by the userspace */ - ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, vb, pb, planes); + if (pb) + ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, + vb, pb, planes); if (ret) return ret; @@ -1192,14 +1197,16 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb) struct vb2_queue *q = vb->vb2_queue; void *mem_priv; unsigned int plane; - int ret; + int ret = 0; enum dma_data_direction dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); /* Copy relevant information provided by the userspace */ - ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, vb, pb, planes); + if (pb) + ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, + vb, pb, planes); if (ret) return ret; @@ -1520,7 +1527,8 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) q->waiting_for_buffers = false; vb->state = VB2_BUF_STATE_QUEUED; - call_void_bufop(q, copy_timestamp, vb, pb); + if (pb) + call_void_bufop(q, copy_timestamp, vb, pb); trace_vb2_qbuf(q, vb); @@ -1532,7 +1540,8 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) __enqueue_in_driver(vb); /* Fill buffer information for the userspace */ - call_void_bufop(q, fill_user_buffer, vb, pb); + if (pb) + call_void_bufop(q, fill_user_buffer, vb, pb); /* * If streamon has been called, and we haven't yet called @@ -1731,7 +1740,8 @@ static void __vb2_dqbuf(struct vb2_buffer *vb) * The return values from this function are intended to be directly returned * from vidioc_dqbuf handler in driver. */ -int vb2_core_dqbuf(struct vb2_queue *q, void *pb, bool nonblocking) +int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, + bool nonblocking) { struct vb2_buffer *vb = NULL; int ret; @@ -1754,8 +1764,12 @@ int vb2_core_dqbuf(struct vb2_queue *q, void *pb, bool nonblocking) call_void_vb_qop(vb, buf_finish, vb); + if (pindex) + *pindex = vb->index; + /* Fill buffer information for the userspace */ - call_void_bufop(q, fill_user_buffer, vb, pb); + if (pb) + call_void_bufop(q, fill_user_buffer, vb, pb); /* Remove from videobuf queue */ list_del(&vb->queued_entry); @@ -1828,7 +1842,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) * that's done in dqbuf, but that's not going to happen when we * cancel the whole queue. Note: this code belongs here, not in * __vb2_dqbuf() since in vb2_internal_dqbuf() there is a critical - * call to __fill_v4l2_buffer() after buf_finish(). That order can't + * call to __fill_user_buffer() after buf_finish(). That order can't * be changed, so we can't move the buf_finish() to __vb2_dqbuf(). */ for (i = 0; i < q->num_buffers; ++i) { @@ -2357,7 +2371,6 @@ struct vb2_fileio_data { unsigned int count; unsigned int type; unsigned int memory; - struct vb2_buffer *b; struct vb2_fileio_buf bufs[VB2_MAX_FRAME]; unsigned int cur_index; unsigned int initial_index; @@ -2410,12 +2423,6 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) if (fileio == NULL) return -ENOMEM; - fileio->b = kzalloc(q->buf_struct_size, GFP_KERNEL); - if (fileio->b == NULL) { - kfree(fileio); - return -ENOMEM; - } - fileio->read_once = q->fileio_read_once; fileio->write_immediately = q->fileio_write_immediately; @@ -2460,13 +2467,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) * Queue all buffers. */ for (i = 0; i < q->num_buffers; i++) { - struct vb2_buffer *b = fileio->b; - - memset(b, 0, q->buf_struct_size); - b->type = q->type; - b->memory = q->memory; - b->index = i; - ret = vb2_core_qbuf(q, i, b); + ret = vb2_core_qbuf(q, i, NULL); if (ret) goto err_reqbufs; fileio->bufs[i].queued = 1; @@ -2511,7 +2512,6 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q) q->fileio = NULL; fileio->count = 0; vb2_core_reqbufs(q, fileio->memory, &fileio->count); - kfree(fileio->b); kfree(fileio); dprintk(3, "file io emulator closed\n"); } @@ -2539,7 +2539,8 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ * else is able to provide this information with the write() operation. */ bool copy_timestamp = !read && q->copy_timestamp; - int ret, index; + unsigned index; + int ret; dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, @@ -2564,22 +2565,20 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ */ index = fileio->cur_index; if (index >= q->num_buffers) { - struct vb2_buffer *b = fileio->b; + struct vb2_buffer *b; /* * Call vb2_dqbuf to get buffer back. */ - memset(b, 0, q->buf_struct_size); - b->type = q->type; - b->memory = q->memory; - ret = vb2_core_dqbuf(q, b, nonblock); + ret = vb2_core_dqbuf(q, &index, NULL, nonblock); dprintk(5, "vb2_dqbuf result: %d\n", ret); if (ret) return ret; fileio->dq_count += 1; - fileio->cur_index = index = b->index; + fileio->cur_index = index; buf = &fileio->bufs[index]; + b = q->bufs[index]; /* * Get number of bytes filled by the driver @@ -2630,7 +2629,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && fileio->write_immediately)) { - struct vb2_buffer *b = fileio->b; + struct vb2_buffer *b = q->bufs[index]; /* * Check if this is the last buffer to read. @@ -2643,15 +2642,11 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ /* * Call vb2_qbuf and give buffer to the driver. */ - memset(b, 0, q->buf_struct_size); - b->type = q->type; - b->memory = q->memory; - b->index = index; b->planes[0].bytesused = buf->pos; if (copy_timestamp) b->timestamp = ktime_get_ns(); - ret = vb2_core_qbuf(q, index, b); + ret = vb2_core_qbuf(q, index, NULL); dprintk(5, "vb2_dbuf result: %d\n", ret); if (ret) return ret; @@ -2713,10 +2708,9 @@ static int vb2_thread(void *data) { struct vb2_queue *q = data; struct vb2_threadio_data *threadio = q->threadio; - struct vb2_fileio_data *fileio = q->fileio; bool copy_timestamp = false; - int prequeue = 0; - int index = 0; + unsigned prequeue = 0; + unsigned index = 0; int ret = 0; if (q->is_output) { @@ -2728,37 +2722,34 @@ static int vb2_thread(void *data) for (;;) { struct vb2_buffer *vb; - struct vb2_buffer *b = fileio->b; /* * Call vb2_dqbuf to get buffer back. */ - memset(b, 0, q->buf_struct_size); - b->type = q->type; - b->memory = q->memory; if (prequeue) { - b->index = index++; + vb = q->bufs[index++]; prequeue--; } else { call_void_qop(q, wait_finish, q); if (!threadio->stop) - ret = vb2_core_dqbuf(q, b, 0); + ret = vb2_core_dqbuf(q, &index, NULL, 0); call_void_qop(q, wait_prepare, q); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); + if (!ret) + vb = q->bufs[index]; } if (ret || threadio->stop) break; try_to_freeze(); - vb = q->bufs[b->index]; - if (b->state == VB2_BUF_STATE_DONE) + if (vb->state == VB2_BUF_STATE_DONE) if (threadio->fnc(vb, threadio->priv)) break; call_void_qop(q, wait_finish, q); if (copy_timestamp) - b->timestamp = ktime_get_ns();; + vb->timestamp = ktime_get_ns();; if (!threadio->stop) - ret = vb2_core_qbuf(q, b->index, b); + ret = vb2_core_qbuf(q, vb->index, NULL); call_void_qop(q, wait_prepare, q); if (ret || threadio->stop) break; diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index c9a28605511a..91f552124050 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c @@ -625,7 +625,7 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, return -EINVAL; } - ret = vb2_core_dqbuf(q, b, nonblocking); + ret = vb2_core_dqbuf(q, NULL, b, nonblocking); return ret; } diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index ef03ae56b1c1..8a0f55b6c2ba 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -533,7 +533,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, const unsigned int requested_sizes[]); int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb); -int vb2_core_dqbuf(struct vb2_queue *q, void *pb, bool nonblocking); +int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, + bool nonblocking); int vb2_core_streamon(struct vb2_queue *q, unsigned int type); int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); -- cgit v1.2.3 From 1f2c450185b7b8d50d38d37ee30387ff4cd337f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 3 Feb 2016 19:30:31 -0200 Subject: [media] vb2-core: call threadio->fnc() if !VB2_BUF_STATE_ERROR changeset 70433a152f0 ("media: videobuf2: Refactor vb2_fileio_data and vb2_thread") broke videobuf2-dvb. The root cause is that, instead of calling threadio->fnc() for all types of events except for VB2_BUF_STATE_ERROR, it was calling it only for VB2_BUF_STATE_DONE. With that, the DVB thread were never called. Cc: stable@vger.kernel.org # Kernel >= 4.3 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index b53e42c329cb..ff8953ae52d1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2742,7 +2742,7 @@ static int vb2_thread(void *data) break; try_to_freeze(); - if (vb->state == VB2_BUF_STATE_DONE) + if (vb->state != VB2_BUF_STATE_ERROR) if (threadio->fnc(vb, threadio->priv)) break; call_void_qop(q, wait_finish, q); -- cgit v1.2.3 From ac75fe5d8fe4a0bf063be18fb29684405279e79e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 4 Feb 2016 15:59:43 -0200 Subject: [media] saa7134-alsa: Only frees registered sound cards That prevents this bug: [ 2382.269496] BUG: unable to handle kernel NULL pointer dereference at 0000000000000540 [ 2382.270013] IP: [] snd_card_free+0x36/0x70 [snd] [ 2382.270013] PGD 0 [ 2382.270013] Oops: 0002 [#1] SMP [ 2382.270013] Modules linked in: saa7134_alsa(-) tda1004x saa7134_dvb videobuf2_dvb dvb_core tda827x tda8290 tuner saa7134 tveeprom videobuf2_dma_sg videobuf2_memops videobuf2_v4l2 videobuf2_core v4l2_common videodev media auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc tun bridge stp llc ebtables ip6table_filter ip6_tables nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack it87 hwmon_vid snd_hda_codec_idt snd_hda_codec_generic iTCO_wdt iTCO_vendor_support snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_seq pcspkr i2c_i801 snd_seq_device snd_pcm snd_timer lpc_ich snd mfd_core soundcore binfmt_misc i915 video i2c_algo_bit drm_kms_helper drm r8169 ata_generic serio_raw pata_acpi mii i2c_core [last unloaded: videobuf2_memops] [ 2382.270013] CPU: 0 PID: 4899 Comm: rmmod Not tainted 4.5.0-rc1+ #4 [ 2382.270013] Hardware name: PCCHIPS P17G/P17G, BIOS 080012 05/14/2008 [ 2382.270013] task: ffff880039c38000 ti: ffff88003c764000 task.ti: ffff88003c764000 [ 2382.270013] RIP: 0010:[] [] snd_card_free+0x36/0x70 [snd] [ 2382.270013] RSP: 0018:ffff88003c767ea0 EFLAGS: 00010286 [ 2382.270013] RAX: ffff88003c767eb8 RBX: 0000000000000000 RCX: 0000000000006260 [ 2382.270013] RDX: ffffffffa020a060 RSI: ffffffffa0206de1 RDI: ffff88003c767eb0 [ 2382.270013] RBP: ffff88003c767ed8 R08: 0000000000019960 R09: ffffffff811a5412 [ 2382.270013] R10: ffffea0000d7c200 R11: 0000000000000000 R12: ffff88003c767ea8 [ 2382.270013] R13: 00007ffe760617f7 R14: 0000000000000000 R15: 0000557625d7f1e0 [ 2382.270013] FS: 00007f80bb1c0700(0000) GS:ffff88003f400000(0000) knlGS:0000000000000000 [ 2382.270013] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 2382.270013] CR2: 0000000000000540 CR3: 000000003c00f000 CR4: 00000000000006f0 [ 2382.270013] Stack: [ 2382.270013] 000000003c767ed8 ffffffff00000000 ffff880000000000 ffff88003c767eb8 [ 2382.270013] ffff88003c767eb8 ffffffffa049a890 00007ffe76060060 ffff88003c767ef0 [ 2382.270013] ffffffffa049889d ffffffffa049a500 ffff88003c767f48 ffffffff8111079c [ 2382.270013] Call Trace: [ 2382.270013] [] saa7134_alsa_exit+0x1d/0x780 [saa7134_alsa] [ 2382.270013] [] SyS_delete_module+0x19c/0x1f0 [ 2382.270013] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 2382.270013] Code: 20 a0 48 c7 c6 e1 6d 20 a0 48 89 e5 41 54 53 4c 8d 65 d0 48 89 fb 48 83 ec 28 c7 45 d0 00 00 00 00 49 8d 7c 24 08 e8 7a 55 ed e0 <4c> 89 a3 40 05 00 00 48 89 df e8 eb fd ff ff 85 c0 75 1a 48 8d [ 2382.270013] RIP [] snd_card_free+0x36/0x70 [snd] [ 2382.270013] RSP [ 2382.270013] CR2: 0000000000000540 Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-alsa.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 1d2c310ce838..94f816244407 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -1211,6 +1211,8 @@ static int alsa_device_init(struct saa7134_dev *dev) static int alsa_device_exit(struct saa7134_dev *dev) { + if (!snd_saa7134_cards[dev->nr]) + return 1; snd_card_free(snd_saa7134_cards[dev->nr]); snd_saa7134_cards[dev->nr] = NULL; @@ -1260,7 +1262,8 @@ static void saa7134_alsa_exit(void) int idx; for (idx = 0; idx < SNDRV_CARDS; idx++) { - snd_card_free(snd_saa7134_cards[idx]); + if (snd_saa7134_cards[idx]) + snd_card_free(snd_saa7134_cards[idx]); } saa7134_dmasound_init = NULL; -- cgit v1.2.3