summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig12
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c2
-rw-r--r--drivers/media/pci/cx88/cx88-alsa.c7
-rw-r--r--drivers/media/pci/cx88/cx88-video.c8
-rw-r--r--drivers/media/platform/coda.c9
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c15
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c3
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-regs.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c48
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c4
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c2
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.h2
-rw-r--r--drivers/media/platform/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/platform/s5p-mfc/Makefile2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c8
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_debug.h4
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c20
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c82
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c4
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c53
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c23
-rw-r--r--drivers/media/platform/sh_veu.c15
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c4
-rw-r--r--drivers/media/radio/Kconfig1
-rw-r--r--drivers/media/radio/radio-si476x.c2
-rw-r--r--drivers/media/tuners/Kconfig20
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c6
-rw-r--r--drivers/media/usb/gspca/sonixb.c7
-rw-r--r--drivers/media/usb/pwc/pwc.h2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c47
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c39
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c3
36 files changed, 235 insertions, 235 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 7f5a7cac6dc7..8270388e2a0d 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -136,9 +136,9 @@ config DVB_NET
# This Kconfig option is used by both PCI and USB drivers
config TTPCI_EEPROM
- tristate
- depends on I2C
- default n
+ tristate
+ depends on I2C
+ default n
source "drivers/media/dvb-core/Kconfig"
@@ -189,6 +189,12 @@ config MEDIA_SUBDRV_AUTOSELECT
If unsure say Y.
+config MEDIA_ATTACH
+ bool
+ depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
+ depends on MODULES
+ default MODULES
+
source "drivers/media/i2c/Kconfig"
source "drivers/media/tuners/Kconfig"
source "drivers/media/dvb-frontends/Kconfig"
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index cb52438e53ac..9eac5310942f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -956,7 +956,7 @@ static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd,
if (fie->pad != OIF_SOURCE_PAD)
return -EINVAL;
- if (fie->index > ARRAY_SIZE(s5c73m3_intervals))
+ if (fie->index >= ARRAY_SIZE(s5c73m3_intervals))
return -EINVAL;
mutex_lock(&state->lock);
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index 27d62623274b..aba5b1c649e6 100644
--- a/drivers/media/pci/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -615,7 +615,7 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
int changed = 0;
u32 old;
- if (core->board.audio_chip == V4L2_IDENT_WM8775)
+ if (core->sd_wm8775)
snd_cx88_wm8775_volume_put(kcontrol, value);
left = value->value.integer.value[0] & 0x3f;
@@ -682,8 +682,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
vol ^= bit;
cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
/* Pass mute onto any WM8775 */
- if ((core->board.audio_chip == V4L2_IDENT_WM8775) &&
- ((1<<6) == bit))
+ if (core->sd_wm8775 && ((1<<6) == bit))
wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit));
ret = 1;
}
@@ -903,7 +902,7 @@ static int cx88_audio_initdev(struct pci_dev *pci,
goto error;
/* If there's a wm8775 then add a Line-In ALC switch */
- if (core->board.audio_chip == V4L2_IDENT_WM8775)
+ if (core->sd_wm8775)
snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip));
strcpy (card->driver, "CX88x");
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index 1b00615fd395..c7a9be1065c0 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -385,8 +385,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
/* The wm8775 module has the "2" route hardwired into
the initialization. Some boards may use different
routes for different inputs. HVR-1300 surely does */
- if (core->board.audio_chip &&
- core->board.audio_chip == V4L2_IDENT_WM8775) {
+ if (core->sd_wm8775) {
call_all(core, audio, s_routing,
INPUT(input).audioroute, 0, 0);
}
@@ -771,8 +770,7 @@ static int video_open(struct file *file)
cx_write(MO_GP1_IO, core->board.radio.gpio1);
cx_write(MO_GP2_IO, core->board.radio.gpio2);
if (core->board.radio.audioroute) {
- if(core->board.audio_chip &&
- core->board.audio_chip == V4L2_IDENT_WM8775) {
+ if (core->sd_wm8775) {
call_all(core, audio, s_routing,
core->board.radio.audioroute, 0, 0);
}
@@ -959,7 +957,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl)
u32 value,mask;
/* Pass changes onto any WM8775 */
- if (core->board.audio_chip == V4L2_IDENT_WM8775) {
+ if (core->sd_wm8775) {
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
wm8775_s_ctrl(core, ctrl->id, ctrl->val);
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 48b8d7af386d..9d1481a60bd9 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -576,6 +576,14 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
}
+static int vidioc_create_bufs(struct file *file, void *priv,
+ struct v4l2_create_buffers *create)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create);
+}
+
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
@@ -610,6 +618,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_create_bufs = vidioc_create_bufs,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 1802f11e939f..d0b375cf565f 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -916,6 +916,21 @@ static int vpbe_display_s_fmt(struct file *file, void *priv,
other video window */
layer->pix_fmt = *pixfmt;
+ if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) {
+ struct vpbe_layer *otherlayer;
+
+ otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer);
+ /* if other layer is available, only
+ * claim it, do not configure it
+ */
+ ret = osd_device->ops.request_layer(osd_device,
+ otherlayer->layer_info.id);
+ if (ret < 0) {
+ v4l2_err(&vpbe_dev->v4l2_dev,
+ "Display Manager failed to allocate layer\n");
+ return -EBUSY;
+ }
+ }
/* Get osd layer config */
osd_device->ops.get_layer_config(osd_device,
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 8c50d3074866..93609091cb23 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1837,7 +1837,7 @@ static int vpfe_probe(struct platform_device *pdev)
if (NULL == ccdc_cfg) {
v4l2_err(pdev->dev.driver,
"Memory allocation failed for ccdc_cfg\n");
- goto probe_free_lock;
+ goto probe_free_dev_mem;
}
mutex_lock(&ccdc_lock);
@@ -1991,7 +1991,6 @@ probe_out_release_irq:
free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
probe_free_ccdc_cfg_mem:
kfree(ccdc_cfg);
-probe_free_lock:
mutex_unlock(&ccdc_lock);
probe_free_dev_mem:
kfree(vpfe_dev);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
index b0ff67bc1b05..d05eaa2c8490 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
@@ -174,7 +174,7 @@ int fimc_is_hw_change_mode(struct fimc_is *is)
HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO,
};
- if (WARN_ON(is->config_index > ARRAY_SIZE(cmd)))
+ if (WARN_ON(is->config_index >= ARRAY_SIZE(cmd)))
return -EINVAL;
mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0));
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 47c6363d04e2..0741945b79ed 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -48,7 +48,6 @@ static char *fimc_is_clocks[ISS_CLKS_MAX] = {
[ISS_CLK_LITE0] = "lite0",
[ISS_CLK_LITE1] = "lite1",
[ISS_CLK_MPLL] = "mpll",
- [ISS_CLK_SYSREG] = "sysreg",
[ISS_CLK_ISP] = "isp",
[ISS_CLK_DRC] = "drc",
[ISS_CLK_FD] = "fd",
@@ -71,7 +70,6 @@ static void fimc_is_put_clocks(struct fimc_is *is)
for (i = 0; i < ISS_CLKS_MAX; i++) {
if (IS_ERR(is->clocks[i]))
continue;
- clk_unprepare(is->clocks[i]);
clk_put(is->clocks[i]);
is->clocks[i] = ERR_PTR(-EINVAL);
}
@@ -90,12 +88,6 @@ static int fimc_is_get_clocks(struct fimc_is *is)
ret = PTR_ERR(is->clocks[i]);
goto err;
}
- ret = clk_prepare(is->clocks[i]);
- if (ret < 0) {
- clk_put(is->clocks[i]);
- is->clocks[i] = ERR_PTR(-EINVAL);
- goto err;
- }
}
return 0;
@@ -103,7 +95,7 @@ err:
fimc_is_put_clocks(is);
dev_err(&is->pdev->dev, "failed to get clock: %s\n",
fimc_is_clocks[i]);
- return -ENXIO;
+ return ret;
}
static int fimc_is_setup_clocks(struct fimc_is *is)
@@ -144,7 +136,7 @@ int fimc_is_enable_clocks(struct fimc_is *is)
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
if (IS_ERR(is->clocks[i]))
continue;
- ret = clk_enable(is->clocks[i]);
+ ret = clk_prepare_enable(is->clocks[i]);
if (ret < 0) {
dev_err(&is->pdev->dev, "clock %s enable failed\n",
fimc_is_clocks[i]);
@@ -163,7 +155,7 @@ void fimc_is_disable_clocks(struct fimc_is *is)
for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
if (!IS_ERR(is->clocks[i])) {
- clk_disable(is->clocks[i]);
+ clk_disable_unprepare(is->clocks[i]);
pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
}
}
@@ -326,6 +318,11 @@ int fimc_is_start_firmware(struct fimc_is *is)
struct device *dev = &is->pdev->dev;
int ret;
+ if (is->fw.f_w == NULL) {
+ dev_err(dev, "firmware is not loaded\n");
+ return -EINVAL;
+ }
+
memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size);
wmb();
@@ -837,23 +834,11 @@ static int fimc_is_probe(struct platform_device *pdev)
goto err_clk;
}
pm_runtime_enable(dev);
- /*
- * Enable only the ISP power domain, keep FIMC-IS clocks off until
- * the whole clock tree is configured. The ISP power domain needs
- * be active in order to acces any CMU_ISP clock registers.
- */
- ret = pm_runtime_get_sync(dev);
- if (ret < 0)
- goto err_irq;
-
- ret = fimc_is_setup_clocks(is);
- pm_runtime_put_sync(dev);
+ ret = pm_runtime_get_sync(dev);
if (ret < 0)
goto err_irq;
- is->clk_init = true;
-
is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
if (IS_ERR(is->alloc_ctx)) {
ret = PTR_ERR(is->alloc_ctx);
@@ -875,6 +860,8 @@ static int fimc_is_probe(struct platform_device *pdev)
if (ret < 0)
goto err_dfs;
+ pm_runtime_put_sync(dev);
+
dev_dbg(dev, "FIMC-IS registered successfully\n");
return 0;
@@ -894,9 +881,11 @@ err_clk:
static int fimc_is_runtime_resume(struct device *dev)
{
struct fimc_is *is = dev_get_drvdata(dev);
+ int ret;
- if (!is->clk_init)
- return 0;
+ ret = fimc_is_setup_clocks(is);
+ if (ret)
+ return ret;
return fimc_is_enable_clocks(is);
}
@@ -905,9 +894,7 @@ static int fimc_is_runtime_suspend(struct device *dev)
{
struct fimc_is *is = dev_get_drvdata(dev);
- if (is->clk_init)
- fimc_is_disable_clocks(is);
-
+ fimc_is_disable_clocks(is);
return 0;
}
@@ -941,7 +928,8 @@ static int fimc_is_remove(struct platform_device *pdev)
vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
fimc_is_put_clocks(is);
fimc_is_debugfs_remove(is);
- release_firmware(is->fw.f_w);
+ if (is->fw.f_w)
+ release_firmware(is->fw.f_w);
fimc_is_free_cpu_memory(is);
return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
index f5275a5b0156..d7db133b493f 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.h
+++ b/drivers/media/platform/exynos4-is/fimc-is.h
@@ -73,7 +73,6 @@ enum {
ISS_CLK_LITE0,
ISS_CLK_LITE1,
ISS_CLK_MPLL,
- ISS_CLK_SYSREG,
ISS_CLK_ISP,
ISS_CLK_DRC,
ISS_CLK_FD,
@@ -265,7 +264,6 @@ struct fimc_is {
spinlock_t slock;
struct clk *clocks[ISS_CLKS_MAX];
- bool clk_init;
void __iomem *regs;
void __iomem *pmu_regs;
int irq;
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index d63947f7b302..7ede30b5910f 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -138,7 +138,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
return 0;
}
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
mutex_lock(&isp->subdev_lock);
__is_get_frame_size(is, &cur_fmt);
@@ -194,7 +194,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
__func__, fmt->pad, mf->code, mf->width, mf->height);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
mutex_lock(&isp->subdev_lock);
__isp_subdev_try_format(isp, fmt);
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index a2eda9d5ac87..254d70fe762a 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -746,7 +746,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
node = v4l2_of_get_next_endpoint(node, NULL);
if (!node) {
dev_err(&pdev->dev, "No port node at %s\n",
- node->full_name);
+ pdev->dev.of_node->full_name);
return -EINVAL;
}
/* Get port node and validate MIPI-CSI channel id. */
diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h
index 261134baa655..35d2fcdc0036 100644
--- a/drivers/media/platform/s3c-camif/camif-core.h
+++ b/drivers/media/platform/s3c-camif/camif-core.h
@@ -229,7 +229,7 @@ struct camif_vp {
unsigned int state;
u16 fmt_flags;
u8 id;
- u8 rotation;
+ u16 rotation;
u8 hflip;
u8 vflip;
unsigned int offset;
diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile
index ddc2900d88a2..d18cb5edd2d5 100644
--- a/drivers/media/platform/s5p-jpeg/Makefile
+++ b/drivers/media/platform/s5p-jpeg/Makefile
@@ -1,2 +1,2 @@
s5p-jpeg-objs := jpeg-core.o
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile
index 379008c6d09a..15f59b324fef 100644
--- a/drivers/media/platform/s5p-mfc/Makefile
+++ b/drivers/media/platform/s5p-mfc/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc.o
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 01f9ae0dadb0..d12faa691af8 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -397,7 +397,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
leave_handle_frame:
spin_unlock_irqrestore(&dev->irqlock, flags);
if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
- || ctx->dst_queue_cnt < ctx->dpb_count)
+ || ctx->dst_queue_cnt < ctx->pb_count)
clear_work_bit(ctx);
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
@@ -473,7 +473,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx);
- ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
+ ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
dev);
ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count,
dev);
@@ -562,7 +562,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx,
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *mb_entry;
- mfc_debug(2, "Stream completed");
+ mfc_debug(2, "Stream completed\n");
s5p_mfc_clear_int_flags(dev);
ctx->int_type = reason;
@@ -1362,7 +1362,6 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
.port_num = MFC_NUM_PORTS,
.buf_size = &buf_size_v5,
.buf_align = &mfc_buf_align_v5,
- .mclk_name = "sclk_mfc",
.fw_name = "s5p-mfc.fw",
};
@@ -1389,7 +1388,6 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = {
.port_num = MFC_NUM_PORTS_V6,
.buf_size = &buf_size_v6,
.buf_align = &mfc_buf_align_v6,
- .mclk_name = "aclk_333",
.fw_name = "s5p-mfc-v6.fw",
};
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 202d1d7a37a8..ef4074cd5316 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -138,6 +138,7 @@ enum s5p_mfc_inst_state {
MFCINST_INIT = 100,
MFCINST_GOT_INST,
MFCINST_HEAD_PARSED,
+ MFCINST_HEAD_PRODUCED,
MFCINST_BUFS_SET,
MFCINST_RUNNING,
MFCINST_FINISHING,
@@ -231,7 +232,6 @@ struct s5p_mfc_variant {
unsigned int port_num;
struct s5p_mfc_buf_size *buf_size;
struct s5p_mfc_buf_align *buf_align;
- char *mclk_name;
char *fw_name;
};
@@ -438,7 +438,7 @@ struct s5p_mfc_enc_params {
u32 rc_framerate_num;
u32 rc_framerate_denom;
- union {
+ struct {
struct s5p_mfc_h264_enc_params h264;
struct s5p_mfc_mpeg4_enc_params mpeg4;
} codec;
@@ -602,7 +602,7 @@ struct s5p_mfc_ctx {
int after_packed_pb;
int sei_fp_parse;
- int dpb_count;
+ int pb_count;
int total_dpb_count;
int mv_count;
/* Buffers */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 2e5f30b40dea..dc1fc94a488d 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -38,7 +38,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size,
&dev->bank1, GFP_KERNEL);
- if (IS_ERR(dev->fw_virt_addr)) {
+ if (IS_ERR_OR_NULL(dev->fw_virt_addr)) {
dev->fw_virt_addr = NULL;
mfc_err("Allocating bitprocessor buffer failed\n");
return -ENOMEM;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h
index bd5cd4ae993c..8e608f5aa0d7 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h
@@ -30,8 +30,8 @@ extern int debug;
#define mfc_debug(level, fmt, args...)
#endif
-#define mfc_debug_enter() mfc_debug(5, "enter")
-#define mfc_debug_leave() mfc_debug(5, "leave")
+#define mfc_debug_enter() mfc_debug(5, "enter\n")
+#define mfc_debug_leave() mfc_debug(5, "leave\n")
#define mfc_err(fmt, args...) \
do { \
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index 4af53bd2f182..00b07032f4f0 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -210,11 +210,11 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
/* Context is to decode a frame */
if (ctx->src_queue_cnt >= 1 &&
ctx->state == MFCINST_RUNNING &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
+ ctx->dst_queue_cnt >= ctx->pb_count)
return 1;
/* Context is to return last frame */
if (ctx->state == MFCINST_FINISHING &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
+ ctx->dst_queue_cnt >= ctx->pb_count)
return 1;
/* Context is to set buffers */
if (ctx->src_queue_cnt >= 1 &&
@@ -224,7 +224,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
/* Resolution change */
if ((ctx->state == MFCINST_RES_CHANGE_INIT ||
ctx->state == MFCINST_RES_CHANGE_FLUSH) &&
- ctx->dst_queue_cnt >= ctx->dpb_count)
+ ctx->dst_queue_cnt >= ctx->pb_count)
return 1;
if (ctx->state == MFCINST_RES_CHANGE_END &&
ctx->src_queue_cnt >= 1)
@@ -537,7 +537,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
mfc_err("vb2_reqbufs on capture failed\n");
return ret;
}
- if (reqbufs->count < ctx->dpb_count) {
+ if (reqbufs->count < ctx->pb_count) {
mfc_err("Not enough buffers allocated\n");
reqbufs->count = 0;
s5p_mfc_clock_on();
@@ -751,7 +751,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
if (ctx->state >= MFCINST_HEAD_PARSED &&
ctx->state < MFCINST_ABORT) {
- ctrl->val = ctx->dpb_count;
+ ctrl->val = ctx->pb_count;
break;
} else if (ctx->state != MFCINST_INIT) {
v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
@@ -763,7 +763,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);
if (ctx->state >= MFCINST_HEAD_PARSED &&
ctx->state < MFCINST_ABORT) {
- ctrl->val = ctx->dpb_count;
+ ctrl->val = ctx->pb_count;
} else {
v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
return -EINVAL;
@@ -924,10 +924,10 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
/* Output plane count is 2 - one for Y and one for CbCr */
*plane_count = 2;
/* Setup buffer count */
- if (*buf_count < ctx->dpb_count)
- *buf_count = ctx->dpb_count;
- if (*buf_count > ctx->dpb_count + MFC_MAX_EXTRA_DPB)
- *buf_count = ctx->dpb_count + MFC_MAX_EXTRA_DPB;
+ if (*buf_count < ctx->pb_count)
+ *buf_count = ctx->pb_count;
+ if (*buf_count > ctx->pb_count + MFC_MAX_EXTRA_DPB)
+ *buf_count = ctx->pb_count + MFC_MAX_EXTRA_DPB;
if (*buf_count > MFC_MAX_BUFFERS)
*buf_count = MFC_MAX_BUFFERS;
} else {
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 4f6b553c4b2d..2549967b2f85 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -592,7 +592,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
return 1;
/* context is ready to encode a frame */
if ((ctx->state == MFCINST_RUNNING ||
- ctx->state == MFCINST_HEAD_PARSED) &&
+ ctx->state == MFCINST_HEAD_PRODUCED) &&
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
return 1;
/* context is ready to encode remaining frames */
@@ -649,6 +649,7 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
struct s5p_mfc_enc_params *p = &ctx->enc_params;
struct s5p_mfc_buf *dst_mb;
unsigned long flags;
+ unsigned int enc_pb_count;
if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
spin_lock_irqsave(&dev->irqlock, flags);
@@ -661,18 +662,19 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
spin_unlock_irqrestore(&dev->irqlock, flags);
}
- if (IS_MFCV6(dev)) {
- ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
- } else {
+
+ if (!IS_MFCV6(dev)) {
ctx->state = MFCINST_RUNNING;
if (s5p_mfc_ctx_ready(ctx))
set_work_bit_irqsave(ctx);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
- }
-
- if (IS_MFCV6(dev))
- ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops,
+ } else {
+ enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops,
get_enc_dpb_count, dev);
+ if (ctx->pb_count < enc_pb_count)
+ ctx->pb_count = enc_pb_count;
+ ctx->state = MFCINST_HEAD_PRODUCED;
+ }
return 0;
}
@@ -717,9 +719,9 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
- mfc_debug(2, "Encoded slice type: %d", slice_type);
- mfc_debug(2, "Encoded stream size: %d", strm_size);
- mfc_debug(2, "Display order: %d",
+ mfc_debug(2, "Encoded slice type: %d\n", slice_type);
+ mfc_debug(2, "Encoded stream size: %d\n", strm_size);
+ mfc_debug(2, "Display order: %d\n",
mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
spin_lock_irqsave(&dev->irqlock, flags);
if (slice_type >= 0) {
@@ -1055,15 +1057,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
}
ctx->capture_state = QUEUE_BUFS_REQUESTED;
- if (!IS_MFCV6(dev)) {
- ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
- alloc_codec_buffers, ctx);
- if (ret) {
- mfc_err("Failed to allocate encoding buffers\n");
- reqbufs->count = 0;
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- return -ENOMEM;
- }
+ ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
+ alloc_codec_buffers, ctx);
+ if (ret) {
+ mfc_err("Failed to allocate encoding buffers\n");
+ reqbufs->count = 0;
+ ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+ return -ENOMEM;
}
} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
if (ctx->output_state != QUEUE_FREE) {
@@ -1071,6 +1071,19 @@ static int vidioc_reqbufs(struct file *file, void *priv,
ctx->output_state);
return -EINVAL;
}
+
+ if (IS_MFCV6(dev)) {
+ /* Check for min encoder buffers */
+ if (ctx->pb_count &&
+ (reqbufs->count < ctx->pb_count)) {
+ reqbufs->count = ctx->pb_count;
+ mfc_debug(2, "Minimum %d output buffers needed\n",
+ ctx->pb_count);
+ } else {
+ ctx->pb_count = reqbufs->count;
+ }
+ }
+
ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
if (ret != 0) {
mfc_err("error in vb2_reqbufs() for E(S)\n");
@@ -1533,14 +1546,14 @@ int vidioc_encoder_cmd(struct file *file, void *priv,
spin_lock_irqsave(&dev->irqlock, flags);
if (list_empty(&ctx->src_queue)) {
- mfc_debug(2, "EOS: empty src queue, entering finishing state");
+ mfc_debug(2, "EOS: empty src queue, entering finishing state\n");
ctx->state = MFCINST_FINISHING;
if (s5p_mfc_ctx_ready(ctx))
set_work_bit_irqsave(ctx);
spin_unlock_irqrestore(&dev->irqlock, flags);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
} else {
- mfc_debug(2, "EOS: marking last buffer of stream");
+ mfc_debug(2, "EOS: marking last buffer of stream\n");
buf = list_entry(ctx->src_queue.prev,
struct s5p_mfc_buf, list);
if (buf->flags & MFC_BUF_FLAG_USED)
@@ -1609,9 +1622,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
mfc_err("failed to get plane cookie\n");
return -EINVAL;
}
- mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx",
- vb->v4l2_buf.index, i,
- vb2_dma_contig_plane_dma_addr(vb, i));
+ mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx\n",
+ vb->v4l2_buf.index, i,
+ vb2_dma_contig_plane_dma_addr(vb, i));
}
return 0;
}
@@ -1760,11 +1773,27 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
struct s5p_mfc_dev *dev = ctx->dev;
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+ if (IS_MFCV6(dev) && (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
+
+ if ((ctx->state == MFCINST_GOT_INST) &&
+ (dev->curr_ctx == ctx->num) && dev->hw_lock) {
+ s5p_mfc_wait_for_done_ctx(ctx,
+ S5P_MFC_R2H_CMD_SEQ_DONE_RET,
+ 0);
+ }
+
+ if (ctx->src_bufs_cnt < ctx->pb_count) {
+ mfc_err("Need minimum %d OUTPUT buffers\n",
+ ctx->pb_count);
+ return -EINVAL;
+ }
+ }
+
/* If context is ready then dev = work->data;schedule it to run */
if (s5p_mfc_ctx_ready(ctx))
set_work_bit_irqsave(ctx);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+
return 0;
}
@@ -1920,6 +1949,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
if (controls[i].is_volatile && ctx->ctrls[i])
ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
}
+ v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
return 0;
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
index 0af05a2d1cd4..368582b091bf 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -1275,8 +1275,8 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- mfc_debug(2, "encoding buffer with index=%d state=%d",
- src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
+ mfc_debug(2, "encoding buffer with index=%d state=%d\n",
+ src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
s5p_mfc_encode_one_frame_v5(ctx);
return 0;
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index 7e76fce2e524..66f0d042357f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -62,12 +62,6 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
/* NOP */
}
-static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev)
-{
- /* NOP */
- return -1;
-}
-
/* Allocate codec buffers */
static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
{
@@ -167,7 +161,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
ctx->bank1.size =
ctx->scratch_buf_size + ctx->tmv_buffer_size +
- (ctx->dpb_count * (ctx->luma_dpb_size +
+ (ctx->pb_count * (ctx->luma_dpb_size +
ctx->chroma_dpb_size + ctx->me_buffer_size));
ctx->bank2.size = 0;
break;
@@ -181,7 +175,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
ctx->bank1.size =
ctx->scratch_buf_size + ctx->tmv_buffer_size +
- (ctx->dpb_count * (ctx->luma_dpb_size +
+ (ctx->pb_count * (ctx->luma_dpb_size +
ctx->chroma_dpb_size + ctx->me_buffer_size));
ctx->bank2.size = 0;
break;
@@ -198,7 +192,6 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
}
BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
}
-
return 0;
}
@@ -449,8 +442,8 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */
WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6);
- mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d",
- addr, size);
+ mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n",
+ addr, size);
return 0;
}
@@ -463,8 +456,8 @@ static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */
WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6);
- mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr);
- mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr);
+ mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr);
+ mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr);
}
static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
@@ -479,8 +472,8 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6);
enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6);
- mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr);
- mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr);
+ mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr);
+ mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr);
}
/* Set encoding ref & codec buffer */
@@ -497,7 +490,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
- for (i = 0; i < ctx->dpb_count; i++) {
+ for (i = 0; i < ctx->pb_count; i++) {
WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i));
buf_addr1 += ctx->luma_dpb_size;
WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i));
@@ -520,7 +513,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
buf_size1 -= ctx->tmv_buffer_size;
mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n",
- buf_addr1, buf_size1, ctx->dpb_count);
+ buf_addr1, buf_size1, ctx->pb_count);
if (buf_size1 < 0) {
mfc_debug(2, "Not enough memory has been allocated.\n");
return -ENOMEM;
@@ -1431,8 +1424,8 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
- mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr);
- mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr);
+ mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr);
+ mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr);
s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
@@ -1522,22 +1515,6 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
struct s5p_mfc_dev *dev = ctx->dev;
int ret;
- ret = s5p_mfc_alloc_codec_buffers_v6(ctx);
- if (ret) {
- mfc_err("Failed to allocate encoding buffers.\n");
- return -ENOMEM;
- }
-
- /* Header was generated now starting processing
- * First set the reference frame buffers
- */
- if (ctx->capture_state != QUEUE_BUFS_REQUESTED) {
- mfc_err("It seems that destionation buffers were not\n"
- "requested.MFC requires that header should be generated\n"
- "before allocating codec buffer.\n");
- return -EAGAIN;
- }
-
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
ret = s5p_mfc_set_enc_ref_buffer_v6(ctx);
@@ -1582,7 +1559,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
mfc_debug(1, "Seting new context to %p\n", ctx);
/* Got context to run in ctx */
mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n",
- ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt);
+ ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt);
mfc_debug(1, "ctx->state=%d\n", ctx->state);
/* Last frame has already been sent to MFC
* Now obtaining frames from MFC buffer */
@@ -1647,7 +1624,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
case MFCINST_GOT_INST:
s5p_mfc_run_init_enc(ctx);
break;
- case MFCINST_HEAD_PARSED: /* Only for MFC6.x */
+ case MFCINST_HEAD_PRODUCED:
ret = s5p_mfc_run_init_enc_buffers(ctx);
break;
default:
@@ -1730,7 +1707,7 @@ static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6);
}
-static int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev)
+static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev)
{
return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6);
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index 6aa38a56aaf2..11d5f1dada32 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -50,19 +50,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
goto err_p_ip_clk;
}
- pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name);
- if (IS_ERR(pm->clock)) {
- mfc_err("Failed to get MFC clock\n");
- ret = PTR_ERR(pm->clock);
- goto err_g_ip_clk_2;
- }
-
- ret = clk_prepare(pm->clock);
- if (ret) {
- mfc_err("Failed to prepare MFC clock\n");
- goto err_p_ip_clk_2;
- }
-
atomic_set(&pm->power, 0);
#ifdef CONFIG_PM_RUNTIME
pm->device = &dev->plat_dev->dev;
@@ -72,10 +59,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
atomic_set(&clk_ref, 0);
#endif
return 0;
-err_p_ip_clk_2:
- clk_put(pm->clock);
-err_g_ip_clk_2:
- clk_unprepare(pm->clock_gate);
err_p_ip_clk:
clk_put(pm->clock_gate);
err_g_ip_clk:
@@ -86,8 +69,6 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
{
clk_unprepare(pm->clock_gate);
clk_put(pm->clock_gate);
- clk_unprepare(pm->clock);
- clk_put(pm->clock);
#ifdef CONFIG_PM_RUNTIME
pm_runtime_disable(pm->device);
#endif
@@ -98,7 +79,7 @@ int s5p_mfc_clock_on(void)
int ret;
#ifdef CLK_DEBUG
atomic_inc(&clk_ref);
- mfc_debug(3, "+ %d", atomic_read(&clk_ref));
+ mfc_debug(3, "+ %d\n", atomic_read(&clk_ref));
#endif
ret = clk_enable(pm->clock_gate);
return ret;
@@ -108,7 +89,7 @@ void s5p_mfc_clock_off(void)
{
#ifdef CLK_DEBUG
atomic_dec(&clk_ref);
- mfc_debug(3, "- %d", atomic_read(&clk_ref));
+ mfc_debug(3, "- %d\n", atomic_read(&clk_ref));
#endif
clk_disable(pm->clock_gate);
}
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 0b32cc3f6a47..59a9deefb242 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -905,11 +905,11 @@ static int sh_veu_queue_setup(struct vb2_queue *vq,
if (ftmp.fmt.pix.width != pix->width ||
ftmp.fmt.pix.height != pix->height)
return -EINVAL;
- size = pix->bytesperline ? pix->bytesperline * pix->height :
- pix->width * pix->height * fmt->depth >> 3;
+ size = pix->bytesperline ? pix->bytesperline * pix->height * fmt->depth / fmt->ydepth :
+ pix->width * pix->height * fmt->depth / fmt->ydepth;
} else {
vfmt = sh_veu_get_vfmt(veu, vq->type);
- size = vfmt->bytesperline * vfmt->frame.height;
+ size = vfmt->bytesperline * vfmt->frame.height * vfmt->fmt->depth / vfmt->fmt->ydepth;
}
if (count < 2)
@@ -1033,8 +1033,6 @@ static int sh_veu_release(struct file *file)
dev_dbg(veu->dev, "Releasing instance %p\n", veu_file);
- pm_runtime_put(veu->dev);
-
if (veu_file == veu->capture) {
veu->capture = NULL;
vb2_queue_release(v4l2_m2m_get_vq(veu->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE));
@@ -1050,6 +1048,8 @@ static int sh_veu_release(struct file *file)
veu->m2m_ctx = NULL;
}
+ pm_runtime_put(veu->dev);
+
kfree(veu_file);
return 0;
@@ -1138,10 +1138,7 @@ static irqreturn_t sh_veu_isr(int irq, void *dev_id)
veu->xaction++;
- if (!veu->aborting)
- return IRQ_WAKE_THREAD;
-
- return IRQ_HANDLED;
+ return IRQ_WAKE_THREAD;
}
static int sh_veu_probe(struct platform_device *pdev)
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index eea832c5fd01..3a4efbdc7668 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -643,9 +643,9 @@ static int soc_camera_close(struct file *file)
if (ici->ops->init_videobuf2)
vb2_queue_release(&icd->vb2_vidq);
- ici->ops->remove(icd);
-
__soc_camera_power_off(icd);
+
+ ici->ops->remove(icd);
}
if (icd->streamer == file)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index c0beee2fa37c..d529ba788f41 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -22,6 +22,7 @@ config RADIO_SI476X
tristate "Silicon Laboratories Si476x I2C FM Radio"
depends on I2C && VIDEO_V4L2
depends on MFD_SI476X_CORE
+ depends on SND_SOC
select SND_SOC_SI476X
---help---
Choose Y here if you have this FM radio chip.
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 9430c6a29937..9dc8bafe6486 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -44,7 +44,7 @@
#define FREQ_MUL (10000000 / 625)
-#define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0b10000000 & (status))
+#define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0x80 & (status))
#define DRIVER_NAME "si476x-radio"
#define DRIVER_CARD "SI476x AM/FM Receiver"
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index f6768cad001a..15665debc572 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -1,23 +1,3 @@
-config MEDIA_ATTACH
- bool "Load and attach frontend and tuner driver modules as needed"
- depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
- depends on MODULES
- default y if !EXPERT
- help
- Remove the static dependency of DVB card drivers on all
- frontend modules for all possible card variants. Instead,
- allow the card drivers to only load the frontend modules
- they require.
-
- Also, tuner module will automatically load a tuner driver
- when needed, for analog mode.
-
- This saves several KBytes of memory.
-
- Note: You will need module-init-tools v3.2 or later for this feature.
-
- If unsure say Y.
-
# Analog TV tuners, auto-loaded via tuner.ko
config MEDIA_TUNER
tristate
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 22015fe1a0f3..2cc8ec70e3b6 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -376,7 +376,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
- struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 5, buf};
+ struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
dev_dbg(&d->udev->dev, "%s:\n", __func__);
@@ -481,9 +481,9 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
goto found;
}
- /* check R820T by reading tuner stats at I2C addr 0x1a */
+ /* check R820T ID register; reg=00 val=69 */
ret = rtl28xxu_ctrl_msg(d, &req_r820t);
- if (ret == 0) {
+ if (ret == 0 && buf[0] == 0x69) {
priv->tuner = TUNER_RTL2832_R820T;
priv->tuner_name = "R820T";
goto found;
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
index 3fe207e038c7..d7ff3b9687c5 100644
--- a/drivers/media/usb/gspca/sonixb.c
+++ b/drivers/media/usb/gspca/sonixb.c
@@ -1159,6 +1159,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
regs[0x01] = 0x44; /* Select 24 Mhz clock */
regs[0x12] = 0x02; /* Set hstart to 2 */
}
+ break;
+ case SENSOR_PAS202:
+ /* For some unknown reason we need to increase hstart by 1 on
+ the sn9c103, otherwise we get wrong colors (bayer shift). */
+ if (sd->bridge == BRIDGE_103)
+ regs[0x12] += 1;
+ break;
}
/* Disable compression when the raw bayer format has been selected */
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h
index 7a6a0d39c2c6..81b017a554bc 100644
--- a/drivers/media/usb/pwc/pwc.h
+++ b/drivers/media/usb/pwc/pwc.h
@@ -226,7 +226,7 @@ struct pwc_device
struct list_head queued_bufs;
spinlock_t queued_bufs_lock; /* Protects queued_bufs */
- /* Note if taking both locks v4l2_lock must always be locked first! */
+ /* If taking both locks vb_queue_lock must always be locked first! */
struct mutex v4l2_lock; /* Protects everything else */
struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index ebb8e48619a2..fccd08b66d1a 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1835,6 +1835,8 @@ bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl)
{
if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX)
return true;
+ if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_RX)
+ return true;
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_VOLUME:
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index f81bda1a48ec..7658586fe5f4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -243,7 +243,6 @@ static void v4l_print_format(const void *arg, bool write_only)
const struct v4l2_vbi_format *vbi;
const struct v4l2_sliced_vbi_format *sliced;
const struct v4l2_window *win;
- const struct v4l2_clip *clip;
unsigned i;
pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
@@ -253,7 +252,7 @@ static void v4l_print_format(const void *arg, bool write_only)
pix = &p->fmt.pix;
pr_cont(", width=%u, height=%u, "
"pixelformat=%c%c%c%c, field=%s, "
- "bytesperline=%u sizeimage=%u, colorspace=%d\n",
+ "bytesperline=%u, sizeimage=%u, colorspace=%d\n",
pix->width, pix->height,
(pix->pixelformat & 0xff),
(pix->pixelformat >> 8) & 0xff,
@@ -284,20 +283,14 @@ static void v4l_print_format(const void *arg, bool write_only)
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
win = &p->fmt.win;
- pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, "
- "chromakey=0x%08x, bitmap=%p, "
- "global_alpha=0x%02x\n",
- win->w.width, win->w.height,
- win->w.left, win->w.top,
+ /* Note: we can't print the clip list here since the clips
+ * pointer is a userspace pointer, not a kernelspace
+ * pointer. */
+ pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n",
+ win->w.width, win->w.height, win->w.left, win->w.top,
prt_names(win->field, v4l2_field_names),
- win->chromakey, win->bitmap, win->global_alpha);
- clip = win->clips;
- for (i = 0; i < win->clipcount; i++) {
- printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n",
- i, clip->c.width, clip->c.height,
- clip->c.left, clip->c.top);
- clip = clip->next;
- }
+ win->chromakey, win->clipcount, win->clips,
+ win->bitmap, win->global_alpha);
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
@@ -332,7 +325,7 @@ static void v4l_print_framebuffer(const void *arg, bool write_only)
pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, "
"height=%u, pixelformat=%c%c%c%c, "
- "bytesperline=%u sizeimage=%u, colorspace=%d\n",
+ "bytesperline=%u, sizeimage=%u, colorspace=%d\n",
p->capability, p->flags, p->base,
p->fmt.width, p->fmt.height,
(p->fmt.pixelformat & 0xff),
@@ -353,7 +346,7 @@ static void v4l_print_modulator(const void *arg, bool write_only)
const struct v4l2_modulator *p = arg;
if (write_only)
- pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans);
+ pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans);
else
pr_cont("index=%u, name=%.*s, capability=0x%x, "
"rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
@@ -445,13 +438,13 @@ static void v4l_print_buffer(const void *arg, bool write_only)
for (i = 0; i < p->length; ++i) {
plane = &p->m.planes[i];
printk(KERN_DEBUG
- "plane %d: bytesused=%d, data_offset=0x%08x "
+ "plane %d: bytesused=%d, data_offset=0x%08x, "
"offset/userptr=0x%lx, length=%d\n",
i, plane->bytesused, plane->data_offset,
plane->m.userptr, plane->length);
}
} else {
- pr_cont("bytesused=%d, offset/userptr=0x%lx, length=%d\n",
+ pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n",
p->bytesused, p->m.userptr, p->length);
}
@@ -504,6 +497,8 @@ static void v4l_print_streamparm(const void *arg, bool write_only)
c->capability, c->outputmode,
c->timeperframe.numerator, c->timeperframe.denominator,
c->extendedmode, c->writebuffers);
+ } else {
+ pr_cont("\n");
}
}
@@ -734,11 +729,11 @@ static void v4l_print_frmsizeenum(const void *arg, bool write_only)
p->type);
switch (p->type) {
case V4L2_FRMSIZE_TYPE_DISCRETE:
- pr_cont(" wxh=%ux%u\n",
+ pr_cont(", wxh=%ux%u\n",
p->discrete.width, p->discrete.height);
break;
case V4L2_FRMSIZE_TYPE_STEPWISE:
- pr_cont(" min=%ux%u, max=%ux%u, step=%ux%u\n",
+ pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
p->stepwise.min_width, p->stepwise.min_height,
p->stepwise.step_width, p->stepwise.step_height,
p->stepwise.max_width, p->stepwise.max_height);
@@ -764,12 +759,12 @@ static void v4l_print_frmivalenum(const void *arg, bool write_only)
p->width, p->height, p->type);
switch (p->type) {
case V4L2_FRMIVAL_TYPE_DISCRETE:
- pr_cont(" fps=%d/%d\n",
+ pr_cont(", fps=%d/%d\n",
p->discrete.numerator,
p->discrete.denominator);
break;
case V4L2_FRMIVAL_TYPE_STEPWISE:
- pr_cont(" min=%d/%d, max=%d/%d, step=%d/%d\n",
+ pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n",
p->stepwise.min.numerator,
p->stepwise.min.denominator,
p->stepwise.max.numerator,
@@ -807,8 +802,8 @@ static void v4l_print_event(const void *arg, bool write_only)
pr_cont("value64=%lld, ", c->value64);
else
pr_cont("value=%d, ", c->value);
- pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d,"
- " default_value=%d\n",
+ pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, "
+ "default_value=%d\n",
c->flags, c->minimum, c->maximum,
c->step, c->default_value);
break;
@@ -845,7 +840,7 @@ static void v4l_print_freq_band(const void *arg, bool write_only)
const struct v4l2_frequency_band *p = arg;
pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, "
- "rangelow=%u, rangehigh=%u, modulation=0x%x\n",
+ "rangelow=%u, rangehigh=%u, modulation=0x%x\n",
p->tuner, p->type, p->index,
p->capability, p->rangelow,
p->rangehigh, p->modulation);
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 66f599fcb829..e96497f7c3ed 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -205,7 +205,7 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
{
struct v4l2_m2m_dev *m2m_dev;
- unsigned long flags_job, flags;
+ unsigned long flags_job, flags_out, flags_cap;
m2m_dev = m2m_ctx->m2m_dev;
dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
@@ -223,23 +223,26 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
return;
}
- spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+ spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out);
if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) {
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock,
+ flags_out);
spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
dprintk("No input buffers available\n");
return;
}
- spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
+ spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap);
if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) {
- spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+ spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock,
+ flags_cap);
+ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock,
+ flags_out);
spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
dprintk("No output buffers available\n");
return;
}
- spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
+ spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap);
+ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out);
if (m2m_dev->m2m_ops->job_ready
&& (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
@@ -372,6 +375,20 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
/**
+ * v4l2_m2m_create_bufs() - create a source or destination buffer, depending
+ * on the type
+ */
+int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+ struct v4l2_create_buffers *create)
+{
+ struct vb2_queue *vq;
+
+ vq = v4l2_m2m_get_vq(m2m_ctx, create->format.type);
+ return vb2_create_bufs(vq, create);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_create_bufs);
+
+/**
* v4l2_m2m_expbuf() - export a source or destination buffer, depending on
* the type
*/
@@ -486,8 +503,10 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
if (m2m_ctx->m2m_dev->m2m_ops->unlock)
m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
- poll_wait(file, &src_q->done_wq, wait);
- poll_wait(file, &dst_q->done_wq, wait);
+ if (list_empty(&src_q->done_list))
+ poll_wait(file, &src_q->done_wq, wait);
+ if (list_empty(&dst_q->done_list))
+ poll_wait(file, &dst_q->done_wq, wait);
if (m2m_ctx->m2m_dev->m2m_ops->lock)
m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 7d833eefaf4e..e3bdc3be91e1 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2014,7 +2014,8 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
if (list_empty(&q->queued_list))
return res | POLLERR;
- poll_wait(file, &q->done_wq, wait);
+ if (list_empty(&q->done_list))
+ poll_wait(file, &q->done_wq, wait);
/*
* Take first buffer available for dequeuing.