linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v7] Refactoring Videobuf2 for common use
@ 2015-10-16  6:27 Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 1/7] media: videobuf2: Fix a build warning on fimc-lite.c Junghak Sung
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Hello everybody,

This is the 7th round for refactoring Videobuf2(a.k.a VB2).
The purpose of this patch series is to separate existing VB2 framework
into core part and V4L2 specific part. So that not only V4L2 but also other
frameworks can use them to manage buffer and utilize queue.

Why do we try to make the VB2 framework to be common?

As you may know, current DVB framework uses ringbuffer mechanism to demux
MPEG-2 TS data and pass it to userspace. However, this mechanism requires
extra memory copy because DVB framework provides only read() system call for
application - read() system call copies the kernel data to user-space buffer.
So if we can use VB2 framework which supports streaming I/O and buffer
sharing mechanism, then we could enhance existing DVB framework by removing
the extra memory copy - with VB2 framework, application can access the kernel
data directly through mmap system call.

We have a plan for this work as follows:
1. Separate existing VB2 framework into three parts - VB2 core, VB2 v4l2.
   Of course, this change will not affect other v4l2-based
   device drivers. This patch series corresponds to this step.

2. Add and implement new APIs for DVB streaming I/O.
   We can remove unnecessary memory copy between kernel-space and user-space
   by using these new APIs. However, we leaves legacy interfaces as-is
   for backward compatibility.

This patch series is the first step for it.
The previous version of this patch series can be found at belows.

[1] RFC PATCH v1 - http://www.spinics.net/lists/linux-media/msg90688.html
[2] RFC PATCH v2 - http://www.spinics.net/lists/linux-media/msg92130.html
[3] RFC PATCH v3 - http://www.spinics.net/lists/linux-media/msg92953.html
[4] RFC PATCH v4 - http://www.spinics.net/lists/linux-media/msg93421.html
[5] RFC PATCH v5 - http://www.spinics.net/lists/linux-media/msg93810.html
[6] RFC PATCH v6 - http://www.spinics.net/lists/linux-media/msg94112.html


Changes since v6
1. Based on v6
Patch series v6 was accepted (but, not merged yet). So, this series v7 is
based on v6.

2. Fix a warning on fimc-lite.c
In patch series v6, a warning is reported by kbuild robot. So, this warning
is fixed.

3. Move things related with vb2_thread to core part
In order to move vb2_thread to vb2-core, these changes below would precede it.
 - timestamp of vb2_v4l2_buffer is moved to vb2_buffer for common use.
 - A flag - which is for checking if vb2-core should set timestamps or not - is
  added as a member of vb2_queue.
 - Replace v4l2-stuffs with common things in vb2_fileio_data and vb2_thread.


Changes since v5
1. v5 is merged partially to media_tree
4 of 8 patches - restructuring vb2_buffer for common use - are merged to
media_tree. So, v6 is rebased on later version than that.

2. vb2_format is reverted to void *
vb2_format - which is newly defined for queue_setup() in v5 to deliver
the format information from user-space to device driver - is reverted to
void pointer. This change requires more discussion about the way to do
the format validation and decide the image size.
So, in this version, I would like to revert it to original version.

3. The change related with v4l2_buf_ops is moved
The change related with v4l2_buf_ops seems to be a sort of functional change.
So, it was moved to patch 3/4 - which includes the most of functional changes.


Changes since v4
1. Rebase on 4.3-rc1
Kernel 4.3-rc1 was released. So, this patch set is made based on
that version.

2. Modify queue_setup() argument
In previous patch set, struct v4l2_format, which is a parameter of
queue_setup(), is abstracted by using void pointer. But, it is better way to
pass the parameter with presise meaning than abstracting it.
So, replace void * with struct vb2_format which is newly defined to contain
the format information for common use.

3. Add a code to check if VB2_MAX_* match with VIDEO_MAX_*
Add a check code to videobuf2-v4l2.c where the compiler compares VIDEO_MAX_FRAME
and VB2_MAX_FRAME (and ditto for MAX_PLANES) and throws an #error if they
do not match.

4. Change the commit order
For easier review, the patch that just move things around without doing any
functional change is moved to the last.

All ideas above are from Hans and it seems to be better and right way.


Changes since v3

1. Resolve build errors
In previous patch set, the build errors prevented reviewers from applying
the patch. So, in this patch, I tryed to fix the build errors but I hadn't
the build test on all architectures except for x86 and ARM.

2. Modify descriptions for DocBook
Descriptions not complying with the DocBook rule are modified,
which was pointed out by Mauro.

3. Initialize reserved fields explicitly
The reserved fields of v4l2_buffer are initialized by 0 explicitly
when the vb2_buffer information is returned to userspace,
which was pointed out by Hans.

4. Remove unnecessary type-cast
According to Mauro's advice, the unnecessary type-cast are removed
because it's better for the compiler - rather than human - to check those
things.

5. Sperate the patch - not easy to review - into two patches
In previous patch set, patch 5 was too difficult to review. So accoring to
Hans' opinion, it separated the patch without any functional changes.


Changes since v2

1. Remove v4l2 stuffs completely from vb2_buffer
The v4l2 stuffs - v4l2_buf and v4l2_planes - are removed completely from
struct vb2_buffer. New member variables - index, type, memory - are added
to struct vb2_buffer, all of which can be used commonly. And bytesused,
length, offset, userptr, fd, data_offset are added to struct vb2_plane
for the same reason. So, we can manage video buffer by only using
struct vb2_buffer.
And, v4l2 stuffs - flags, field, timestamp, timecode, sequence - are defined
as member variables of struct vb2_v4l2_buffer.

2. Create new header file for VB2 internal use
videobuf2-internal.h is created, which is referred by videobuf2-core
and videobuf2-v4l2. The header file contains dprintk() for debug,
macro functions to invoke various callbacks, and vb2_core_* function prototypes
referred by inside of videobuf2.

3. Remove buffer-specific callbacks as much as possible
There were many callback functions to handle video buffer information
in previous patch series. In this patch series, I try to remove these callbacks
as much as possible without breaking the existing function flow.
As a result, only four callbacks are remained - fill_user_buffer(),
fill_vb2_buffer(), fill_vb2_timestamp() and is_last().

All ideas above are from Hans and it seems to be better and right way.


Changes since v1

1. Divide patch set into more pieces
v1 was not reviewed normally because the 2/3 patch is failed to send to mailing
list with size problem - over 300kb. So I have divided the patch set into five
pieces and refined them neatly, which was pointed by Hans.

2. Add shell scripts for renaming patch
In case of renaming patch, shell scripts are included inside the body of the
patches by Mauro's advice. 1/5 and 5/5 patches include these scripts, which can
be used by reviewers or maintainers to regenerate big patch file if something
goes wrong during patch apply.

3. Remove dependency on v4l2 from videobuf2
In previous patch set, videobuf2-core uses v4l2-specific stuff as it is.
e.g. enum v4l2_buf_type and enum v4l2_memory. That prevented other frameworks
from using videobuf2 independently and made them forced to include
v4l2-specific stuff.
In this version, these dependent stuffs are replaced with VB2 own stuffs.
e.g. enum vb2_buf_type and enum vb2_memory. So, v4l2-specific header file isn't
required to use videobuf2 in other modules. Please, note that videobuf2 stuffs
will be translated to v4l2-specific stuffs in videobuf2-v4l2.c file for
backward compatibility.

4. Unify duplicated definitions
VB2_DEBUG() is newly defined in videobuf2-core header file in order to unify
duplicated macro functions that invoke callback functions implemented in vb2
backends - i.e., videobuf2-vmalloc and videobuf2-dma-sg - and queue relevant
callbacks of device drivers.
In previous patch set, these macro functions were defined
in both videobuf2-core.c and videobuf2-v4l2.c.


This patch series is based on media_tree.git [7]. I have applied this patches
to my own git [8] for review, and tested this patch series on ubuntu
PC(Intel i7-3770) for x86 system and odroid-xu3(exynos5422) for ARM.

[7] media_tree.git - http://git.linuxtv.org/cgit.cgi/media_tree.git master
[8] jsung/dvb-vb2.git - http://git.linuxtv.org/cgit.cgi/jsung/dvb-vb2.git vb2-refactoring

Any suggestions and comments are welcome.

Regards,
Junghak
Junghak Sung (7):
  media: videobuf2: Fix a build warning on fimc-lite.c
  media: videobuf2: Move timestamp to vb2_buffer
  media: videobuf2: Add set_timestamp to struct vb2_queue
  media: videobuf2: Separate vb2_poll()
  media: videobuf2: last_buffer_queued is checked at fill_v4l2_buffer()
  media: videobuf2: Refactor vb2_fileio_data and vb2_thread
  media: videobuf2: Move vb2_fileio_data and vb2_thread to core part

 drivers/input/touchscreen/sur40.c                  |    2 +-
 drivers/media/dvb-frontends/rtl2832_sdr.c          |    2 +-
 drivers/media/pci/cobalt/cobalt-irq.c              |    2 +-
 drivers/media/pci/cx23885/cx23885-core.c           |    2 +-
 drivers/media/pci/cx23885/cx23885-video.c          |    2 +-
 drivers/media/pci/cx25821/cx25821-video.c          |    2 +-
 drivers/media/pci/cx88/cx88-core.c                 |    2 +-
 drivers/media/pci/dt3155/dt3155.c                  |    2 +-
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |    2 +-
 drivers/media/pci/saa7134/saa7134-core.c           |    2 +-
 drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c     |    4 +-
 drivers/media/pci/solo6x10/solo6x10-v4l2.c         |    2 +-
 drivers/media/pci/sta2x11/sta2x11_vip.c            |    2 +-
 drivers/media/pci/tw68/tw68-video.c                |    2 +-
 drivers/media/platform/am437x/am437x-vpfe.c        |    2 +-
 drivers/media/platform/blackfin/bfin_capture.c     |    2 +-
 drivers/media/platform/coda/coda-bit.c             |    6 +-
 drivers/media/platform/davinci/vpbe_display.c      |    2 +-
 drivers/media/platform/davinci/vpif_capture.c      |    2 +-
 drivers/media/platform/davinci/vpif_display.c      |    4 +-
 drivers/media/platform/exynos-gsc/gsc-m2m.c        |    4 +-
 drivers/media/platform/exynos4-is/fimc-capture.c   |    2 +-
 drivers/media/platform/exynos4-is/fimc-isp-video.c |    2 +-
 drivers/media/platform/exynos4-is/fimc-lite.c      |    4 +-
 drivers/media/platform/exynos4-is/fimc-m2m.c       |    2 +-
 drivers/media/platform/m2m-deinterlace.c           |    2 +-
 drivers/media/platform/marvell-ccic/mcam-core.c    |    2 +-
 drivers/media/platform/mx2_emmaprp.c               |    2 +-
 drivers/media/platform/omap3isp/ispvideo.c         |    2 +-
 drivers/media/platform/rcar_jpu.c                  |    2 +-
 drivers/media/platform/s3c-camif/camif-capture.c   |    2 +-
 drivers/media/platform/s5p-g2d/g2d.c               |    2 +-
 drivers/media/platform/s5p-jpeg/jpeg-core.c        |    4 +-
 drivers/media/platform/s5p-mfc/s5p_mfc.c           |    4 +-
 drivers/media/platform/sh_veu.c                    |    2 +-
 drivers/media/platform/sh_vou.c                    |    2 +-
 drivers/media/platform/soc_camera/atmel-isi.c      |    2 +-
 drivers/media/platform/soc_camera/mx2_camera.c     |    2 +-
 drivers/media/platform/soc_camera/mx3_camera.c     |    2 +-
 drivers/media/platform/soc_camera/rcar_vin.c       |    2 +-
 .../platform/soc_camera/sh_mobile_ceu_camera.c     |    2 +-
 drivers/media/platform/sti/bdisp/bdisp-v4l2.c      |    4 +-
 drivers/media/platform/ti-vpe/vpe.c                |    2 +-
 drivers/media/platform/vim2m.c                     |    2 +-
 drivers/media/platform/vivid/vivid-kthread-cap.c   |    6 +-
 drivers/media/platform/vivid/vivid-kthread-out.c   |    8 +-
 drivers/media/platform/vivid/vivid-sdr-cap.c       |    5 +-
 drivers/media/platform/vivid/vivid-vbi-cap.c       |    8 +-
 drivers/media/platform/vsp1/vsp1_video.c           |    2 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |    2 +-
 drivers/media/usb/airspy/airspy.c                  |    2 +-
 drivers/media/usb/au0828/au0828-video.c            |    2 +-
 drivers/media/usb/em28xx/em28xx-video.c            |    2 +-
 drivers/media/usb/go7007/go7007-driver.c           |    2 +-
 drivers/media/usb/hackrf/hackrf.c                  |    2 +-
 drivers/media/usb/pwc/pwc-if.c                     |    2 +-
 drivers/media/usb/s2255/s2255drv.c                 |    2 +-
 drivers/media/usb/stk1160/stk1160-video.c          |    2 +-
 drivers/media/usb/usbtv/usbtv-video.c              |    2 +-
 drivers/media/usb/uvc/uvc_video.c                  |   12 +-
 drivers/media/v4l2-core/videobuf2-core.c           |  786 +++++++++++++++++++-
 drivers/media/v4l2-core/videobuf2-internal.h       |  161 ----
 drivers/media/v4l2-core/videobuf2-v4l2.c           |  646 +---------------
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |    2 +-
 drivers/staging/media/omap4iss/iss_video.c         |    2 +-
 drivers/usb/gadget/function/uvc_queue.c            |    2 +-
 include/media/videobuf2-core.h                     |   47 ++
 include/media/videobuf2-v4l2.h                     |   40 +-
 include/trace/events/v4l2.h                        |    2 +-
 include/trace/events/vb2.h                         |    7 +-
 70 files changed, 945 insertions(+), 917 deletions(-)
 delete mode 100644 drivers/media/v4l2-core/videobuf2-internal.h

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 1/7] media: videobuf2: Fix a build warning on fimc-lite.c
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer Junghak Sung
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Fix a warning on fimc-lite.c reported by kbuild robot.

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
---
 drivers/media/platform/exynos4-is/fimc-lite.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index d93d03d..60660c3 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -359,7 +359,7 @@ static int queue_setup(struct vb2_queue *vq, const void *parg,
 		       unsigned int *num_buffers, unsigned int *num_planes,
 		       unsigned int sizes[], void *allocators[])
 {
-	struct v4l2_format *pfmt = parg;
+	const struct v4l2_format *pfmt = parg;
 	const struct v4l2_pix_format_mplane *pixm = NULL;
 	struct fimc_lite *fimc = vq->drv_priv;
 	struct flite_frame *frame = &fimc->out_frame;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 1/7] media: videobuf2: Fix a build warning on fimc-lite.c Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-29  2:27   ` Hans Verkuil
  2015-10-16  6:27 ` [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue Junghak Sung
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Move timestamp from struct vb2_v4l2_buffer to struct vb2_buffer
for common use. This patch includes all device drivers' changes
related with this restructuring.

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/input/touchscreen/sur40.c                  |    2 +-
 drivers/media/dvb-frontends/rtl2832_sdr.c          |    2 +-
 drivers/media/pci/cobalt/cobalt-irq.c              |    2 +-
 drivers/media/pci/cx23885/cx23885-core.c           |    2 +-
 drivers/media/pci/cx23885/cx23885-video.c          |    2 +-
 drivers/media/pci/cx25821/cx25821-video.c          |    2 +-
 drivers/media/pci/cx88/cx88-core.c                 |    2 +-
 drivers/media/pci/dt3155/dt3155.c                  |    2 +-
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |    2 +-
 drivers/media/pci/saa7134/saa7134-core.c           |    2 +-
 drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c     |    4 ++--
 drivers/media/pci/solo6x10/solo6x10-v4l2.c         |    2 +-
 drivers/media/pci/sta2x11/sta2x11_vip.c            |    2 +-
 drivers/media/pci/tw68/tw68-video.c                |    2 +-
 drivers/media/platform/am437x/am437x-vpfe.c        |    2 +-
 drivers/media/platform/blackfin/bfin_capture.c     |    2 +-
 drivers/media/platform/coda/coda-bit.c             |    6 +++---
 drivers/media/platform/davinci/vpbe_display.c      |    2 +-
 drivers/media/platform/davinci/vpif_capture.c      |    2 +-
 drivers/media/platform/davinci/vpif_display.c      |    4 ++--
 drivers/media/platform/exynos-gsc/gsc-m2m.c        |    4 ++--
 drivers/media/platform/exynos4-is/fimc-capture.c   |    2 +-
 drivers/media/platform/exynos4-is/fimc-isp-video.c |    2 +-
 drivers/media/platform/exynos4-is/fimc-lite.c      |    2 +-
 drivers/media/platform/exynos4-is/fimc-m2m.c       |    2 +-
 drivers/media/platform/m2m-deinterlace.c           |    2 +-
 drivers/media/platform/marvell-ccic/mcam-core.c    |    2 +-
 drivers/media/platform/mx2_emmaprp.c               |    2 +-
 drivers/media/platform/omap3isp/ispvideo.c         |    2 +-
 drivers/media/platform/rcar_jpu.c                  |    2 +-
 drivers/media/platform/s3c-camif/camif-capture.c   |    2 +-
 drivers/media/platform/s5p-g2d/g2d.c               |    2 +-
 drivers/media/platform/s5p-jpeg/jpeg-core.c        |    4 ++--
 drivers/media/platform/s5p-mfc/s5p_mfc.c           |    4 ++--
 drivers/media/platform/sh_veu.c                    |    2 +-
 drivers/media/platform/sh_vou.c                    |    2 +-
 drivers/media/platform/soc_camera/atmel-isi.c      |    2 +-
 drivers/media/platform/soc_camera/mx2_camera.c     |    2 +-
 drivers/media/platform/soc_camera/mx3_camera.c     |    2 +-
 drivers/media/platform/soc_camera/rcar_vin.c       |    2 +-
 .../platform/soc_camera/sh_mobile_ceu_camera.c     |    2 +-
 drivers/media/platform/sti/bdisp/bdisp-v4l2.c      |    4 ++--
 drivers/media/platform/ti-vpe/vpe.c                |    2 +-
 drivers/media/platform/vim2m.c                     |    2 +-
 drivers/media/platform/vivid/vivid-kthread-cap.c   |    6 +++---
 drivers/media/platform/vivid/vivid-kthread-out.c   |    8 ++++----
 drivers/media/platform/vivid/vivid-sdr-cap.c       |    5 +++--
 drivers/media/platform/vivid/vivid-vbi-cap.c       |    8 ++++----
 drivers/media/platform/vsp1/vsp1_video.c           |    2 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |    2 +-
 drivers/media/usb/airspy/airspy.c                  |    2 +-
 drivers/media/usb/au0828/au0828-video.c            |    2 +-
 drivers/media/usb/em28xx/em28xx-video.c            |    2 +-
 drivers/media/usb/go7007/go7007-driver.c           |    2 +-
 drivers/media/usb/hackrf/hackrf.c                  |    2 +-
 drivers/media/usb/pwc/pwc-if.c                     |    2 +-
 drivers/media/usb/s2255/s2255drv.c                 |    2 +-
 drivers/media/usb/stk1160/stk1160-video.c          |    2 +-
 drivers/media/usb/usbtv/usbtv-video.c              |    2 +-
 drivers/media/usb/uvc/uvc_video.c                  |   12 ++++++------
 drivers/media/v4l2-core/videobuf2-v4l2.c           |    8 ++++----
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |    2 +-
 drivers/staging/media/omap4iss/iss_video.c         |    2 +-
 drivers/usb/gadget/function/uvc_queue.c            |    2 +-
 include/media/videobuf2-core.h                     |    2 ++
 include/media/videobuf2-v4l2.h                     |    2 --
 include/trace/events/v4l2.h                        |    2 +-
 include/trace/events/vb2.h                         |    7 +++++--
 68 files changed, 98 insertions(+), 94 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index d214f22..aee8b4f 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -444,7 +444,7 @@ static void sur40_process_video(struct sur40_state *sur40)
 		goto err_poll;
 
 	/* mark as finished */
-	v4l2_get_timestamp(&new_buf->vb.timestamp);
+	v4l2_get_timestamp(&new_buf->vb.vb2_buf.timestamp);
 	new_buf->vb.sequence = sur40->sequence++;
 	new_buf->vb.field = V4L2_FIELD_NONE;
 	vb2_buffer_done(&new_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index dcd8d94..69dbd1b 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -310,7 +310,7 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
 		len = rtl2832_sdr_convert_stream(dev, ptr, urb->transfer_buffer,
 				urb->actual_length);
 		vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
-		v4l2_get_timestamp(&fbuf->vb.timestamp);
+		v4l2_get_timestamp(&fbuf->vb.vb2_buf.timestamp);
 		fbuf->vb.sequence = dev->sequence++;
 		vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	}
diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c
index 3de26d0..2a5f3f2 100644
--- a/drivers/media/pci/cobalt/cobalt-irq.c
+++ b/drivers/media/pci/cobalt/cobalt-irq.c
@@ -134,7 +134,7 @@ done:
 		skip = true;
 		s->skip_first_frames--;
 	}
-	v4l2_get_timestamp(&cb->vb.timestamp);
+	v4l2_get_timestamp(&cb->vb.vb2_buf.timestamp);
 	/* TODO: the sequence number should be read from the FPGA so we
 	   also know about dropped frames. */
 	cb->vb.sequence = s->sequence++;
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index bc1c960..7474203 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -427,7 +427,7 @@ static void cx23885_wakeup(struct cx23885_tsport *port,
 	buf = list_entry(q->active.next,
 			 struct cx23885_buffer, queue);
 
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 	buf->vb.sequence = q->count++;
 	dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
 		buf->vb.vb2_buf.index,
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 71a80e2..d369b96 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -105,7 +105,7 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
 			struct cx23885_buffer, queue);
 
 	buf->vb.sequence = q->count++;
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 	dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf,
 			buf->vb.vb2_buf.index, count, q->count);
 	list_del(&buf->queue);
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index 26e3e29..6b06c42 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -130,7 +130,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
 			buf = list_entry(dmaq->active.next,
 					 struct cx25821_buffer, queue);
 
-			v4l2_get_timestamp(&buf->vb.timestamp);
+			v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 			buf->vb.sequence = dmaq->count++;
 			list_del(&buf->queue);
 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index 9a43c78..7428532 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -518,7 +518,7 @@ void cx88_wakeup(struct cx88_core *core,
 
 	buf = list_entry(q->active.next,
 			 struct cx88_buffer, list);
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 	buf->vb.field = core->field;
 	buf->vb.sequence = q->count++;
 	list_del(&buf->list);
diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c
index d84abde..148d6f1 100644
--- a/drivers/media/pci/dt3155/dt3155.c
+++ b/drivers/media/pci/dt3155/dt3155.c
@@ -271,7 +271,7 @@ static irqreturn_t dt3155_irq_handler_even(int irq, void *dev_id)
 
 	spin_lock(&ipd->lock);
 	if (ipd->curr_buf && !list_empty(&ipd->dmaq)) {
-		v4l2_get_timestamp(&ipd->curr_buf->timestamp);
+		v4l2_get_timestamp(&ipd->curr_buf->vb2_buf.timestamp);
 		ipd->curr_buf->sequence = ipd->sequence++;
 		ipd->curr_buf->field = V4L2_FIELD_NONE;
 		vb2_buffer_done(&ipd->curr_buf->vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 83c90d3..90d8ddc 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -580,7 +580,7 @@ static void netup_unidvb_dma_worker(struct work_struct *work)
 			dev_dbg(&ndev->pci_dev->dev,
 				"%s(): buffer %p done, size %d\n",
 				__func__, buf, buf->size);
-			v4l2_get_timestamp(&buf->vb.timestamp);
+			v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 			vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 		}
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index 87f39f9..ee66137 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -309,7 +309,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev,
 	core_dbg("buffer_finish %p\n", q->curr);
 
 	/* finish current buffer */
-	v4l2_get_timestamp(&q->curr->vb2.timestamp);
+	v4l2_get_timestamp(&q->curr->vb2.vb2_buf.timestamp);
 	q->curr->vb2.sequence = q->seq_nr++;
 	vb2_buffer_done(&q->curr->vb2.vb2_buf, state);
 	q->curr = NULL;
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 1bd2fd4..0671571 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -531,8 +531,8 @@ static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
 
 	if (!ret) {
 		vbuf->sequence = solo_enc->sequence++;
-		vbuf->timestamp.tv_sec = vop_sec(vh);
-		vbuf->timestamp.tv_usec = vop_usec(vh);
+		vb->timestamp.tv_sec = vop_sec(vh);
+		vb->timestamp.tv_usec = vop_usec(vh);
 
 		/* Check for motion flags */
 		if (solo_is_motion_on(solo_enc) && enc_buf->motion) {
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
index 26df903..aabef3e 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
@@ -225,7 +225,7 @@ finish_buf:
 		vb2_set_plane_payload(vb, 0,
 			solo_vlines(solo_dev) * solo_bytesperline(solo_dev));
 		vbuf->sequence = solo_dev->sequence++;
-		v4l2_get_timestamp(&vbuf->timestamp);
+		v4l2_get_timestamp(&vb->timestamp);
 	}
 
 	vb2_buffer_done(vb, error ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 6367b45..23b1ef9 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -817,7 +817,7 @@ static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
 		/* Disable acquisition */
 		reg_write(vip, DVP_CTL, reg_read(vip, DVP_CTL) & ~DVP_CTL_ENA);
 		/* Remove the active buffer from the list */
-		v4l2_get_timestamp(&vip->active->vb.timestamp);
+		v4l2_get_timestamp(&vip->active->vb.vb2_buf.timestamp);
 		vip->active->vb.sequence = vip->sequence++;
 		vb2_buffer_done(&vip->active->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	}
diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
index 4c3293d..4d240ae 100644
--- a/drivers/media/pci/tw68/tw68-video.c
+++ b/drivers/media/pci/tw68/tw68-video.c
@@ -1016,7 +1016,7 @@ void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
 		buf = list_entry(dev->active.next, struct tw68_buf, list);
 		list_del(&buf->list);
 		spin_unlock(&dev->slock);
-		v4l2_get_timestamp(&buf->vb.timestamp);
+		v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 		buf->vb.field = dev->field;
 		buf->vb.sequence = dev->seqnr++;
 		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index f0480d6..fb5bf99 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -1281,7 +1281,7 @@ static inline void vpfe_schedule_bottom_field(struct vpfe_device *vpfe)
  */
 static inline void vpfe_process_buffer_complete(struct vpfe_device *vpfe)
 {
-	v4l2_get_timestamp(&vpfe->cur_frm->vb.timestamp);
+	v4l2_get_timestamp(&vpfe->cur_frm->vb.vb2_buf.timestamp);
 	vpfe->cur_frm->vb.field = vpfe->fmt.fmt.pix.field;
 	vpfe->cur_frm->vb.sequence = vpfe->sequence++;
 	vb2_buffer_done(&vpfe->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 7764b9c..2c30454 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -406,7 +406,7 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
 	spin_lock(&bcap_dev->lock);
 
 	if (!list_empty(&bcap_dev->dma_queue)) {
-		v4l2_get_timestamp(&vbuf->timestamp);
+		v4l2_get_timestamp(&vb->timestamp);
 		if (ppi->err) {
 			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 			ppi->err = false;
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 654e964..21beb97 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -279,7 +279,7 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
 			if (meta) {
 				meta->sequence = src_buf->sequence;
 				meta->timecode = src_buf->timecode;
-				meta->timestamp = src_buf->timestamp;
+				meta->timestamp = src_buf->vb2_buf.timestamp;
 				meta->start = start;
 				meta->end = ctx->bitstream_fifo.kfifo.in &
 					    ctx->bitstream_fifo.kfifo.mask;
@@ -1364,7 +1364,7 @@ static void coda_finish_encode(struct coda_ctx *ctx)
 		dst_buf->flags &= ~V4L2_BUF_FLAG_KEYFRAME;
 	}
 
-	dst_buf->timestamp = src_buf->timestamp;
+	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
 	dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst_buf->flags |=
 		src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
@@ -2040,7 +2040,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
 		dst_buf->flags |= ctx->frame_types[ctx->display_idx];
 		meta = &ctx->frame_metas[ctx->display_idx];
 		dst_buf->timecode = meta->timecode;
-		dst_buf->timestamp = meta->timestamp;
+		dst_buf->vb2_buf.timestamp = meta->timestamp;
 
 		trace_coda_dec_rot_done(ctx, dst_buf, meta);
 
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 6d91422..4d7f05c 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -74,7 +74,7 @@ static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
 	if (layer->cur_frm == layer->next_frm)
 		return;
 
-	v4l2_get_timestamp(&layer->cur_frm->vb.timestamp);
+	v4l2_get_timestamp(&layer->cur_frm->vb.vb2_buf.timestamp);
 	vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	/* Make cur_frm pointing to next_frm */
 	layer->cur_frm = layer->next_frm;
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index c1e573b..d308be8 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -331,7 +331,7 @@ static struct vb2_ops video_qops = {
  */
 static void vpif_process_buffer_complete(struct common_obj *common)
 {
-	v4l2_get_timestamp(&common->cur_frm->vb.timestamp);
+	v4l2_get_timestamp(&common->cur_frm->vb.vb2_buf.timestamp);
 	vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	/* Make curFrm pointing to nextFrm */
 	common->cur_frm = common->next_frm;
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index fd27803..dd45efe 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -330,7 +330,7 @@ static void process_interlaced_mode(int fid, struct common_obj *common)
 		/* one frame is displayed If next frame is
 		 *  available, release cur_frm and move on */
 		/* Copy frame display time */
-		v4l2_get_timestamp(&common->cur_frm->vb.timestamp);
+		v4l2_get_timestamp(&common->cur_frm->vb.vb2_buf.timestamp);
 		/* Change status of the cur_frm */
 		vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
 					VB2_BUF_STATE_DONE);
@@ -387,7 +387,7 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 				/* Mark status of the cur_frm to
 				 * done and unlock semaphore on it */
 				v4l2_get_timestamp(
-					&common->cur_frm->vb.timestamp);
+					&common->cur_frm->vb.vb2_buf.timestamp);
 				vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
 						VB2_BUF_STATE_DONE);
 				/* Make cur_frm pointing to next_frm */
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
index d82e717..70bf10f 100644
--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -86,7 +86,7 @@ void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
 	dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
 	if (src_vb && dst_vb) {
-		dst_vb->timestamp = src_vb->timestamp;
+		dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 		dst_vb->timecode = src_vb->timecode;
 		dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 		dst_vb->flags |=
@@ -125,7 +125,7 @@ static int gsc_get_bufs(struct gsc_ctx *ctx)
 	if (ret)
 		return ret;
 
-	dst_vb->timestamp = src_vb->timestamp;
+	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 
 	return 0;
 }
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 99e5732..5fb3013 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -193,7 +193,7 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
 	    test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
 		v_buf = fimc_active_queue_pop(cap);
 
-		v4l2_get_timestamp(&v_buf->vb.timestamp);
+		v4l2_get_timestamp(&v_buf->vb.vb2_buf.timestamp);
 		v_buf->vb.sequence = cap->frame_count++;
 
 		vb2_buffer_done(&v_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 6e66484..a582d19 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -254,7 +254,7 @@ void fimc_isp_video_irq_handler(struct fimc_is *is)
 	buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count;
 	vbuf = &video->buffers[buf_index]->vb;
 
-	v4l2_get_timestamp(&vbuf->timestamp);
+	v4l2_get_timestamp(&vbuf->vb2_buf.timestamp);
 	vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 
 	video->buf_mask &= ~BIT(buf_index);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 60660c3..c53e4c3 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -292,7 +292,7 @@ static irqreturn_t flite_irq_handler(int irq, void *priv)
 	    test_bit(ST_FLITE_RUN, &fimc->state) &&
 	    !list_empty(&fimc->active_buf_q)) {
 		vbuf = fimc_lite_active_queue_pop(fimc);
-		v4l2_get_timestamp(&vbuf->vb.timestamp);
+		v4l2_get_timestamp(&vbuf->vb.vb2_buf.timestamp);
 		vbuf->vb.sequence = fimc->frame_count++;
 		flite_hw_mask_dma_buffer(fimc, vbuf->index);
 		vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 4d1d64a4..0d72b50 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -132,7 +132,7 @@ static void fimc_device_run(void *priv)
 	if (ret)
 		goto dma_unlock;
 
-	dst_vb->timestamp = src_vb->timestamp;
+	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 	dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst_vb->flags |=
 		src_vb->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 29973f9..e27fb82 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -207,7 +207,7 @@ static void dma_callback(void *data)
 	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
 	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
 
-	dst_vb->timestamp = src_vb->timestamp;
+	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 	dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst_vb->flags |=
 		src_vb->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index aa2b440..7cf7427 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -226,7 +226,7 @@ static void mcam_buffer_done(struct mcam_camera *cam, int frame,
 	vbuf->vb2_buf.planes[0].bytesused = cam->pix_format.sizeimage;
 	vbuf->sequence = cam->buf_seq[frame];
 	vbuf->field = V4L2_FIELD_NONE;
-	v4l2_get_timestamp(&vbuf->timestamp);
+	v4l2_get_timestamp(&vbuf->vb2_buf.timestamp);
 	vb2_set_plane_payload(&vbuf->vb2_buf, 0, cam->pix_format.sizeimage);
 	vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 }
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index 03a1b60..e0e36ea 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -375,7 +375,7 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data)
 			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
 			dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
 
-			dst_vb->timestamp = src_vb->timestamp;
+			dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 			dst_vb->flags &=
 				~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 			dst_vb->flags |=
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index f4f5916..9bc929b 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -467,7 +467,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
 	list_del(&buf->irqlist);
 	spin_unlock_irqrestore(&video->irqlock, flags);
 
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 
 	/* Do frame number propagation only if this is the output video node.
 	 * Frame number either comes from the CSI receivers or it gets
diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c
index f8e3e83..6e0871b 100644
--- a/drivers/media/platform/rcar_jpu.c
+++ b/drivers/media/platform/rcar_jpu.c
@@ -1560,7 +1560,7 @@ static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
 		}
 
 		dst_buf->field = src_buf->field;
-		dst_buf->timestamp = src_buf->timestamp;
+		dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
 		if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
 			dst_buf->timecode = src_buf->timecode;
 		dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 537b858..3ca6f0a 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -338,7 +338,7 @@ irqreturn_t s3c_camif_irq_handler(int irq, void *priv)
 
 		if (!WARN_ON(vbuf == NULL)) {
 			/* Dequeue a filled buffer */
-			v4l2_get_timestamp(&vbuf->vb.timestamp);
+			v4l2_get_timestamp(&vbuf->vb.vb2_buf.timestamp);
 			vbuf->vb.sequence = vp->frame_sequence++;
 			vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index e1936d9..658e091 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -552,7 +552,7 @@ static irqreturn_t g2d_isr(int irq, void *prv)
 	BUG_ON(dst == NULL);
 
 	dst->timecode = src->timecode;
-	dst->timestamp = src->timestamp;
+	dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
 	dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst->flags |=
 		src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 4a608cb..e9b0e32 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2621,7 +2621,7 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
 	}
 
 	dst_buf->timecode = src_buf->timecode;
-	dst_buf->timestamp = src_buf->timestamp;
+	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
 	dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst_buf->flags |=
 		src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
@@ -2752,7 +2752,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
 	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
 
 	dst_buf->timecode = src_buf->timecode;
-	dst_buf->timestamp = src_buf->timestamp;
+	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
 
 	v4l2_m2m_buf_done(src_buf, state);
 	if (curr_ctx->mode == S5P_JPEG_ENCODE)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 7b646c2..604026f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -239,8 +239,8 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
 				== dec_y_addr) {
 			dst_buf->b->timecode =
 						src_buf->b->timecode;
-			dst_buf->b->timestamp =
-						src_buf->b->timestamp;
+			dst_buf->b->vb2_buf.timestamp =
+						src_buf->b->vb2_buf.timestamp;
 			dst_buf->b->flags &=
 				~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 			dst_buf->b->flags |=
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index d6ab33e..720e40c 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -1107,7 +1107,7 @@ static irqreturn_t sh_veu_isr(int irq, void *dev_id)
 	if (!src || !dst)
 		return IRQ_NONE;
 
-	dst->timestamp = src->timestamp;
+	dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
 	dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst->flags |=
 		src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 2231f89..7b02743 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1071,7 +1071,7 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
 
 	list_del(&vb->list);
 
-	v4l2_get_timestamp(&vb->vb.timestamp);
+	v4l2_get_timestamp(&vb->vb.vb2_buf.timestamp);
 	vb->vb.sequence = vou_dev->sequence++;
 	vb->vb.field = V4L2_FIELD_INTERLACED;
 	vb2_buffer_done(&vb->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 454f68f..7d0f9f9 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -165,7 +165,7 @@ static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
 		struct frame_buffer *buf = isi->active;
 
 		list_del_init(&buf->list);
-		v4l2_get_timestamp(&vbuf->timestamp);
+		v4l2_get_timestamp(&vbuf->vb2_buf.timestamp);
 		vbuf->sequence = isi->sequence++;
 		vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 	}
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 1f28d21..61f01d7 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -1351,7 +1351,7 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
 				vb2_get_plane_payload(vb, 0));
 
 		list_del_init(&buf->internal.queue);
-		v4l2_get_timestamp(&vbuf->timestamp);
+		v4l2_get_timestamp(&vb->timestamp);
 		vbuf->sequence = pcdev->frame_count;
 		if (err)
 			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 49c3a25..92730ab 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -155,7 +155,7 @@ static void mx3_cam_dma_done(void *arg)
 		struct mx3_camera_buffer *buf = to_mx3_vb(vb);
 
 		list_del_init(&buf->queue);
-		v4l2_get_timestamp(&vb->timestamp);
+		v4l2_get_timestamp(&vb->vb2_buf.timestamp);
 		vb->field = mx3_cam->field;
 		vb->sequence = mx3_cam->sequence++;
 		vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index efe57b2..d3fa722 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -912,7 +912,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
 
 		priv->queue_buf[slot]->field = priv->field;
 		priv->queue_buf[slot]->sequence = priv->sequence++;
-		v4l2_get_timestamp(&priv->queue_buf[slot]->timestamp);
+		v4l2_get_timestamp(&priv->queue_buf[slot]->vb2_buf.timestamp);
 		vb2_buffer_done(&priv->queue_buf[slot]->vb2_buf,
 				VB2_BUF_STATE_DONE);
 		priv->queue_buf[slot] = NULL;
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 67a669d..ea04066 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -533,7 +533,7 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
 		pcdev->active = NULL;
 
 	ret = sh_mobile_ceu_capture(pcdev);
-	v4l2_get_timestamp(&vbuf->timestamp);
+	v4l2_get_timestamp(&vbuf->vb2_buf.timestamp);
 	if (!ret) {
 		vbuf->field = pcdev->field;
 		vbuf->sequence = pcdev->sequence++;
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index a0d267e..ad122cc 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -191,7 +191,7 @@ static void bdisp_job_finish(struct bdisp_ctx *ctx, int vb_state)
 	dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
 	if (src_vb && dst_vb) {
-		dst_vb->timestamp = src_vb->timestamp;
+		dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 		dst_vb->timecode = src_vb->timecode;
 		dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 		dst_vb->flags |= src_vb->flags &
@@ -297,7 +297,7 @@ static int bdisp_get_bufs(struct bdisp_ctx *ctx)
 	if (ret)
 		return ret;
 
-	dst_vb->timestamp = src_vb->timestamp;
+	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 
 	return 0;
 }
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index de24eff..83acb83 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1288,7 +1288,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
 	d_vb = ctx->dst_vb;
 
 	d_vb->flags = s_vb->flags;
-	d_vb->timestamp = s_vb->timestamp;
+	d_vb->vb2_buf.timestamp = s_vb->vb2_buf.timestamp;
 
 	if (s_vb->flags & V4L2_BUF_FLAG_TIMECODE)
 		d_vb->timecode = s_vb->timecode;
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index e18fb9f..06a0e04 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -235,7 +235,7 @@ static int device_process(struct vim2m_ctx *ctx,
 	out_vb->sequence =
 		get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
 	in_vb->sequence = q_data->sequence++;
-	out_vb->timestamp = in_vb->timestamp;
+	out_vb->vb2_buf.timestamp = in_vb->vb2_buf.timestamp;
 
 	if (in_vb->flags & V4L2_BUF_FLAG_TIMECODE)
 		out_vb->timecode = in_vb->timecode;
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 83cc6d3..04ce0d4 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -441,7 +441,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
 	 * "Start of Exposure".
 	 */
 	if (dev->tstamp_src_is_soe)
-		v4l2_get_timestamp(&buf->vb.timestamp);
+		v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 	if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
 		/*
 		 * 60 Hz standards start with the bottom field, 50 Hz standards
@@ -558,8 +558,8 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
 	 * the timestamp now.
 	 */
 	if (!dev->tstamp_src_is_soe)
-		v4l2_get_timestamp(&buf->vb.timestamp);
-	buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+		v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
+	buf->vb.vb2_buf.timestamp.tv_sec += dev->time_wrap_offset;
 }
 
 /*
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
index c2c46dc..c044d84 100644
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
@@ -95,8 +95,8 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
 			 */
 			vid_out_buf->vb.sequence /= 2;
 		}
-		v4l2_get_timestamp(&vid_out_buf->vb.timestamp);
-		vid_out_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+		v4l2_get_timestamp(&vid_out_buf->vb.vb2_buf.timestamp);
+		vid_out_buf->vb.vb2_buf.timestamp.tv_sec += dev->time_wrap_offset;
 		vb2_buffer_done(&vid_out_buf->vb.vb2_buf, dev->dqbuf_error ?
 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 		dprintk(dev, 2, "vid_out buffer %d done\n",
@@ -108,8 +108,8 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
 			vivid_sliced_vbi_out_process(dev, vbi_out_buf);
 
 		vbi_out_buf->vb.sequence = dev->vbi_out_seq_count;
-		v4l2_get_timestamp(&vbi_out_buf->vb.timestamp);
-		vbi_out_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+		v4l2_get_timestamp(&vbi_out_buf->vb.vb2_buf.timestamp);
+		vbi_out_buf->vb.vb2_buf.timestamp.tv_sec += dev->time_wrap_offset;
 		vb2_buffer_done(&vbi_out_buf->vb.vb2_buf, dev->dqbuf_error ?
 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 		dprintk(dev, 2, "vbi_out buffer %d done\n",
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
index 082c401..6d8fe85 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -117,8 +117,9 @@ static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
 	if (sdr_cap_buf) {
 		sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
 		vivid_sdr_cap_process(dev, sdr_cap_buf);
-		v4l2_get_timestamp(&sdr_cap_buf->vb.timestamp);
-		sdr_cap_buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+		v4l2_get_timestamp(&sdr_cap_buf->vb.vb2_buf.timestamp);
+		sdr_cap_buf->vb.vb2_buf.timestamp.tv_sec +=
+					dev->time_wrap_offset;
 		vb2_buffer_done(&sdr_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 		dev->dqbuf_error = false;
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c b/drivers/media/platform/vivid/vivid-vbi-cap.c
index e903d02..3177eb7 100644
--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
+++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
@@ -108,8 +108,8 @@ void vivid_raw_vbi_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
 	if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode))
 		vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
 
-	v4l2_get_timestamp(&buf->vb.timestamp);
-	buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
+	buf->vb.vb2_buf.timestamp.tv_sec += dev->time_wrap_offset;
 }
 
 
@@ -133,8 +133,8 @@ void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
 			vbuf[i] = dev->vbi_gen.data[i];
 	}
 
-	v4l2_get_timestamp(&buf->vb.timestamp);
-	buf->vb.timestamp.tv_sec += dev->time_wrap_offset;
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
+	buf->vb.vb2_buf.timestamp.tv_sec += dev->time_wrap_offset;
 }
 
 static int vbi_cap_queue_setup(struct vb2_queue *vq, const void *parg,
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 5ce88e1..9d287d5 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -611,7 +611,7 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 	spin_unlock_irqrestore(&video->irqlock, flags);
 
 	done->buf.sequence = video->sequence++;
-	v4l2_get_timestamp(&done->buf.timestamp);
+	v4l2_get_timestamp(&done->buf.vb2_buf.timestamp);
 	for (i = 0; i < done->buf.vb2_buf.num_planes; ++i)
 		vb2_set_plane_payload(&done->buf.vb2_buf, i, done->length[i]);
 	vb2_buffer_done(&done->buf.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index d11cc70..27cfcdb 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -303,7 +303,7 @@ static void xvip_dma_complete(void *param)
 
 	buf->buf.field = V4L2_FIELD_NONE;
 	buf->buf.sequence = dma->sequence++;
-	v4l2_get_timestamp(&buf->buf.timestamp);
+	v4l2_get_timestamp(&buf->buf.vb2_buf.timestamp);
 	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, dma->format.sizeimage);
 	vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
 }
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index fcbb497..7c38901 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -316,7 +316,7 @@ static void airspy_urb_complete(struct urb *urb)
 		len = airspy_convert_stream(s, ptr, urb->transfer_buffer,
 				urb->actual_length);
 		vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
-		v4l2_get_timestamp(&fbuf->vb.timestamp);
+		v4l2_get_timestamp(&fbuf->vb.vb2_buf.timestamp);
 		fbuf->vb.sequence = s->sequence++;
 		vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	}
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 45c622e..1020042 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -314,7 +314,7 @@ static inline void buffer_filled(struct au0828_dev *dev,
 		vb->sequence = dev->vbi_frame_count++;
 
 	vb->field = V4L2_FIELD_INTERLACED;
-	v4l2_get_timestamp(&vb->timestamp);
+	v4l2_get_timestamp(&vb->vb2_buf.timestamp);
 	vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
 }
 
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 6a3cf34..a9f0f5f 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -438,7 +438,7 @@ static inline void finish_buffer(struct em28xx *dev,
 		buf->vb.field = V4L2_FIELD_NONE;
 	else
 		buf->vb.field = V4L2_FIELD_INTERLACED;
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 
 	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 }
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index ae1cfa7..b269988 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -466,7 +466,7 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf
 	else
 		go7007_set_motion_regions(go, vb, 0);
 
-	v4l2_get_timestamp(&vb->vb.timestamp);
+	v4l2_get_timestamp(&vb->vb.vb2_buf.timestamp);
 	vb_tmp = vb;
 	spin_lock(&go->spinlock);
 	list_del(&vb->list);
diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c
index 1d93db3..086db6f 100644
--- a/drivers/media/usb/hackrf/hackrf.c
+++ b/drivers/media/usb/hackrf/hackrf.c
@@ -293,7 +293,7 @@ static void hackrf_urb_complete(struct urb *urb)
 		len = hackrf_convert_stream(dev, ptr, urb->transfer_buffer,
 				urb->actual_length);
 		vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
-		v4l2_get_timestamp(&fbuf->vb.timestamp);
+		v4l2_get_timestamp(&fbuf->vb.vb2_buf.timestamp);
 		fbuf->vb.sequence = dev->sequence++;
 		vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	}
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index b79c36f..d2f23f1 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -317,7 +317,7 @@ static void pwc_isoc_handler(struct urb *urb)
 
 			if (pdev->vsync == 1) {
 				v4l2_get_timestamp(
-					&fbuf->vb.timestamp);
+					&fbuf->vb.vb2_buf.timestamp);
 				pdev->vsync = 2;
 			}
 
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index e7acb12..c988049 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -574,7 +574,7 @@ static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
 	buf = list_entry(vc->buf_list.next,
 			 struct s2255_buffer, list);
 	list_del(&buf->list);
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 	buf->vb.field = vc->field;
 	buf->vb.sequence = vc->frame_count;
 	spin_unlock_irqrestore(&vc->qlock, flags);
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index 75654e6..5735607 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -99,7 +99,7 @@ void stk1160_buffer_done(struct stk1160 *dev)
 	buf->vb.sequence = dev->sequence++;
 	buf->vb.field = V4L2_FIELD_INTERLACED;
 	buf->vb.vb2_buf.planes[0].bytesused = buf->bytesused;
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 
 	vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->bytesused);
 	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index e645c9d..adcd5ad 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -322,7 +322,7 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)
 
 		buf->vb.field = V4L2_FIELD_INTERLACED;
 		buf->vb.sequence = usbtv->sequence++;
-		v4l2_get_timestamp(&buf->vb.timestamp);
+		v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
 		vb2_buffer_done(&buf->vb.vb2_buf, state);
 		list_del(&buf->list);
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 2b276ab..0135659 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -699,14 +699,14 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
 		  stream->dev->name,
 		  sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
 		  y, ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC,
-		  vbuf->timestamp.tv_sec,
-		  (unsigned long)vbuf->timestamp.tv_usec,
+		  vbuf->vb2_buf.timestamp.tv_sec,
+		  (unsigned long)vbuf->vb2_buf.timestamp.tv_usec,
 		  x1, first->host_sof, first->dev_sof,
 		  x2, last->host_sof, last->dev_sof, y1, y2);
 
 	/* Update the V4L2 buffer. */
-	vbuf->timestamp.tv_sec = ts.tv_sec;
-	vbuf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+	vbuf->vb2_buf.timestamp.tv_sec = ts.tv_sec;
+	vbuf->vb2_buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 
 done:
 	spin_unlock_irqrestore(&stream->clock.lock, flags);
@@ -1034,8 +1034,8 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
 
 		buf->buf.field = V4L2_FIELD_NONE;
 		buf->buf.sequence = stream->sequence;
-		buf->buf.timestamp.tv_sec = ts.tv_sec;
-		buf->buf.timestamp.tv_usec =
+		buf->buf.vb2_buf.timestamp.tv_sec = ts.tv_sec;
+		buf->buf.vb2_buf.timestamp.tv_usec =
 			ts.tv_nsec / NSEC_PER_USEC;
 
 		/* TODO: Handle PTS and SCR. */
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 27b4b9e..b1334d6 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -120,7 +120,7 @@ static int __set_timestamp(struct vb2_buffer *vb, const void *pb)
 		 */
 		if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
 				V4L2_BUF_FLAG_TIMESTAMP_COPY)
-			vbuf->timestamp = b->timestamp;
+			vb->timestamp = b->timestamp;
 		vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
 		if (b->flags & V4L2_BUF_FLAG_TIMECODE)
 			vbuf->timecode = b->timecode;
@@ -191,7 +191,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 
 	b->flags = vbuf->flags;
 	b->field = vbuf->field;
-	b->timestamp = vbuf->timestamp;
+	b->timestamp = vb->timestamp;
 	b->timecode = vbuf->timecode;
 	b->sequence = vbuf->sequence;
 	b->reserved2 = 0;
@@ -308,8 +308,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
 					"for an output buffer\n");
 		return -EINVAL;
 	}
-	vbuf->timestamp.tv_sec = 0;
-	vbuf->timestamp.tv_usec = 0;
+	vb->timestamp.tv_sec = 0;
+	vb->timestamp.tv_usec = 0;
 	vbuf->sequence = 0;
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 0fdff91..a9e37e8 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -470,7 +470,7 @@ void vpfe_video_process_buffer_complete(struct vpfe_video_device *video)
 {
 	struct vpfe_pipeline *pipe = &video->pipe;
 
-	v4l2_get_timestamp(&video->cur_frm->vb.timestamp);
+	v4l2_get_timestamp(&video->cur_frm->vb.vb2_buf.timestamp);
 	vb2_buffer_done(&video->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
 	if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
 		video->cur_frm = video->next_frm;
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 28c067d..8d94202 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -435,7 +435,7 @@ struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video)
 	list_del(&buf->list);
 	spin_unlock_irqrestore(&video->qlock, flags);
 
-	v4l2_get_timestamp(&buf->vb.timestamp);
+	v4l2_get_timestamp(&buf->vb.vb2_buf.timestamp);
 
 	/* Do frame number propagation only if this is the output video node.
 	 * Frame number either comes from the CSI receivers or it gets
diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
index 51d4a17..ee3b169 100644
--- a/drivers/usb/gadget/function/uvc_queue.c
+++ b/drivers/usb/gadget/function/uvc_queue.c
@@ -329,7 +329,7 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
 
 	buf->buf.field = V4L2_FIELD_NONE;
 	buf->buf.sequence = queue->sequence++;
-	v4l2_get_timestamp(&buf->buf.timestamp);
+	v4l2_get_timestamp(&buf->buf.vb2_buf.timestamp);
 
 	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
 	vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 647ebfe..f1e7169 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -211,6 +211,7 @@ struct vb2_queue;
  * @num_planes:		number of planes in the buffer
  *			on an internal driver queue
  * @planes:		private per-plane information; do not change
+ * @timestamp:		frame timestamp
  */
 struct vb2_buffer {
 	struct vb2_queue	*vb2_queue;
@@ -219,6 +220,7 @@ struct vb2_buffer {
 	unsigned int		memory;
 	unsigned int		num_planes;
 	struct vb2_plane	planes[VB2_MAX_PLANES];
+	struct timeval		timestamp;
 
 	/* private: internal use only
 	 *
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 5abab1e..110062e 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -28,7 +28,6 @@
  * @vb2_buf:	video buffer 2
  * @flags:	buffer informational flags
  * @field:	enum v4l2_field; field order of the image in the buffer
- * @timestamp:	frame timestamp
  * @timecode:	frame timecode
  * @sequence:	sequence count of this frame
  * Should contain enough information to be able to cover all the fields
@@ -39,7 +38,6 @@ struct vb2_v4l2_buffer {
 
 	__u32			flags;
 	__u32			field;
-	struct timeval		timestamp;
 	struct v4l2_timecode	timecode;
 	__u32			sequence;
 };
diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
index 04ef89b..5b57d0a 100644
--- a/include/trace/events/v4l2.h
+++ b/include/trace/events/v4l2.h
@@ -204,7 +204,7 @@ DECLARE_EVENT_CLASS(vb2_v4l2_event_class,
 		__entry->minor = owner ? owner->vdev->minor : -1;
 		__entry->flags = vbuf->flags;
 		__entry->field = vbuf->field;
-		__entry->timestamp = timeval_to_ns(&vbuf->timestamp);
+		__entry->timestamp = timeval_to_ns(&vb->timestamp);
 		__entry->timecode_type = vbuf->timecode.type;
 		__entry->timecode_flags = vbuf->timecode.flags;
 		__entry->timecode_frames = vbuf->timecode.frames;
diff --git a/include/trace/events/vb2.h b/include/trace/events/vb2.h
index bfeceeb..35c1589 100644
--- a/include/trace/events/vb2.h
+++ b/include/trace/events/vb2.h
@@ -18,6 +18,7 @@ DECLARE_EVENT_CLASS(vb2_event_class,
 		__field(u32, index)
 		__field(u32, type)
 		__field(u32, bytesused)
+		__field(s64, timestamp)
 	),
 
 	TP_fast_assign(
@@ -28,14 +29,16 @@ DECLARE_EVENT_CLASS(vb2_event_class,
 		__entry->index = vb->index;
 		__entry->type = vb->type;
 		__entry->bytesused = vb->planes[0].bytesused;
+		__entry->timestamp = timeval_to_ns(&vb->timestamp);
 	),
 
 	TP_printk("owner = %p, queued = %u, owned_by_drv = %d, index = %u, "
-		  "type = %u, bytesused = %u", __entry->owner,
+		  "type = %u, bytesused = %u, timestamp = %llu", __entry->owner,
 		  __entry->queued_count,
 		  __entry->owned_by_drv_count,
 		  __entry->index, __entry->type,
-		  __entry->bytesused
+		  __entry->bytesused,
+		  __entry->timestamp
 	)
 )
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 1/7] media: videobuf2: Fix a build warning on fimc-lite.c Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-16 12:04   ` Sakari Ailus
  2015-10-16  6:27 ` [RFC PATCH v7 4/7] media: videobuf2: Separate vb2_poll() Junghak Sung
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Add set_timestamp to struct vb2_queue as a flag set if vb2-core should
set timestamps.

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c |   19 +++++++------------
 include/media/videobuf2-core.h           |    2 ++
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index b1334d6..525f4c7 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -118,8 +118,7 @@ static int __set_timestamp(struct vb2_buffer *vb, const void *pb)
 		 * For output buffers copy the timestamp if needed,
 		 * and the timecode field and flag if needed.
 		 */
-		if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
-				V4L2_BUF_FLAG_TIMESTAMP_COPY)
+		if (q->set_timestamp)
 			vb->timestamp = b->timestamp;
 		vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
 		if (b->flags & V4L2_BUF_FLAG_TIMECODE)
@@ -238,8 +237,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 	 */
 	b->flags &= ~V4L2_BUFFER_MASK_FLAGS;
 	b->flags |= q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK;
-	if ((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
-	    V4L2_BUF_FLAG_TIMESTAMP_COPY) {
+	if (!q->set_timestamp) {
 		/*
 		 * For non-COPY timestamps, drop timestamp source bits
 		 * and obtain the timestamp source from the queue.
@@ -404,8 +402,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
 
 	/* Zero flags that the vb2 core handles */
 	vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
-	if ((vb->vb2_queue->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) !=
-	    V4L2_BUF_FLAG_TIMESTAMP_COPY || !V4L2_TYPE_IS_OUTPUT(b->type)) {
+	if (!vb->vb2_queue->set_timestamp || !V4L2_TYPE_IS_OUTPUT(b->type)) {
 		/*
 		 * Non-COPY timestamps and non-OUTPUT queues will get
 		 * their timestamp and timestamp source flags from the
@@ -723,6 +720,8 @@ int vb2_queue_init(struct vb2_queue *q)
 	q->buf_ops = &v4l2_buf_ops;
 	q->is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type);
 	q->is_output = V4L2_TYPE_IS_OUTPUT(q->type);
+	q->set_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK)
+			== V4L2_BUF_FLAG_TIMESTAMP_COPY;
 
 	return vb2_core_queue_init(q);
 }
@@ -1080,9 +1079,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
 	 * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody
 	 * else is able to provide this information with the write() operation.
 	 */
-	bool set_timestamp = !read &&
-		(q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
-		V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	bool set_timestamp = !read && q->set_timestamp;
 	int ret, index;
 
 	dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",
@@ -1271,9 +1268,7 @@ static int vb2_thread(void *data)
 
 	if (q->is_output) {
 		prequeue = q->num_buffers;
-		set_timestamp =
-			(q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
-			V4L2_BUF_FLAG_TIMESTAMP_COPY;
+		set_timestamp = q->set_timestamp;
 	}
 
 	set_freezable();
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index f1e7169..6ef7da7 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -431,6 +431,7 @@ struct vb2_buf_ops {
  *		called since poll() needs to return POLLERR in that situation.
  * @is_multiplanar: set if buffer type is multiplanar
  * @is_output:	set if buffer type is output
+ * @copy_timestamp: set if vb2-core should set timestamps
  * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
  *		last decoded buffer was already dequeued. Set for capture queues
  *		when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
@@ -480,6 +481,7 @@ struct vb2_queue {
 	unsigned int			waiting_for_buffers:1;
 	unsigned int			is_multiplanar:1;
 	unsigned int			is_output:1;
+	unsigned int			set_timestamp:1;
 	unsigned int			last_buffer_dequeued:1;
 
 	struct vb2_fileio_data		*fileio;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 4/7] media: videobuf2: Separate vb2_poll()
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
                   ` (2 preceding siblings ...)
  2015-10-16  6:27 ` [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 5/7] media: videobuf2: last_buffer_queued is checked at fill_v4l2_buffer() Junghak Sung
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Separate vb2_poll() into core and v4l2 part.

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c |   80 +++++++++++++++++++-----------
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 525f4c7..8ea4d9e 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -746,7 +746,7 @@ void vb2_queue_release(struct vb2_queue *q)
 EXPORT_SYMBOL_GPL(vb2_queue_release);
 
 /**
- * vb2_poll() - implements poll userspace operation
+ * vb2_core_poll() - implements poll userspace operation
  * @q:		videobuf2 queue
  * @file:	file argument passed to the poll file operation handler
  * @wait:	wait argument passed to the poll file operation handler
@@ -758,33 +758,20 @@ EXPORT_SYMBOL_GPL(vb2_queue_release);
  * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
  * will be reported as available for writing.
  *
- * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
- * pending events.
- *
  * The return values from this function are intended to be directly returned
  * from poll handler in driver.
  */
-unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
+unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
+		poll_table *wait)
 {
-	struct video_device *vfd = video_devdata(file);
 	unsigned long req_events = poll_requested_events(wait);
 	struct vb2_buffer *vb = NULL;
-	unsigned int res = 0;
 	unsigned long flags;
 
-	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
-		struct v4l2_fh *fh = file->private_data;
-
-		if (v4l2_event_pending(fh))
-			res = POLLPRI;
-		else if (req_events & POLLPRI)
-			poll_wait(file, &fh->wait, wait);
-	}
-
 	if (!q->is_output && !(req_events & (POLLIN | POLLRDNORM)))
-		return res;
+		return 0;
 	if (q->is_output && !(req_events & (POLLOUT | POLLWRNORM)))
-		return res;
+		return 0;
 
 	/*
 	 * Start file I/O emulator only if streaming API has not been used yet.
@@ -793,16 +780,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 		if (!q->is_output && (q->io_modes & VB2_READ) &&
 				(req_events & (POLLIN | POLLRDNORM))) {
 			if (__vb2_init_fileio(q, 1))
-				return res | POLLERR;
+				return POLLERR;
 		}
 		if (q->is_output && (q->io_modes & VB2_WRITE) &&
 				(req_events & (POLLOUT | POLLWRNORM))) {
 			if (__vb2_init_fileio(q, 0))
-				return res | POLLERR;
+				return POLLERR;
 			/*
 			 * Write to OUTPUT queue can be done immediately.
 			 */
-			return res | POLLOUT | POLLWRNORM;
+			return POLLOUT | POLLWRNORM;
 		}
 	}
 
@@ -811,21 +798,21 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 	 * error flag is set.
 	 */
 	if (!vb2_is_streaming(q) || q->error)
-		return res | POLLERR;
+		return POLLERR;
 	/*
 	 * For compatibility with vb1: if QBUF hasn't been called yet, then
 	 * return POLLERR as well. This only affects capture queues, output
 	 * queues will always initialize waiting_for_buffers to false.
 	 */
 	if (q->waiting_for_buffers)
-		return res | POLLERR;
+		return POLLERR;
 
 	/*
 	 * For output streams you can write as long as there are fewer buffers
 	 * queued than there are buffers available.
 	 */
 	if (q->is_output && q->queued_count < q->num_buffers)
-		return res | POLLOUT | POLLWRNORM;
+		return POLLOUT | POLLWRNORM;
 
 	if (list_empty(&q->done_list)) {
 		/*
@@ -833,7 +820,7 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 		 * return immediately. DQBUF will return -EPIPE.
 		 */
 		if (q->last_buffer_dequeued)
-			return res | POLLIN | POLLRDNORM;
+			return POLLIN | POLLRDNORM;
 
 		poll_wait(file, &q->done_wq, wait);
 	}
@@ -850,10 +837,47 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 	if (vb && (vb->state == VB2_BUF_STATE_DONE
 			|| vb->state == VB2_BUF_STATE_ERROR)) {
 		return (q->is_output) ?
-				res | POLLOUT | POLLWRNORM :
-				res | POLLIN | POLLRDNORM;
+				POLLOUT | POLLWRNORM :
+				POLLIN | POLLRDNORM;
 	}
-	return res;
+	return 0;
+}
+
+/**
+ * vb2_poll() - implements poll userspace operation
+ * @q:		videobuf2 queue
+ * @file:	file argument passed to the poll file operation handler
+ * @wait:	wait argument passed to the poll file operation handler
+ *
+ * This function implements poll file operation handler for a driver.
+ * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
+ * be informed that the file descriptor of a video device is available for
+ * reading.
+ * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
+ * will be reported as available for writing.
+ *
+ * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
+ * pending events.
+ *
+ * The return values from this function are intended to be directly returned
+ * from poll handler in driver.
+ */
+unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
+{
+	struct video_device *vfd = video_devdata(file);
+	unsigned long req_events = poll_requested_events(wait);
+	unsigned int res = 0;
+
+	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
+		struct v4l2_fh *fh = file->private_data;
+
+		if (v4l2_event_pending(fh))
+			res = POLLPRI;
+		else if (req_events & POLLPRI)
+			poll_wait(file, &fh->wait, wait);
+	}
+
+	return res | vb2_core_poll(q, file, wait);
 }
 EXPORT_SYMBOL_GPL(vb2_poll);
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 5/7] media: videobuf2: last_buffer_queued is checked at fill_v4l2_buffer()
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
                   ` (3 preceding siblings ...)
  2015-10-16  6:27 ` [RFC PATCH v7 4/7] media: videobuf2: Separate vb2_poll() Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-16  6:27 ` [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread Junghak Sung
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

The location to set last_buffer_queued is moved to fill_v4l2_buffer().
So, vb2_core_dqbuf() can be used instead of vb2_internal_dqbuf()
in __vb2_perform_fileio().

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 8ea4d9e..dabcb6d 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -270,6 +270,11 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 	if (vb2_buffer_in_use(q, vb))
 		b->flags |= V4L2_BUF_FLAG_MAPPED;
 
+	if (!q->is_output &&
+		b->flags & V4L2_BUF_FLAG_DONE &&
+		b->flags & V4L2_BUF_FLAG_LAST)
+		q->last_buffer_dequeued = true;
+
 	return 0;
 }
 
@@ -580,10 +585,6 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b,
 
 	ret = vb2_core_dqbuf(q, b, nonblocking);
 
-	if (!ret && !q->is_output &&
-			b->flags & V4L2_BUF_FLAG_LAST)
-		q->last_buffer_dequeued = true;
-
 	return ret;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
                   ` (4 preceding siblings ...)
  2015-10-16  6:27 ` [RFC PATCH v7 5/7] media: videobuf2: last_buffer_queued is checked at fill_v4l2_buffer() Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-29  2:31   ` Hans Verkuil
  2015-10-16  6:27 ` [RFC PATCH v7 7/7] media: videobuf2: Move vb2_fileio_data and vb2_thread to core part Junghak Sung
  2015-10-19  7:56 ` [RFC PATCH v7] Refactoring Videobuf2 for common use Hans Verkuil
  7 siblings, 1 reply; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Replace v4l2-stuffs with common things in struct vb2_fileio_data and
vb2_thread().

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-v4l2.c |  113 +++++++++++++++---------------
 1 file changed, 58 insertions(+), 55 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index dabcb6d..ea5ab37 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -882,6 +882,15 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 }
 EXPORT_SYMBOL_GPL(vb2_poll);
 
+static void vb2_get_timestamp(struct timeval *tv)
+{
+	struct timespec ts;
+
+	ktime_get_ts(&ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+}
+
 /**
  * struct vb2_fileio_buf - buffer context used by file io emulator
  *
@@ -921,9 +930,10 @@ struct vb2_fileio_buf {
  * or write function.
  */
 struct vb2_fileio_data {
-	struct v4l2_requestbuffers req;
-	struct v4l2_plane p;
-	struct v4l2_buffer b;
+	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;
@@ -976,6 +986,10 @@ 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)
+		return -ENOMEM;
+
 	fileio->read_once = q->fileio_read_once;
 	fileio->write_immediately = q->fileio_write_immediately;
 
@@ -983,11 +997,11 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
 	 * Request buffers and use MMAP type to force driver
 	 * to allocate buffers by itself.
 	 */
-	fileio->req.count = count;
-	fileio->req.memory = VB2_MEMORY_MMAP;
-	fileio->req.type = q->type;
+	fileio->count = count;
+	fileio->memory = VB2_MEMORY_MMAP;
+	fileio->type = q->type;
 	q->fileio = fileio;
-	ret = vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
+	ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count);
 	if (ret)
 		goto err_kfree;
 
@@ -1016,24 +1030,17 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
 	 * Read mode requires pre queuing of all buffers.
 	 */
 	if (read) {
-		bool is_multiplanar = q->is_multiplanar;
-
 		/*
 		 * Queue all buffers.
 		 */
 		for (i = 0; i < q->num_buffers; i++) {
-			struct v4l2_buffer *b = &fileio->b;
+			struct vb2_buffer *b = fileio->b;
 
-			memset(b, 0, sizeof(*b));
+			memset(b, 0, q->buf_struct_size);
 			b->type = q->type;
-			if (is_multiplanar) {
-				memset(&fileio->p, 0, sizeof(fileio->p));
-				b->m.planes = &fileio->p;
-				b->length = 1;
-			}
 			b->memory = q->memory;
 			b->index = i;
-			ret = vb2_internal_qbuf(q, b);
+			ret = vb2_core_qbuf(q, i, b);
 			if (ret)
 				goto err_reqbufs;
 			fileio->bufs[i].queued = 1;
@@ -1056,8 +1063,8 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
 	return ret;
 
 err_reqbufs:
-	fileio->req.count = 0;
-	vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
+	fileio->count = 0;
+	vb2_core_reqbufs(q, fileio->memory, &fileio->count);
 
 err_kfree:
 	q->fileio = NULL;
@@ -1076,8 +1083,9 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q)
 	if (fileio) {
 		vb2_core_streamoff(q, q->type);
 		q->fileio = NULL;
-		fileio->req.count = 0;
-		vb2_reqbufs(q, &fileio->req);
+		fileio->count = 0;
+		vb2_core_reqbufs(q, fileio->memory, &fileio->count);
+		kfree(fileio->b);
 		kfree(fileio);
 		dprintk(3, "file io emulator closed\n");
 	}
@@ -1130,24 +1138,21 @@ 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;
+
 		/*
 		 * Call vb2_dqbuf to get buffer back.
 		 */
-		memset(&fileio->b, 0, sizeof(fileio->b));
-		fileio->b.type = q->type;
-		fileio->b.memory = q->memory;
-		if (is_multiplanar) {
-			memset(&fileio->p, 0, sizeof(fileio->p));
-			fileio->b.m.planes = &fileio->p;
-			fileio->b.length = 1;
-		}
-		ret = vb2_internal_dqbuf(q, &fileio->b, nonblock);
+		memset(b, 0, q->buf_struct_size);
+		b->type = q->type;
+		b->memory = q->memory;
+		ret = vb2_core_dqbuf(q, b, nonblock);
 		dprintk(5, "vb2_dqbuf result: %d\n", ret);
 		if (ret)
 			return ret;
 		fileio->dq_count += 1;
 
-		fileio->cur_index = index = fileio->b.index;
+		fileio->cur_index = index = b->index;
 		buf = &fileio->bufs[index];
 
 		/*
@@ -1159,8 +1164,8 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
 				 : vb2_plane_size(q->bufs[index], 0);
 		/* Compensate for data_offset on read in the multiplanar case. */
 		if (is_multiplanar && read &&
-		    fileio->b.m.planes[0].data_offset < buf->size) {
-			buf->pos = fileio->b.m.planes[0].data_offset;
+				b->planes[0].data_offset < buf->size) {
+			buf->pos = b->planes[0].data_offset;
 			buf->size -= buf->pos;
 		}
 	} else {
@@ -1199,6 +1204,8 @@ 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;
+
 		/*
 		 * Check if this is the last buffer to read.
 		 */
@@ -1210,20 +1217,15 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
 		/*
 		 * Call vb2_qbuf and give buffer to the driver.
 		 */
-		memset(&fileio->b, 0, sizeof(fileio->b));
-		fileio->b.type = q->type;
-		fileio->b.memory = q->memory;
-		fileio->b.index = index;
-		fileio->b.bytesused = buf->pos;
-		if (is_multiplanar) {
-			memset(&fileio->p, 0, sizeof(fileio->p));
-			fileio->p.bytesused = buf->pos;
-			fileio->b.m.planes = &fileio->p;
-			fileio->b.length = 1;
-		}
+		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 (set_timestamp)
-			v4l2_get_timestamp(&fileio->b.timestamp);
-		ret = vb2_internal_qbuf(q, &fileio->b);
+			vb2_get_timestamp(&b->timestamp);
+		ret = vb2_core_qbuf(q, index, b);
 		dprintk(5, "vb2_dbuf result: %d\n", ret);
 		if (ret)
 			return ret;
@@ -1300,20 +1302,21 @@ 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(&fileio->b, 0, sizeof(fileio->b));
-		fileio->b.type = q->type;
-		fileio->b.memory = q->memory;
+		memset(b, 0, q->buf_struct_size);
+		b->type = q->type;
+		b->memory = q->memory;
 		if (prequeue) {
-			fileio->b.index = index++;
+			b->index = index++;
 			prequeue--;
 		} else {
 			call_void_qop(q, wait_finish, q);
 			if (!threadio->stop)
-				ret = vb2_internal_dqbuf(q, &fileio->b, 0);
+				ret = vb2_core_dqbuf(q, b, 0);
 			call_void_qop(q, wait_prepare, q);
 			dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
 		}
@@ -1321,15 +1324,15 @@ static int vb2_thread(void *data)
 			break;
 		try_to_freeze();
 
-		vb = q->bufs[fileio->b.index];
-		if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR))
+		vb = q->bufs[b->index];
+		if (b->state == VB2_BUF_STATE_DONE)
 			if (threadio->fnc(vb, threadio->priv))
 				break;
 		call_void_qop(q, wait_finish, q);
 		if (set_timestamp)
-			v4l2_get_timestamp(&fileio->b.timestamp);
+			vb2_get_timestamp(&b->timestamp);
 		if (!threadio->stop)
-			ret = vb2_internal_qbuf(q, &fileio->b);
+			ret = vb2_core_qbuf(q, b->index, b);
 		call_void_qop(q, wait_prepare, q);
 		if (ret || threadio->stop)
 			break;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC PATCH v7 7/7] media: videobuf2: Move vb2_fileio_data and vb2_thread to core part
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
                   ` (5 preceding siblings ...)
  2015-10-16  6:27 ` [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread Junghak Sung
@ 2015-10-16  6:27 ` Junghak Sung
  2015-10-19  7:56 ` [RFC PATCH v7] Refactoring Videobuf2 for common use Hans Verkuil
  7 siblings, 0 replies; 13+ messages in thread
From: Junghak Sung @ 2015-10-16  6:27 UTC (permalink / raw)
  To: linux-media, mchehab, hverkuil, laurent.pinchart, sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon,
	Junghak Sung

Move things related with vb2 file I/O and vb2_thread without doing any
functional changes. After that, videobuf2-internal.h is removed because
it is not necessary any more.

Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/media/v4l2-core/videobuf2-core.c     |  786 +++++++++++++++++++++++++-
 drivers/media/v4l2-core/videobuf2-internal.h |  161 ------
 drivers/media/v4l2-core/videobuf2-v4l2.c     |  639 +--------------------
 include/media/videobuf2-core.h               |   43 ++
 include/media/videobuf2-v4l2.h               |   38 +-
 5 files changed, 833 insertions(+), 834 deletions(-)
 delete mode 100644 drivers/media/v4l2-core/videobuf2-internal.h

diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 33bdd81..497eef9 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -28,11 +28,155 @@
 
 #include <trace/events/vb2.h>
 
-#include "videobuf2-internal.h"
+static int debug;
+module_param(debug, int, 0644);
 
-int vb2_debug;
-EXPORT_SYMBOL_GPL(vb2_debug);
-module_param_named(debug, vb2_debug, int, 0644);
+#define dprintk(level, fmt, arg...)					      \
+	do {								      \
+		if (debug >= level)					      \
+			pr_info("vb2-core: %s: " fmt, __func__, ## arg); \
+	} while (0)
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+ * If advanced debugging is on, then count how often each op is called
+ * successfully, which can either be per-buffer or per-queue.
+ *
+ * This makes it easy to check that the 'init' and 'cleanup'
+ * (and variations thereof) stay balanced.
+ */
+
+#define log_memop(vb, op)						\
+	dprintk(2, "call_memop(%p, %d, %s)%s\n",			\
+		(vb)->vb2_queue, (vb)->index, #op,			\
+		(vb)->vb2_queue->mem_ops->op ? "" : " (nop)")
+
+#define call_memop(vb, op, args...)					\
+({									\
+	struct vb2_queue *_q = (vb)->vb2_queue;				\
+	int err;							\
+									\
+	log_memop(vb, op);						\
+	err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0;		\
+	if (!err)							\
+		(vb)->cnt_mem_ ## op++;					\
+	err;								\
+})
+
+#define call_ptr_memop(vb, op, args...)					\
+({									\
+	struct vb2_queue *_q = (vb)->vb2_queue;				\
+	void *ptr;							\
+									\
+	log_memop(vb, op);						\
+	ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL;		\
+	if (!IS_ERR_OR_NULL(ptr))					\
+		(vb)->cnt_mem_ ## op++;					\
+	ptr;								\
+})
+
+#define call_void_memop(vb, op, args...)				\
+({									\
+	struct vb2_queue *_q = (vb)->vb2_queue;				\
+									\
+	log_memop(vb, op);						\
+	if (_q->mem_ops->op)						\
+		_q->mem_ops->op(args);					\
+	(vb)->cnt_mem_ ## op++;						\
+})
+
+#define log_qop(q, op)							\
+	dprintk(2, "call_qop(%p, %s)%s\n", q, #op,			\
+		(q)->ops->op ? "" : " (nop)")
+
+#define call_qop(q, op, args...)					\
+({									\
+	int err;							\
+									\
+	log_qop(q, op);							\
+	err = (q)->ops->op ? (q)->ops->op(args) : 0;			\
+	if (!err)							\
+		(q)->cnt_ ## op++;					\
+	err;								\
+})
+
+#define call_void_qop(q, op, args...)					\
+({									\
+	log_qop(q, op);							\
+	if ((q)->ops->op)						\
+		(q)->ops->op(args);					\
+	(q)->cnt_ ## op++;						\
+})
+
+#define log_vb_qop(vb, op, args...)					\
+	dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",			\
+		(vb)->vb2_queue, (vb)->index, #op,			\
+		(vb)->vb2_queue->ops->op ? "" : " (nop)")
+
+#define call_vb_qop(vb, op, args...)					\
+({									\
+	int err;							\
+									\
+	log_vb_qop(vb, op);						\
+	err = (vb)->vb2_queue->ops->op ?				\
+		(vb)->vb2_queue->ops->op(args) : 0;			\
+	if (!err)							\
+		(vb)->cnt_ ## op++;					\
+	err;								\
+})
+
+#define call_void_vb_qop(vb, op, args...)				\
+({									\
+	log_vb_qop(vb, op);						\
+	if ((vb)->vb2_queue->ops->op)					\
+		(vb)->vb2_queue->ops->op(args);				\
+	(vb)->cnt_ ## op++;						\
+})
+
+#else
+
+#define call_memop(vb, op, args...)					\
+	((vb)->vb2_queue->mem_ops->op ?					\
+		(vb)->vb2_queue->mem_ops->op(args) : 0)
+
+#define call_ptr_memop(vb, op, args...)					\
+	((vb)->vb2_queue->mem_ops->op ?					\
+		(vb)->vb2_queue->mem_ops->op(args) : NULL)
+
+#define call_void_memop(vb, op, args...)				\
+	do {								\
+		if ((vb)->vb2_queue->mem_ops->op)			\
+			(vb)->vb2_queue->mem_ops->op(args);		\
+	} while (0)
+
+#define call_qop(q, op, args...)					\
+	((q)->ops->op ? (q)->ops->op(args) : 0)
+
+#define call_void_qop(q, op, args...)					\
+	do {								\
+		if ((q)->ops->op)					\
+			(q)->ops->op(args);				\
+	} while (0)
+
+#define call_vb_qop(vb, op, args...)					\
+	((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
+
+#define call_void_vb_qop(vb, op, args...)				\
+	do {								\
+		if ((vb)->vb2_queue->ops->op)				\
+			(vb)->vb2_queue->ops->op(args);			\
+	} while (0)
+
+#endif
+
+#define call_bufop(q, op, args...)					\
+({									\
+	int ret = 0;							\
+	if (q && q->buf_ops && q->buf_ops->op)				\
+		ret = q->buf_ops->op(args);				\
+	ret;								\
+})
 
 static void __vb2_queue_cancel(struct vb2_queue *q);
 static void __enqueue_in_driver(struct vb2_buffer *vb);
@@ -330,7 +474,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 		bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming ||
 				  q->cnt_wait_prepare != q->cnt_wait_finish;
 
-		if (unbalanced || vb2_debug) {
+		if (unbalanced || debug) {
 			pr_info("vb2: counters for queue %p:%s\n", q,
 				unbalanced ? " UNBALANCED!" : "");
 			pr_info("vb2:     setup: %u start_streaming: %u stop_streaming: %u\n",
@@ -356,7 +500,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 				  vb->cnt_buf_prepare != vb->cnt_buf_finish ||
 				  vb->cnt_buf_init != vb->cnt_buf_cleanup;
 
-		if (unbalanced || vb2_debug) {
+		if (unbalanced || debug) {
 			pr_info("vb2:   counters for queue %p, buffer %d:%s\n",
 				q, buffer, unbalanced ? " UNBALANCED!" : "");
 			pr_info("vb2:     buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
@@ -2073,6 +2217,8 @@ int vb2_core_queue_init(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_core_queue_init);
 
+static int __vb2_init_fileio(struct vb2_queue *q, int read);
+static int __vb2_cleanup_fileio(struct vb2_queue *q);
 /**
  * vb2_core_queue_release() - stop streaming, release the queue and free memory
  * @q:		videobuf2 queue
@@ -2083,6 +2229,7 @@ EXPORT_SYMBOL_GPL(vb2_core_queue_init);
  */
 void vb2_core_queue_release(struct vb2_queue *q)
 {
+	__vb2_cleanup_fileio(q);
 	__vb2_queue_cancel(q);
 	mutex_lock(&q->mmap_lock);
 	__vb2_queue_free(q, q->num_buffers);
@@ -2090,6 +2237,633 @@ void vb2_core_queue_release(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_core_queue_release);
 
+/**
+ * vb2_core_poll() - implements poll userspace operation
+ * @q:		videobuf2 queue
+ * @file:	file argument passed to the poll file operation handler
+ * @wait:	wait argument passed to the poll file operation handler
+ *
+ * This function implements poll file operation handler for a driver.
+ * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
+ * be informed that the file descriptor of a video device is available for
+ * reading.
+ * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
+ * will be reported as available for writing.
+ *
+ * The return values from this function are intended to be directly returned
+ * from poll handler in driver.
+ */
+unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
+		poll_table *wait)
+{
+	unsigned long req_events = poll_requested_events(wait);
+	struct vb2_buffer *vb = NULL;
+	unsigned long flags;
+
+	if (!q->is_output && !(req_events & (POLLIN | POLLRDNORM)))
+		return 0;
+	if (q->is_output && !(req_events & (POLLOUT | POLLWRNORM)))
+		return 0;
+
+	/*
+	 * Start file I/O emulator only if streaming API has not been used yet.
+	 */
+	if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) {
+		if (!q->is_output && (q->io_modes & VB2_READ) &&
+				(req_events & (POLLIN | POLLRDNORM))) {
+			if (__vb2_init_fileio(q, 1))
+				return POLLERR;
+		}
+		if (q->is_output && (q->io_modes & VB2_WRITE) &&
+				(req_events & (POLLOUT | POLLWRNORM))) {
+			if (__vb2_init_fileio(q, 0))
+				return POLLERR;
+			/*
+			 * Write to OUTPUT queue can be done immediately.
+			 */
+			return POLLOUT | POLLWRNORM;
+		}
+	}
+
+	/*
+	 * There is nothing to wait for if the queue isn't streaming, or if the
+	 * error flag is set.
+	 */
+	if (!vb2_is_streaming(q) || q->error)
+		return POLLERR;
+	/*
+	 * For compatibility with vb1: if QBUF hasn't been called yet, then
+	 * return POLLERR as well. This only affects capture queues, output
+	 * queues will always initialize waiting_for_buffers to false.
+	 */
+	if (q->waiting_for_buffers)
+		return POLLERR;
+
+	/*
+	 * For output streams you can write as long as there are fewer buffers
+	 * queued than there are buffers available.
+	 */
+	if (q->is_output && q->queued_count < q->num_buffers)
+		return POLLOUT | POLLWRNORM;
+
+	if (list_empty(&q->done_list)) {
+		/*
+		 * If the last buffer was dequeued from a capture queue,
+		 * return immediately. DQBUF will return -EPIPE.
+		 */
+		if (q->last_buffer_dequeued)
+			return POLLIN | POLLRDNORM;
+
+		poll_wait(file, &q->done_wq, wait);
+	}
+
+	/*
+	 * Take first buffer available for dequeuing.
+	 */
+	spin_lock_irqsave(&q->done_lock, flags);
+	if (!list_empty(&q->done_list))
+		vb = list_first_entry(&q->done_list, struct vb2_buffer,
+					done_entry);
+	spin_unlock_irqrestore(&q->done_lock, flags);
+
+	if (vb && (vb->state == VB2_BUF_STATE_DONE
+			|| vb->state == VB2_BUF_STATE_ERROR)) {
+		return (q->is_output) ?
+				POLLOUT | POLLWRNORM :
+				POLLIN | POLLRDNORM;
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_core_poll);
+
+static void vb2_get_timestamp(struct timeval *tv)
+{
+	struct timespec ts;
+
+	ktime_get_ts(&ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+}
+
+/**
+ * struct vb2_fileio_buf - buffer context used by file io emulator
+ *
+ * vb2 provides a compatibility layer and emulator of file io (read and
+ * write) calls on top of streaming API. This structure is used for
+ * tracking context related to the buffers.
+ */
+struct vb2_fileio_buf {
+	void *vaddr;
+	unsigned int size;
+	unsigned int pos;
+	unsigned int queued:1;
+};
+
+/**
+ * struct vb2_fileio_data - queue context used by file io emulator
+ *
+ * @cur_index:	the index of the buffer currently being read from or
+ *		written to. If equal to q->num_buffers then a new buffer
+ *		must be dequeued.
+ * @initial_index: in the read() case all buffers are queued up immediately
+ *		in __vb2_init_fileio() and __vb2_perform_fileio() just cycles
+ *		buffers. However, in the write() case no buffers are initially
+ *		queued, instead whenever a buffer is full it is queued up by
+ *		__vb2_perform_fileio(). Only once all available buffers have
+ *		been queued up will __vb2_perform_fileio() start to dequeue
+ *		buffers. This means that initially __vb2_perform_fileio()
+ *		needs to know what buffer index to use when it is queuing up
+ *		the buffers for the first time. That initial index is stored
+ *		in this field. Once it is equal to q->num_buffers all
+ *		available buffers have been queued and __vb2_perform_fileio()
+ *		should start the normal dequeue/queue cycle.
+ *
+ * vb2 provides a compatibility layer and emulator of file io (read and
+ * write) calls on top of streaming API. For proper operation it required
+ * this structure to save the driver state between each call of the read
+ * or write function.
+ */
+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;
+	unsigned int q_count;
+	unsigned int dq_count;
+	unsigned read_once:1;
+	unsigned write_immediately:1;
+};
+
+/**
+ * __vb2_init_fileio() - initialize file io emulator
+ * @q:		videobuf2 queue
+ * @read:	mode selector (1 means read, 0 means write)
+ */
+static int __vb2_init_fileio(struct vb2_queue *q, int read)
+{
+	struct vb2_fileio_data *fileio;
+	int i, ret;
+	unsigned int count = 0;
+
+	/*
+	 * Sanity check
+	 */
+	if (WARN_ON((read && !(q->io_modes & VB2_READ)) ||
+		    (!read && !(q->io_modes & VB2_WRITE))))
+		return -EINVAL;
+
+	/*
+	 * Check if device supports mapping buffers to kernel virtual space.
+	 */
+	if (!q->mem_ops->vaddr)
+		return -EBUSY;
+
+	/*
+	 * Check if streaming api has not been already activated.
+	 */
+	if (q->streaming || q->num_buffers > 0)
+		return -EBUSY;
+
+	/*
+	 * Start with count 1, driver can increase it in queue_setup()
+	 */
+	count = 1;
+
+	dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",
+		(read) ? "read" : "write", count, q->fileio_read_once,
+		q->fileio_write_immediately);
+
+	fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
+	if (fileio == NULL)
+		return -ENOMEM;
+
+	fileio->b = kzalloc(q->buf_struct_size, GFP_KERNEL);
+	if (fileio->b == NULL)
+		return -ENOMEM;
+
+	fileio->read_once = q->fileio_read_once;
+	fileio->write_immediately = q->fileio_write_immediately;
+
+	/*
+	 * Request buffers and use MMAP type to force driver
+	 * to allocate buffers by itself.
+	 */
+	fileio->count = count;
+	fileio->memory = VB2_MEMORY_MMAP;
+	fileio->type = q->type;
+	q->fileio = fileio;
+	ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count);
+	if (ret)
+		goto err_kfree;
+
+	/*
+	 * Check if plane_count is correct
+	 * (multiplane buffers are not supported).
+	 */
+	if (q->bufs[0]->num_planes != 1) {
+		ret = -EBUSY;
+		goto err_reqbufs;
+	}
+
+	/*
+	 * Get kernel address of each buffer.
+	 */
+	for (i = 0; i < q->num_buffers; i++) {
+		fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
+		if (fileio->bufs[i].vaddr == NULL) {
+			ret = -EINVAL;
+			goto err_reqbufs;
+		}
+		fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
+	}
+
+	/*
+	 * Read mode requires pre queuing of all buffers.
+	 */
+	if (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);
+			if (ret)
+				goto err_reqbufs;
+			fileio->bufs[i].queued = 1;
+		}
+		/*
+		 * All buffers have been queued, so mark that by setting
+		 * initial_index to q->num_buffers
+		 */
+		fileio->initial_index = q->num_buffers;
+		fileio->cur_index = q->num_buffers;
+	}
+
+	/*
+	 * Start streaming.
+	 */
+	ret = vb2_core_streamon(q, q->type);
+	if (ret)
+		goto err_reqbufs;
+
+	return ret;
+
+err_reqbufs:
+	fileio->count = 0;
+	vb2_core_reqbufs(q, fileio->memory, &fileio->count);
+
+err_kfree:
+	q->fileio = NULL;
+	kfree(fileio);
+	return ret;
+}
+
+/**
+ * __vb2_cleanup_fileio() - free resourced used by file io emulator
+ * @q:		videobuf2 queue
+ */
+static int __vb2_cleanup_fileio(struct vb2_queue *q)
+{
+	struct vb2_fileio_data *fileio = q->fileio;
+
+	if (fileio) {
+		vb2_core_streamoff(q, q->type);
+		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");
+	}
+	return 0;
+}
+
+/**
+ * __vb2_perform_fileio() - perform a single file io (read or write) operation
+ * @q:		videobuf2 queue
+ * @data:	pointed to target userspace buffer
+ * @count:	number of bytes to read or write
+ * @ppos:	file handle position tracking pointer
+ * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
+ * @read:	access mode selector (1 means read, 0 means write)
+ */
+static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
+		loff_t *ppos, int nonblock, int read)
+{
+	struct vb2_fileio_data *fileio;
+	struct vb2_fileio_buf *buf;
+	bool is_multiplanar = q->is_multiplanar;
+	/*
+	 * When using write() to write data to an output video node the vb2 core
+	 * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody
+	 * else is able to provide this information with the write() operation.
+	 */
+	bool set_timestamp = !read && q->set_timestamp;
+	int ret, index;
+
+	dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",
+		read ? "read" : "write", (long)*ppos, count,
+		nonblock ? "non" : "");
+
+	if (!data)
+		return -EINVAL;
+
+	/*
+	 * Initialize emulator on first call.
+	 */
+	if (!vb2_fileio_is_active(q)) {
+		ret = __vb2_init_fileio(q, read);
+		dprintk(3, "vb2_init_fileio result: %d\n", ret);
+		if (ret)
+			return ret;
+	}
+	fileio = q->fileio;
+
+	/*
+	 * Check if we need to dequeue the buffer.
+	 */
+	index = fileio->cur_index;
+	if (index >= q->num_buffers) {
+		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;
+		ret = vb2_core_dqbuf(q, b, nonblock);
+		dprintk(5, "vb2_dqbuf result: %d\n", ret);
+		if (ret)
+			return ret;
+		fileio->dq_count += 1;
+
+		fileio->cur_index = index = b->index;
+		buf = &fileio->bufs[index];
+
+		/*
+		 * Get number of bytes filled by the driver
+		 */
+		buf->pos = 0;
+		buf->queued = 0;
+		buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
+				 : vb2_plane_size(q->bufs[index], 0);
+		/* Compensate for data_offset on read in the multiplanar case. */
+		if (is_multiplanar && read &&
+				b->planes[0].data_offset < buf->size) {
+			buf->pos = b->planes[0].data_offset;
+			buf->size -= buf->pos;
+		}
+	} else {
+		buf = &fileio->bufs[index];
+	}
+
+	/*
+	 * Limit count on last few bytes of the buffer.
+	 */
+	if (buf->pos + count > buf->size) {
+		count = buf->size - buf->pos;
+		dprintk(5, "reducing read count: %zd\n", count);
+	}
+
+	/*
+	 * Transfer data to userspace.
+	 */
+	dprintk(3, "copying %zd bytes - buffer %d, offset %u\n",
+		count, index, buf->pos);
+	if (read)
+		ret = copy_to_user(data, buf->vaddr + buf->pos, count);
+	else
+		ret = copy_from_user(buf->vaddr + buf->pos, data, count);
+	if (ret) {
+		dprintk(3, "error copying data\n");
+		return -EFAULT;
+	}
+
+	/*
+	 * Update counters.
+	 */
+	buf->pos += count;
+	*ppos += count;
+
+	/*
+	 * Queue next buffer if required.
+	 */
+	if (buf->pos == buf->size || (!read && fileio->write_immediately)) {
+		struct vb2_buffer *b = fileio->b;
+
+		/*
+		 * Check if this is the last buffer to read.
+		 */
+		if (read && fileio->read_once && fileio->dq_count == 1) {
+			dprintk(3, "read limit reached\n");
+			return __vb2_cleanup_fileio(q);
+		}
+
+		/*
+		 * 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 (set_timestamp)
+			vb2_get_timestamp(&b->timestamp);
+		ret = vb2_core_qbuf(q, index, b);
+		dprintk(5, "vb2_dbuf result: %d\n", ret);
+		if (ret)
+			return ret;
+
+		/*
+		 * Buffer has been queued, update the status
+		 */
+		buf->pos = 0;
+		buf->queued = 1;
+		buf->size = vb2_plane_size(q->bufs[index], 0);
+		fileio->q_count += 1;
+		/*
+		 * If we are queuing up buffers for the first time, then
+		 * increase initial_index by one.
+		 */
+		if (fileio->initial_index < q->num_buffers)
+			fileio->initial_index++;
+		/*
+		 * The next buffer to use is either a buffer that's going to be
+		 * queued for the first time (initial_index < q->num_buffers)
+		 * or it is equal to q->num_buffers, meaning that the next
+		 * time we need to dequeue a buffer since we've now queued up
+		 * all the 'first time' buffers.
+		 */
+		fileio->cur_index = fileio->initial_index;
+	}
+
+	/*
+	 * Return proper number of bytes processed.
+	 */
+	if (ret == 0)
+		ret = count;
+	return ret;
+}
+
+size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
+		loff_t *ppos, int nonblocking)
+{
+	return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
+}
+EXPORT_SYMBOL_GPL(vb2_read);
+
+size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
+		loff_t *ppos, int nonblocking)
+{
+	return __vb2_perform_fileio(q, (char __user *) data, count,
+							ppos, nonblocking, 0);
+}
+EXPORT_SYMBOL_GPL(vb2_write);
+
+struct vb2_threadio_data {
+	struct task_struct *thread;
+	vb2_thread_fnc fnc;
+	void *priv;
+	bool stop;
+};
+
+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 set_timestamp = false;
+	int prequeue = 0;
+	int index = 0;
+	int ret = 0;
+
+	if (q->is_output) {
+		prequeue = q->num_buffers;
+		set_timestamp = q->set_timestamp;
+	}
+
+	set_freezable();
+
+	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++;
+			prequeue--;
+		} else {
+			call_void_qop(q, wait_finish, q);
+			if (!threadio->stop)
+				ret = vb2_core_dqbuf(q, b, 0);
+			call_void_qop(q, wait_prepare, q);
+			dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
+		}
+		if (ret || threadio->stop)
+			break;
+		try_to_freeze();
+
+		vb = q->bufs[b->index];
+		if (b->state == VB2_BUF_STATE_DONE)
+			if (threadio->fnc(vb, threadio->priv))
+				break;
+		call_void_qop(q, wait_finish, q);
+		if (set_timestamp)
+			vb2_get_timestamp(&b->timestamp);
+		if (!threadio->stop)
+			ret = vb2_core_qbuf(q, b->index, b);
+		call_void_qop(q, wait_prepare, q);
+		if (ret || threadio->stop)
+			break;
+	}
+
+	/* Hmm, linux becomes *very* unhappy without this ... */
+	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	}
+	return 0;
+}
+
+/*
+ * This function should not be used for anything else but the videobuf2-dvb
+ * support. If you think you have another good use-case for this, then please
+ * contact the linux-media mailinglist first.
+ */
+int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
+		     const char *thread_name)
+{
+	struct vb2_threadio_data *threadio;
+	int ret = 0;
+
+	if (q->threadio)
+		return -EBUSY;
+	if (vb2_is_busy(q))
+		return -EBUSY;
+	if (WARN_ON(q->fileio))
+		return -EBUSY;
+
+	threadio = kzalloc(sizeof(*threadio), GFP_KERNEL);
+	if (threadio == NULL)
+		return -ENOMEM;
+	threadio->fnc = fnc;
+	threadio->priv = priv;
+
+	ret = __vb2_init_fileio(q, !q->is_output);
+	dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
+	if (ret)
+		goto nomem;
+	q->threadio = threadio;
+	threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name);
+	if (IS_ERR(threadio->thread)) {
+		ret = PTR_ERR(threadio->thread);
+		threadio->thread = NULL;
+		goto nothread;
+	}
+	return 0;
+
+nothread:
+	__vb2_cleanup_fileio(q);
+nomem:
+	kfree(threadio);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(vb2_thread_start);
+
+int vb2_thread_stop(struct vb2_queue *q)
+{
+	struct vb2_threadio_data *threadio = q->threadio;
+	int err;
+
+	if (threadio == NULL)
+		return 0;
+	threadio->stop = true;
+	/* Wake up all pending sleeps in the thread */
+	vb2_queue_error(q);
+	err = kthread_stop(threadio->thread);
+	__vb2_cleanup_fileio(q);
+	threadio->thread = NULL;
+	kfree(threadio);
+	q->threadio = NULL;
+	return err;
+}
+EXPORT_SYMBOL_GPL(vb2_thread_stop);
+
 MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
 MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/v4l2-core/videobuf2-internal.h b/drivers/media/v4l2-core/videobuf2-internal.h
deleted file mode 100644
index 79018c7..0000000
--- a/drivers/media/v4l2-core/videobuf2-internal.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifndef _MEDIA_VIDEOBUF2_INTERNAL_H
-#define _MEDIA_VIDEOBUF2_INTERNAL_H
-
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <media/videobuf2-core.h>
-
-extern int vb2_debug;
-
-#define dprintk(level, fmt, arg...)					      \
-	do {								      \
-		if (vb2_debug >= level)					      \
-			pr_info("vb2: %s: " fmt, __func__, ## arg); \
-	} while (0)
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
- * If advanced debugging is on, then count how often each op is called
- * successfully, which can either be per-buffer or per-queue.
- *
- * This makes it easy to check that the 'init' and 'cleanup'
- * (and variations thereof) stay balanced.
- */
-
-#define log_memop(vb, op)						\
-	dprintk(2, "call_memop(%p, %d, %s)%s\n",			\
-		(vb)->vb2_queue, (vb)->index, #op,			\
-		(vb)->vb2_queue->mem_ops->op ? "" : " (nop)")
-
-#define call_memop(vb, op, args...)					\
-({									\
-	struct vb2_queue *_q = (vb)->vb2_queue;				\
-	int err;							\
-									\
-	log_memop(vb, op);						\
-	err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0;		\
-	if (!err)							\
-		(vb)->cnt_mem_ ## op++;					\
-	err;								\
-})
-
-#define call_ptr_memop(vb, op, args...)					\
-({									\
-	struct vb2_queue *_q = (vb)->vb2_queue;				\
-	void *ptr;							\
-									\
-	log_memop(vb, op);						\
-	ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL;		\
-	if (!IS_ERR_OR_NULL(ptr))					\
-		(vb)->cnt_mem_ ## op++;					\
-	ptr;								\
-})
-
-#define call_void_memop(vb, op, args...)				\
-({									\
-	struct vb2_queue *_q = (vb)->vb2_queue;				\
-									\
-	log_memop(vb, op);						\
-	if (_q->mem_ops->op)						\
-		_q->mem_ops->op(args);					\
-	(vb)->cnt_mem_ ## op++;						\
-})
-
-#define log_qop(q, op)							\
-	dprintk(2, "call_qop(%p, %s)%s\n", q, #op,			\
-		(q)->ops->op ? "" : " (nop)")
-
-#define call_qop(q, op, args...)					\
-({									\
-	int err;							\
-									\
-	log_qop(q, op);							\
-	err = (q)->ops->op ? (q)->ops->op(args) : 0;			\
-	if (!err)							\
-		(q)->cnt_ ## op++;					\
-	err;								\
-})
-
-#define call_void_qop(q, op, args...)					\
-({									\
-	log_qop(q, op);							\
-	if ((q)->ops->op)						\
-		(q)->ops->op(args);					\
-	(q)->cnt_ ## op++;						\
-})
-
-#define log_vb_qop(vb, op, args...)					\
-	dprintk(2, "call_vb_qop(%p, %d, %s)%s\n",			\
-		(vb)->vb2_queue, (vb)->index, #op,			\
-		(vb)->vb2_queue->ops->op ? "" : " (nop)")
-
-#define call_vb_qop(vb, op, args...)					\
-({									\
-	int err;							\
-									\
-	log_vb_qop(vb, op);						\
-	err = (vb)->vb2_queue->ops->op ?				\
-		(vb)->vb2_queue->ops->op(args) : 0;			\
-	if (!err)							\
-		(vb)->cnt_ ## op++;					\
-	err;								\
-})
-
-#define call_void_vb_qop(vb, op, args...)				\
-({									\
-	log_vb_qop(vb, op);						\
-	if ((vb)->vb2_queue->ops->op)					\
-		(vb)->vb2_queue->ops->op(args);				\
-	(vb)->cnt_ ## op++;						\
-})
-
-#else
-
-#define call_memop(vb, op, args...)					\
-	((vb)->vb2_queue->mem_ops->op ?					\
-		(vb)->vb2_queue->mem_ops->op(args) : 0)
-
-#define call_ptr_memop(vb, op, args...)					\
-	((vb)->vb2_queue->mem_ops->op ?					\
-		(vb)->vb2_queue->mem_ops->op(args) : NULL)
-
-#define call_void_memop(vb, op, args...)				\
-	do {								\
-		if ((vb)->vb2_queue->mem_ops->op)			\
-			(vb)->vb2_queue->mem_ops->op(args);		\
-	} while (0)
-
-#define call_qop(q, op, args...)					\
-	((q)->ops->op ? (q)->ops->op(args) : 0)
-
-#define call_void_qop(q, op, args...)					\
-	do {								\
-		if ((q)->ops->op)					\
-			(q)->ops->op(args);				\
-	} while (0)
-
-#define call_vb_qop(vb, op, args...)					\
-	((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0)
-
-#define call_void_vb_qop(vb, op, args...)				\
-	do {								\
-		if ((vb)->vb2_queue->ops->op)				\
-			(vb)->vb2_queue->ops->op(args);			\
-	} while (0)
-
-#endif
-
-#define call_bufop(q, op, args...)					\
-({									\
-	int ret = 0;							\
-	if (q && q->buf_ops && q->buf_ops->op)				\
-		ret = q->buf_ops->op(args);				\
-	ret;								\
-})
-
-bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
-int vb2_verify_memory_type(struct vb2_queue *q,
-		enum vb2_memory memory, unsigned int type);
-#endif /* _MEDIA_VIDEOBUF2_INTERNAL_H */
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index ea5ab37..de5c108 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -31,7 +31,14 @@
 
 #include <media/videobuf2-v4l2.h>
 
-#include "videobuf2-internal.h"
+static int debug;
+module_param(debug, int, 0644);
+
+#define dprintk(level, fmt, arg...)					      \
+	do {								      \
+		if (debug >= level)					      \
+			pr_info("vb2-v4l2: %s: " fmt, __func__, ## arg); \
+	} while (0)
 
 /* Flags that are set by the vb2 core */
 #define V4L2_BUFFER_MASK_FLAGS	(V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
@@ -728,9 +735,6 @@ int vb2_queue_init(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_queue_init);
 
-static int __vb2_init_fileio(struct vb2_queue *q, int read);
-static int __vb2_cleanup_fileio(struct vb2_queue *q);
-
 /**
  * vb2_queue_release() - stop streaming, release the queue and free memory
  * @q:		videobuf2 queue
@@ -741,110 +745,11 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q);
  */
 void vb2_queue_release(struct vb2_queue *q)
 {
-	__vb2_cleanup_fileio(q);
 	vb2_core_queue_release(q);
 }
 EXPORT_SYMBOL_GPL(vb2_queue_release);
 
 /**
- * vb2_core_poll() - implements poll userspace operation
- * @q:		videobuf2 queue
- * @file:	file argument passed to the poll file operation handler
- * @wait:	wait argument passed to the poll file operation handler
- *
- * This function implements poll file operation handler for a driver.
- * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
- * be informed that the file descriptor of a video device is available for
- * reading.
- * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
- * will be reported as available for writing.
- *
- * The return values from this function are intended to be directly returned
- * from poll handler in driver.
- */
-unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
-		poll_table *wait)
-{
-	unsigned long req_events = poll_requested_events(wait);
-	struct vb2_buffer *vb = NULL;
-	unsigned long flags;
-
-	if (!q->is_output && !(req_events & (POLLIN | POLLRDNORM)))
-		return 0;
-	if (q->is_output && !(req_events & (POLLOUT | POLLWRNORM)))
-		return 0;
-
-	/*
-	 * Start file I/O emulator only if streaming API has not been used yet.
-	 */
-	if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) {
-		if (!q->is_output && (q->io_modes & VB2_READ) &&
-				(req_events & (POLLIN | POLLRDNORM))) {
-			if (__vb2_init_fileio(q, 1))
-				return POLLERR;
-		}
-		if (q->is_output && (q->io_modes & VB2_WRITE) &&
-				(req_events & (POLLOUT | POLLWRNORM))) {
-			if (__vb2_init_fileio(q, 0))
-				return POLLERR;
-			/*
-			 * Write to OUTPUT queue can be done immediately.
-			 */
-			return POLLOUT | POLLWRNORM;
-		}
-	}
-
-	/*
-	 * There is nothing to wait for if the queue isn't streaming, or if the
-	 * error flag is set.
-	 */
-	if (!vb2_is_streaming(q) || q->error)
-		return POLLERR;
-	/*
-	 * For compatibility with vb1: if QBUF hasn't been called yet, then
-	 * return POLLERR as well. This only affects capture queues, output
-	 * queues will always initialize waiting_for_buffers to false.
-	 */
-	if (q->waiting_for_buffers)
-		return POLLERR;
-
-	/*
-	 * For output streams you can write as long as there are fewer buffers
-	 * queued than there are buffers available.
-	 */
-	if (q->is_output && q->queued_count < q->num_buffers)
-		return POLLOUT | POLLWRNORM;
-
-	if (list_empty(&q->done_list)) {
-		/*
-		 * If the last buffer was dequeued from a capture queue,
-		 * return immediately. DQBUF will return -EPIPE.
-		 */
-		if (q->last_buffer_dequeued)
-			return POLLIN | POLLRDNORM;
-
-		poll_wait(file, &q->done_wq, wait);
-	}
-
-	/*
-	 * Take first buffer available for dequeuing.
-	 */
-	spin_lock_irqsave(&q->done_lock, flags);
-	if (!list_empty(&q->done_list))
-		vb = list_first_entry(&q->done_list, struct vb2_buffer,
-					done_entry);
-	spin_unlock_irqrestore(&q->done_lock, flags);
-
-	if (vb && (vb->state == VB2_BUF_STATE_DONE
-			|| vb->state == VB2_BUF_STATE_ERROR)) {
-		return (q->is_output) ?
-				POLLOUT | POLLWRNORM :
-				POLLIN | POLLRDNORM;
-	}
-	return 0;
-}
-
-/**
  * vb2_poll() - implements poll userspace operation
  * @q:		videobuf2 queue
  * @file:	file argument passed to the poll file operation handler
@@ -882,534 +787,6 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 }
 EXPORT_SYMBOL_GPL(vb2_poll);
 
-static void vb2_get_timestamp(struct timeval *tv)
-{
-	struct timespec ts;
-
-	ktime_get_ts(&ts);
-	tv->tv_sec = ts.tv_sec;
-	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
-}
-
-/**
- * struct vb2_fileio_buf - buffer context used by file io emulator
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. This structure is used for
- * tracking context related to the buffers.
- */
-struct vb2_fileio_buf {
-	void *vaddr;
-	unsigned int size;
-	unsigned int pos;
-	unsigned int queued:1;
-};
-
-/**
- * struct vb2_fileio_data - queue context used by file io emulator
- *
- * @cur_index:	the index of the buffer currently being read from or
- *		written to. If equal to q->num_buffers then a new buffer
- *		must be dequeued.
- * @initial_index: in the read() case all buffers are queued up immediately
- *		in __vb2_init_fileio() and __vb2_perform_fileio() just cycles
- *		buffers. However, in the write() case no buffers are initially
- *		queued, instead whenever a buffer is full it is queued up by
- *		__vb2_perform_fileio(). Only once all available buffers have
- *		been queued up will __vb2_perform_fileio() start to dequeue
- *		buffers. This means that initially __vb2_perform_fileio()
- *		needs to know what buffer index to use when it is queuing up
- *		the buffers for the first time. That initial index is stored
- *		in this field. Once it is equal to q->num_buffers all
- *		available buffers have been queued and __vb2_perform_fileio()
- *		should start the normal dequeue/queue cycle.
- *
- * vb2 provides a compatibility layer and emulator of file io (read and
- * write) calls on top of streaming API. For proper operation it required
- * this structure to save the driver state between each call of the read
- * or write function.
- */
-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;
-	unsigned int q_count;
-	unsigned int dq_count;
-	unsigned read_once:1;
-	unsigned write_immediately:1;
-};
-
-/**
- * __vb2_init_fileio() - initialize file io emulator
- * @q:		videobuf2 queue
- * @read:	mode selector (1 means read, 0 means write)
- */
-static int __vb2_init_fileio(struct vb2_queue *q, int read)
-{
-	struct vb2_fileio_data *fileio;
-	int i, ret;
-	unsigned int count = 0;
-
-	/*
-	 * Sanity check
-	 */
-	if (WARN_ON((read && !(q->io_modes & VB2_READ)) ||
-		    (!read && !(q->io_modes & VB2_WRITE))))
-		return -EINVAL;
-
-	/*
-	 * Check if device supports mapping buffers to kernel virtual space.
-	 */
-	if (!q->mem_ops->vaddr)
-		return -EBUSY;
-
-	/*
-	 * Check if streaming api has not been already activated.
-	 */
-	if (q->streaming || q->num_buffers > 0)
-		return -EBUSY;
-
-	/*
-	 * Start with count 1, driver can increase it in queue_setup()
-	 */
-	count = 1;
-
-	dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",
-		(read) ? "read" : "write", count, q->fileio_read_once,
-		q->fileio_write_immediately);
-
-	fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
-	if (fileio == NULL)
-		return -ENOMEM;
-
-	fileio->b = kzalloc(q->buf_struct_size, GFP_KERNEL);
-	if (fileio->b == NULL)
-		return -ENOMEM;
-
-	fileio->read_once = q->fileio_read_once;
-	fileio->write_immediately = q->fileio_write_immediately;
-
-	/*
-	 * Request buffers and use MMAP type to force driver
-	 * to allocate buffers by itself.
-	 */
-	fileio->count = count;
-	fileio->memory = VB2_MEMORY_MMAP;
-	fileio->type = q->type;
-	q->fileio = fileio;
-	ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count);
-	if (ret)
-		goto err_kfree;
-
-	/*
-	 * Check if plane_count is correct
-	 * (multiplane buffers are not supported).
-	 */
-	if (q->bufs[0]->num_planes != 1) {
-		ret = -EBUSY;
-		goto err_reqbufs;
-	}
-
-	/*
-	 * Get kernel address of each buffer.
-	 */
-	for (i = 0; i < q->num_buffers; i++) {
-		fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
-		if (fileio->bufs[i].vaddr == NULL) {
-			ret = -EINVAL;
-			goto err_reqbufs;
-		}
-		fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
-	}
-
-	/*
-	 * Read mode requires pre queuing of all buffers.
-	 */
-	if (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);
-			if (ret)
-				goto err_reqbufs;
-			fileio->bufs[i].queued = 1;
-		}
-		/*
-		 * All buffers have been queued, so mark that by setting
-		 * initial_index to q->num_buffers
-		 */
-		fileio->initial_index = q->num_buffers;
-		fileio->cur_index = q->num_buffers;
-	}
-
-	/*
-	 * Start streaming.
-	 */
-	ret = vb2_core_streamon(q, q->type);
-	if (ret)
-		goto err_reqbufs;
-
-	return ret;
-
-err_reqbufs:
-	fileio->count = 0;
-	vb2_core_reqbufs(q, fileio->memory, &fileio->count);
-
-err_kfree:
-	q->fileio = NULL;
-	kfree(fileio);
-	return ret;
-}
-
-/**
- * __vb2_cleanup_fileio() - free resourced used by file io emulator
- * @q:		videobuf2 queue
- */
-static int __vb2_cleanup_fileio(struct vb2_queue *q)
-{
-	struct vb2_fileio_data *fileio = q->fileio;
-
-	if (fileio) {
-		vb2_core_streamoff(q, q->type);
-		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");
-	}
-	return 0;
-}
-
-/**
- * __vb2_perform_fileio() - perform a single file io (read or write) operation
- * @q:		videobuf2 queue
- * @data:	pointed to target userspace buffer
- * @count:	number of bytes to read or write
- * @ppos:	file handle position tracking pointer
- * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
- * @read:	access mode selector (1 means read, 0 means write)
- */
-static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
-		loff_t *ppos, int nonblock, int read)
-{
-	struct vb2_fileio_data *fileio;
-	struct vb2_fileio_buf *buf;
-	bool is_multiplanar = q->is_multiplanar;
-	/*
-	 * When using write() to write data to an output video node the vb2 core
-	 * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody
-	 * else is able to provide this information with the write() operation.
-	 */
-	bool set_timestamp = !read && q->set_timestamp;
-	int ret, index;
-
-	dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",
-		read ? "read" : "write", (long)*ppos, count,
-		nonblock ? "non" : "");
-
-	if (!data)
-		return -EINVAL;
-
-	/*
-	 * Initialize emulator on first call.
-	 */
-	if (!vb2_fileio_is_active(q)) {
-		ret = __vb2_init_fileio(q, read);
-		dprintk(3, "vb2_init_fileio result: %d\n", ret);
-		if (ret)
-			return ret;
-	}
-	fileio = q->fileio;
-
-	/*
-	 * Check if we need to dequeue the buffer.
-	 */
-	index = fileio->cur_index;
-	if (index >= q->num_buffers) {
-		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;
-		ret = vb2_core_dqbuf(q, b, nonblock);
-		dprintk(5, "vb2_dqbuf result: %d\n", ret);
-		if (ret)
-			return ret;
-		fileio->dq_count += 1;
-
-		fileio->cur_index = index = b->index;
-		buf = &fileio->bufs[index];
-
-		/*
-		 * Get number of bytes filled by the driver
-		 */
-		buf->pos = 0;
-		buf->queued = 0;
-		buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
-				 : vb2_plane_size(q->bufs[index], 0);
-		/* Compensate for data_offset on read in the multiplanar case. */
-		if (is_multiplanar && read &&
-				b->planes[0].data_offset < buf->size) {
-			buf->pos = b->planes[0].data_offset;
-			buf->size -= buf->pos;
-		}
-	} else {
-		buf = &fileio->bufs[index];
-	}
-
-	/*
-	 * Limit count on last few bytes of the buffer.
-	 */
-	if (buf->pos + count > buf->size) {
-		count = buf->size - buf->pos;
-		dprintk(5, "reducing read count: %zd\n", count);
-	}
-
-	/*
-	 * Transfer data to userspace.
-	 */
-	dprintk(3, "copying %zd bytes - buffer %d, offset %u\n",
-		count, index, buf->pos);
-	if (read)
-		ret = copy_to_user(data, buf->vaddr + buf->pos, count);
-	else
-		ret = copy_from_user(buf->vaddr + buf->pos, data, count);
-	if (ret) {
-		dprintk(3, "error copying data\n");
-		return -EFAULT;
-	}
-
-	/*
-	 * Update counters.
-	 */
-	buf->pos += count;
-	*ppos += count;
-
-	/*
-	 * Queue next buffer if required.
-	 */
-	if (buf->pos == buf->size || (!read && fileio->write_immediately)) {
-		struct vb2_buffer *b = fileio->b;
-
-		/*
-		 * Check if this is the last buffer to read.
-		 */
-		if (read && fileio->read_once && fileio->dq_count == 1) {
-			dprintk(3, "read limit reached\n");
-			return __vb2_cleanup_fileio(q);
-		}
-
-		/*
-		 * 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 (set_timestamp)
-			vb2_get_timestamp(&b->timestamp);
-		ret = vb2_core_qbuf(q, index, b);
-		dprintk(5, "vb2_dbuf result: %d\n", ret);
-		if (ret)
-			return ret;
-
-		/*
-		 * Buffer has been queued, update the status
-		 */
-		buf->pos = 0;
-		buf->queued = 1;
-		buf->size = vb2_plane_size(q->bufs[index], 0);
-		fileio->q_count += 1;
-		/*
-		 * If we are queuing up buffers for the first time, then
-		 * increase initial_index by one.
-		 */
-		if (fileio->initial_index < q->num_buffers)
-			fileio->initial_index++;
-		/*
-		 * The next buffer to use is either a buffer that's going to be
-		 * queued for the first time (initial_index < q->num_buffers)
-		 * or it is equal to q->num_buffers, meaning that the next
-		 * time we need to dequeue a buffer since we've now queued up
-		 * all the 'first time' buffers.
-		 */
-		fileio->cur_index = fileio->initial_index;
-	}
-
-	/*
-	 * Return proper number of bytes processed.
-	 */
-	if (ret == 0)
-		ret = count;
-	return ret;
-}
-
-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
-		loff_t *ppos, int nonblocking)
-{
-	return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
-}
-EXPORT_SYMBOL_GPL(vb2_read);
-
-size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
-		loff_t *ppos, int nonblocking)
-{
-	return __vb2_perform_fileio(q, (char __user *) data, count,
-							ppos, nonblocking, 0);
-}
-EXPORT_SYMBOL_GPL(vb2_write);
-
-struct vb2_threadio_data {
-	struct task_struct *thread;
-	vb2_thread_fnc fnc;
-	void *priv;
-	bool stop;
-};
-
-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 set_timestamp = false;
-	int prequeue = 0;
-	int index = 0;
-	int ret = 0;
-
-	if (q->is_output) {
-		prequeue = q->num_buffers;
-		set_timestamp = q->set_timestamp;
-	}
-
-	set_freezable();
-
-	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++;
-			prequeue--;
-		} else {
-			call_void_qop(q, wait_finish, q);
-			if (!threadio->stop)
-				ret = vb2_core_dqbuf(q, b, 0);
-			call_void_qop(q, wait_prepare, q);
-			dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
-		}
-		if (ret || threadio->stop)
-			break;
-		try_to_freeze();
-
-		vb = q->bufs[b->index];
-		if (b->state == VB2_BUF_STATE_DONE)
-			if (threadio->fnc(vb, threadio->priv))
-				break;
-		call_void_qop(q, wait_finish, q);
-		if (set_timestamp)
-			vb2_get_timestamp(&b->timestamp);
-		if (!threadio->stop)
-			ret = vb2_core_qbuf(q, b->index, b);
-		call_void_qop(q, wait_prepare, q);
-		if (ret || threadio->stop)
-			break;
-	}
-
-	/* Hmm, linux becomes *very* unhappy without this ... */
-	while (!kthread_should_stop()) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-	}
-	return 0;
-}
-
-/*
- * This function should not be used for anything else but the videobuf2-dvb
- * support. If you think you have another good use-case for this, then please
- * contact the linux-media mailinglist first.
- */
-int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
-		     const char *thread_name)
-{
-	struct vb2_threadio_data *threadio;
-	int ret = 0;
-
-	if (q->threadio)
-		return -EBUSY;
-	if (vb2_is_busy(q))
-		return -EBUSY;
-	if (WARN_ON(q->fileio))
-		return -EBUSY;
-
-	threadio = kzalloc(sizeof(*threadio), GFP_KERNEL);
-	if (threadio == NULL)
-		return -ENOMEM;
-	threadio->fnc = fnc;
-	threadio->priv = priv;
-
-	ret = __vb2_init_fileio(q, !q->is_output);
-	dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
-	if (ret)
-		goto nomem;
-	q->threadio = threadio;
-	threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name);
-	if (IS_ERR(threadio->thread)) {
-		ret = PTR_ERR(threadio->thread);
-		threadio->thread = NULL;
-		goto nothread;
-	}
-	return 0;
-
-nothread:
-	__vb2_cleanup_fileio(q);
-nomem:
-	kfree(threadio);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(vb2_thread_start);
-
-int vb2_thread_stop(struct vb2_queue *q)
-{
-	struct vb2_threadio_data *threadio = q->threadio;
-	int err;
-
-	if (threadio == NULL)
-		return 0;
-	threadio->stop = true;
-	/* Wake up all pending sleeps in the thread */
-	vb2_queue_error(q);
-	err = kthread_stop(threadio->thread);
-	__vb2_cleanup_fileio(q);
-	threadio->thread = NULL;
-	kfree(threadio);
-	q->threadio = NULL;
-	return err;
-}
-EXPORT_SYMBOL_GPL(vb2_thread_stop);
-
 /*
  * The following functions are not part of the vb2 core API, but are helper
  * functions that plug into struct v4l2_ioctl_ops, struct v4l2_file_operations
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 6ef7da7..683f26c 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -535,6 +535,42 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
 				    unsigned long pgoff,
 				    unsigned long flags);
 #endif
+unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
+		poll_table *wait);
+size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
+		loff_t *ppos, int nonblock);
+size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
+		loff_t *ppos, int nonblock);
+
+/*
+ * vb2_thread_fnc - callback function for use with vb2_thread
+ *
+ * This is called whenever a buffer is dequeued in the thread.
+ */
+typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv);
+
+/**
+ * vb2_thread_start() - start a thread for the given queue.
+ * @q:		videobuf queue
+ * @fnc:	callback function
+ * @priv:	priv pointer passed to the callback function
+ * @thread_name:the name of the thread. This will be prefixed with "vb2-".
+ *
+ * This starts a thread that will queue and dequeue until an error occurs
+ * or @vb2_thread_stop is called.
+ *
+ * This function should not be used for anything else but the videobuf2-dvb
+ * support. If you think you have another good use-case for this, then please
+ * contact the linux-media mailinglist first.
+ */
+int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
+		     const char *thread_name);
+
+/**
+ * vb2_thread_stop() - stop the thread for the given queue.
+ * @q:		videobuf queue
+ */
+int vb2_thread_stop(struct vb2_queue *q);
 
 /**
  * vb2_is_streaming() - return streaming status of the queue
@@ -639,4 +675,11 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
 	q->last_buffer_dequeued = false;
 }
 
+/*
+ * The following functions are not part of the vb2 core API, but are useful
+ * functions for videobuf2-*.
+ */
+bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
+int vb2_verify_memory_type(struct vb2_queue *q,
+		enum vb2_memory memory, unsigned int type);
 #endif /* _MEDIA_VIDEOBUF2_CORE_H */
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 110062e..3cc836f 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -63,42 +63,8 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
 
 int __must_check vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
-
-unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
-size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
-		loff_t *ppos, int nonblock);
-size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
-		loff_t *ppos, int nonblock);
-
-/*
- * vb2_thread_fnc - callback function for use with vb2_thread
- *
- * This is called whenever a buffer is dequeued in the thread.
- */
-typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv);
-
-/**
- * vb2_thread_start() - start a thread for the given queue.
- * @q:		videobuf queue
- * @fnc:	callback function
- * @priv:	priv pointer passed to the callback function
- * @thread_name:the name of the thread. This will be prefixed with "vb2-".
- *
- * This starts a thread that will queue and dequeue until an error occurs
- * or @vb2_thread_stop is called.
- *
- * This function should not be used for anything else but the videobuf2-dvb
- * support. If you think you have another good use-case for this, then please
- * contact the linux-media mailinglist first.
- */
-int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
-		     const char *thread_name);
-
-/**
- * vb2_thread_stop() - stop the thread for the given queue.
- * @q:		videobuf queue
- */
-int vb2_thread_stop(struct vb2_queue *q);
+unsigned int vb2_poll(struct vb2_queue *q, struct file *file,
+		poll_table *wait);
 
 /*
  * The following functions are not part of the vb2 core API, but are simple
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue
  2015-10-16  6:27 ` [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue Junghak Sung
@ 2015-10-16 12:04   ` Sakari Ailus
  0 siblings, 0 replies; 13+ messages in thread
From: Sakari Ailus @ 2015-10-16 12:04 UTC (permalink / raw)
  To: Junghak Sung
  Cc: linux-media, mchehab, hverkuil, laurent.pinchart, pawel,
	inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon

Hi Junghak,

On Fri, Oct 16, 2015 at 03:27:39PM +0900, Junghak Sung wrote:
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index f1e7169..6ef7da7 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -431,6 +431,7 @@ struct vb2_buf_ops {
>   *		called since poll() needs to return POLLERR in that situation.
>   * @is_multiplanar: set if buffer type is multiplanar
>   * @is_output:	set if buffer type is output
> + * @copy_timestamp: set if vb2-core should set timestamps
>   * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
>   *		last decoded buffer was already dequeued. Set for capture queues
>   *		when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
> @@ -480,6 +481,7 @@ struct vb2_queue {
>  	unsigned int			waiting_for_buffers:1;
>  	unsigned int			is_multiplanar:1;
>  	unsigned int			is_output:1;
> +	unsigned int			set_timestamp:1;
>  	unsigned int			last_buffer_dequeued:1;
>  
>  	struct vb2_fileio_data		*fileio;

V4L2 buffers use struct timeval with µs precision. Generally speaking, if us
precision is preferred elsewhere, the non-V4l2 specific portion could use
that. The conversion could be done in the videobuf2-v4l2.c.

This could be also changed later on if needed, but please use struct
timespec in new APIs instead of struct timeval. V4L2 events use it, for
instance.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC PATCH v7] Refactoring Videobuf2 for common use
  2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
                   ` (6 preceding siblings ...)
  2015-10-16  6:27 ` [RFC PATCH v7 7/7] media: videobuf2: Move vb2_fileio_data and vb2_thread to core part Junghak Sung
@ 2015-10-19  7:56 ` Hans Verkuil
  7 siblings, 0 replies; 13+ messages in thread
From: Hans Verkuil @ 2015-10-19  7:56 UTC (permalink / raw)
  To: Junghak Sung, linux-media, mchehab, laurent.pinchart,
	sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon

On 10/16/2015 08:27 AM, Junghak Sung wrote:
> Hello everybody,
> 
> This is the 7th round for refactoring Videobuf2(a.k.a VB2).
> The purpose of this patch series is to separate existing VB2 framework
> into core part and V4L2 specific part. So that not only V4L2 but also other
> frameworks can use them to manage buffer and utilize queue.
> 
> Why do we try to make the VB2 framework to be common?
> 
> As you may know, current DVB framework uses ringbuffer mechanism to demux
> MPEG-2 TS data and pass it to userspace. However, this mechanism requires
> extra memory copy because DVB framework provides only read() system call for
> application - read() system call copies the kernel data to user-space buffer.
> So if we can use VB2 framework which supports streaming I/O and buffer
> sharing mechanism, then we could enhance existing DVB framework by removing
> the extra memory copy - with VB2 framework, application can access the kernel
> data directly through mmap system call.
> 
> We have a plan for this work as follows:
> 1. Separate existing VB2 framework into three parts - VB2 core, VB2 v4l2.
>    Of course, this change will not affect other v4l2-based
>    device drivers. This patch series corresponds to this step.
> 
> 2. Add and implement new APIs for DVB streaming I/O.
>    We can remove unnecessary memory copy between kernel-space and user-space
>    by using these new APIs. However, we leaves legacy interfaces as-is
>    for backward compatibility.
> 
> This patch series is the first step for it.
> The previous version of this patch series can be found at belows.
> 
> [1] RFC PATCH v1 - http://www.spinics.net/lists/linux-media/msg90688.html
> [2] RFC PATCH v2 - http://www.spinics.net/lists/linux-media/msg92130.html
> [3] RFC PATCH v3 - http://www.spinics.net/lists/linux-media/msg92953.html
> [4] RFC PATCH v4 - http://www.spinics.net/lists/linux-media/msg93421.html
> [5] RFC PATCH v5 - http://www.spinics.net/lists/linux-media/msg93810.html
> [6] RFC PATCH v6 - http://www.spinics.net/lists/linux-media/msg94112.html
> 
> 
> Changes since v6
> 1. Based on v6
> Patch series v6 was accepted (but, not merged yet). So, this series v7 is
> based on v6.
> 
> 2. Fix a warning on fimc-lite.c
> In patch series v6, a warning is reported by kbuild robot. So, this warning
> is fixed.

Fixed already in my pull request.

> 3. Move things related with vb2_thread to core part
> In order to move vb2_thread to vb2-core, these changes below would precede it.
>  - timestamp of vb2_v4l2_buffer is moved to vb2_buffer for common use.
>  - A flag - which is for checking if vb2-core should set timestamps or not - is
>   added as a member of vb2_queue.
>  - Replace v4l2-stuffs with common things in vb2_fileio_data and vb2_thread.

This looks good. However, I'm postponing merging this until after the upcoming
media workshop. The reasons for that have to do with timestamp handling and y2038
(so we probably want to use a u64 timestamp in vb2 core and use ktime_get_ns() to
fill it in), and they have to do with the poll() function which has some problems
in the output case.

I do not expect any major changes to this patch series, but I'm not quite ready
to merge it at this moment.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer
  2015-10-16  6:27 ` [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer Junghak Sung
@ 2015-10-29  2:27   ` Hans Verkuil
  2015-10-29  2:34     ` Hans Verkuil
  0 siblings, 1 reply; 13+ messages in thread
From: Hans Verkuil @ 2015-10-29  2:27 UTC (permalink / raw)
  To: Junghak Sung, linux-media, mchehab, laurent.pinchart,
	sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon



On 10/16/2015 15:27, Junghak Sung wrote:
> Move timestamp from struct vb2_v4l2_buffer to struct vb2_buffer
> for common use. This patch includes all device drivers' changes
> related with this restructuring.
> 
> Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
> Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
> Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> ---
>  drivers/input/touchscreen/sur40.c                  |    2 +-
>  drivers/media/dvb-frontends/rtl2832_sdr.c          |    2 +-
>  drivers/media/pci/cobalt/cobalt-irq.c              |    2 +-
>  drivers/media/pci/cx23885/cx23885-core.c           |    2 +-
>  drivers/media/pci/cx23885/cx23885-video.c          |    2 +-
>  drivers/media/pci/cx25821/cx25821-video.c          |    2 +-
>  drivers/media/pci/cx88/cx88-core.c                 |    2 +-
>  drivers/media/pci/dt3155/dt3155.c                  |    2 +-
>  drivers/media/pci/netup_unidvb/netup_unidvb_core.c |    2 +-
>  drivers/media/pci/saa7134/saa7134-core.c           |    2 +-
>  drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c     |    4 ++--
>  drivers/media/pci/solo6x10/solo6x10-v4l2.c         |    2 +-
>  drivers/media/pci/sta2x11/sta2x11_vip.c            |    2 +-
>  drivers/media/pci/tw68/tw68-video.c                |    2 +-
>  drivers/media/platform/am437x/am437x-vpfe.c        |    2 +-
>  drivers/media/platform/blackfin/bfin_capture.c     |    2 +-
>  drivers/media/platform/coda/coda-bit.c             |    6 +++---
>  drivers/media/platform/davinci/vpbe_display.c      |    2 +-
>  drivers/media/platform/davinci/vpif_capture.c      |    2 +-
>  drivers/media/platform/davinci/vpif_display.c      |    4 ++--
>  drivers/media/platform/exynos-gsc/gsc-m2m.c        |    4 ++--
>  drivers/media/platform/exynos4-is/fimc-capture.c   |    2 +-
>  drivers/media/platform/exynos4-is/fimc-isp-video.c |    2 +-
>  drivers/media/platform/exynos4-is/fimc-lite.c      |    2 +-
>  drivers/media/platform/exynos4-is/fimc-m2m.c       |    2 +-
>  drivers/media/platform/m2m-deinterlace.c           |    2 +-
>  drivers/media/platform/marvell-ccic/mcam-core.c    |    2 +-
>  drivers/media/platform/mx2_emmaprp.c               |    2 +-
>  drivers/media/platform/omap3isp/ispvideo.c         |    2 +-
>  drivers/media/platform/rcar_jpu.c                  |    2 +-
>  drivers/media/platform/s3c-camif/camif-capture.c   |    2 +-
>  drivers/media/platform/s5p-g2d/g2d.c               |    2 +-
>  drivers/media/platform/s5p-jpeg/jpeg-core.c        |    4 ++--
>  drivers/media/platform/s5p-mfc/s5p_mfc.c           |    4 ++--
>  drivers/media/platform/sh_veu.c                    |    2 +-
>  drivers/media/platform/sh_vou.c                    |    2 +-
>  drivers/media/platform/soc_camera/atmel-isi.c      |    2 +-
>  drivers/media/platform/soc_camera/mx2_camera.c     |    2 +-
>  drivers/media/platform/soc_camera/mx3_camera.c     |    2 +-
>  drivers/media/platform/soc_camera/rcar_vin.c       |    2 +-
>  .../platform/soc_camera/sh_mobile_ceu_camera.c     |    2 +-
>  drivers/media/platform/sti/bdisp/bdisp-v4l2.c      |    4 ++--
>  drivers/media/platform/ti-vpe/vpe.c                |    2 +-
>  drivers/media/platform/vim2m.c                     |    2 +-
>  drivers/media/platform/vivid/vivid-kthread-cap.c   |    6 +++---
>  drivers/media/platform/vivid/vivid-kthread-out.c   |    8 ++++----
>  drivers/media/platform/vivid/vivid-sdr-cap.c       |    5 +++--
>  drivers/media/platform/vivid/vivid-vbi-cap.c       |    8 ++++----
>  drivers/media/platform/vsp1/vsp1_video.c           |    2 +-
>  drivers/media/platform/xilinx/xilinx-dma.c         |    2 +-
>  drivers/media/usb/airspy/airspy.c                  |    2 +-
>  drivers/media/usb/au0828/au0828-video.c            |    2 +-
>  drivers/media/usb/em28xx/em28xx-video.c            |    2 +-
>  drivers/media/usb/go7007/go7007-driver.c           |    2 +-
>  drivers/media/usb/hackrf/hackrf.c                  |    2 +-
>  drivers/media/usb/pwc/pwc-if.c                     |    2 +-
>  drivers/media/usb/s2255/s2255drv.c                 |    2 +-
>  drivers/media/usb/stk1160/stk1160-video.c          |    2 +-
>  drivers/media/usb/usbtv/usbtv-video.c              |    2 +-
>  drivers/media/usb/uvc/uvc_video.c                  |   12 ++++++------
>  drivers/media/v4l2-core/videobuf2-v4l2.c           |    8 ++++----
>  drivers/staging/media/davinci_vpfe/vpfe_video.c    |    2 +-
>  drivers/staging/media/omap4iss/iss_video.c         |    2 +-
>  drivers/usb/gadget/function/uvc_queue.c            |    2 +-
>  include/media/videobuf2-core.h                     |    2 ++
>  include/media/videobuf2-v4l2.h                     |    2 --
>  include/trace/events/v4l2.h                        |    2 +-
>  include/trace/events/vb2.h                         |    7 +++++--
>  68 files changed, 98 insertions(+), 94 deletions(-)
> 

<snip>

> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index 647ebfe..f1e7169 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -211,6 +211,7 @@ struct vb2_queue;
>   * @num_planes:		number of planes in the buffer
>   *			on an internal driver queue
>   * @planes:		private per-plane information; do not change
> + * @timestamp:		frame timestamp
>   */
>  struct vb2_buffer {
>  	struct vb2_queue	*vb2_queue;
> @@ -219,6 +220,7 @@ struct vb2_buffer {
>  	unsigned int		memory;
>  	unsigned int		num_planes;
>  	struct vb2_plane	planes[VB2_MAX_PLANES];
> +	struct timeval		timestamp;

This should become a u64 timestamp that's filled using ktime_get_ns().
In the v4l2 code this should be converted to a timeval when v4l2_buffer
is filled. Using ktime_get_ns() is the recommended method to do timestamping
without having to worry about the y2038 problem and this should be used in
vb2 core.

v4l2_set_timestamp should be updated accordingly.

Regards,

	Hans

>  
>  	/* private: internal use only
>  	 *
> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
> index 5abab1e..110062e 100644
> --- a/include/media/videobuf2-v4l2.h
> +++ b/include/media/videobuf2-v4l2.h
> @@ -28,7 +28,6 @@
>   * @vb2_buf:	video buffer 2
>   * @flags:	buffer informational flags
>   * @field:	enum v4l2_field; field order of the image in the buffer
> - * @timestamp:	frame timestamp
>   * @timecode:	frame timecode
>   * @sequence:	sequence count of this frame
>   * Should contain enough information to be able to cover all the fields
> @@ -39,7 +38,6 @@ struct vb2_v4l2_buffer {
>  
>  	__u32			flags;
>  	__u32			field;
> -	struct timeval		timestamp;
>  	struct v4l2_timecode	timecode;
>  	__u32			sequence;
>  };
> diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
> index 04ef89b..5b57d0a 100644
> --- a/include/trace/events/v4l2.h
> +++ b/include/trace/events/v4l2.h
> @@ -204,7 +204,7 @@ DECLARE_EVENT_CLASS(vb2_v4l2_event_class,
>  		__entry->minor = owner ? owner->vdev->minor : -1;
>  		__entry->flags = vbuf->flags;
>  		__entry->field = vbuf->field;
> -		__entry->timestamp = timeval_to_ns(&vbuf->timestamp);
> +		__entry->timestamp = timeval_to_ns(&vb->timestamp);
>  		__entry->timecode_type = vbuf->timecode.type;
>  		__entry->timecode_flags = vbuf->timecode.flags;
>  		__entry->timecode_frames = vbuf->timecode.frames;
> diff --git a/include/trace/events/vb2.h b/include/trace/events/vb2.h
> index bfeceeb..35c1589 100644
> --- a/include/trace/events/vb2.h
> +++ b/include/trace/events/vb2.h
> @@ -18,6 +18,7 @@ DECLARE_EVENT_CLASS(vb2_event_class,
>  		__field(u32, index)
>  		__field(u32, type)
>  		__field(u32, bytesused)
> +		__field(s64, timestamp)
>  	),
>  
>  	TP_fast_assign(
> @@ -28,14 +29,16 @@ DECLARE_EVENT_CLASS(vb2_event_class,
>  		__entry->index = vb->index;
>  		__entry->type = vb->type;
>  		__entry->bytesused = vb->planes[0].bytesused;
> +		__entry->timestamp = timeval_to_ns(&vb->timestamp);
>  	),
>  
>  	TP_printk("owner = %p, queued = %u, owned_by_drv = %d, index = %u, "
> -		  "type = %u, bytesused = %u", __entry->owner,
> +		  "type = %u, bytesused = %u, timestamp = %llu", __entry->owner,
>  		  __entry->queued_count,
>  		  __entry->owned_by_drv_count,
>  		  __entry->index, __entry->type,
> -		  __entry->bytesused
> +		  __entry->bytesused,
> +		  __entry->timestamp
>  	)
>  )
>  
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread
  2015-10-16  6:27 ` [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread Junghak Sung
@ 2015-10-29  2:31   ` Hans Verkuil
  0 siblings, 0 replies; 13+ messages in thread
From: Hans Verkuil @ 2015-10-29  2:31 UTC (permalink / raw)
  To: Junghak Sung, linux-media, mchehab, laurent.pinchart,
	sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon

Hi Junghak,

On 10/16/2015 15:27, Junghak Sung wrote:
> Replace v4l2-stuffs with common things in struct vb2_fileio_data and
> vb2_thread().
> 
> Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
> Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
> Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> ---
>  drivers/media/v4l2-core/videobuf2-v4l2.c |  113 +++++++++++++++---------------
>  1 file changed, 58 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
> index dabcb6d..ea5ab37 100644
> --- a/drivers/media/v4l2-core/videobuf2-v4l2.c
> +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
> @@ -882,6 +882,15 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
>  }
>  EXPORT_SYMBOL_GPL(vb2_poll);
>  
> +static void vb2_get_timestamp(struct timeval *tv)
> +{
> +	struct timespec ts;
> +
> +	ktime_get_ts(&ts);
> +	tv->tv_sec = ts.tv_sec;
> +	tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
> +}

This isn't necessary after we switch to u64 for the timestamp. We can just call ktime_get_ns() without
introducing a new function.

Regards,

	Hans

> +
>  /**
>   * struct vb2_fileio_buf - buffer context used by file io emulator
>   *
> @@ -921,9 +930,10 @@ struct vb2_fileio_buf {
>   * or write function.
>   */
>  struct vb2_fileio_data {
> -	struct v4l2_requestbuffers req;
> -	struct v4l2_plane p;
> -	struct v4l2_buffer b;
> +	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;
> @@ -976,6 +986,10 @@ 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)
> +		return -ENOMEM;
> +
>  	fileio->read_once = q->fileio_read_once;
>  	fileio->write_immediately = q->fileio_write_immediately;
>  
> @@ -983,11 +997,11 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
>  	 * Request buffers and use MMAP type to force driver
>  	 * to allocate buffers by itself.
>  	 */
> -	fileio->req.count = count;
> -	fileio->req.memory = VB2_MEMORY_MMAP;
> -	fileio->req.type = q->type;
> +	fileio->count = count;
> +	fileio->memory = VB2_MEMORY_MMAP;
> +	fileio->type = q->type;
>  	q->fileio = fileio;
> -	ret = vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
> +	ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count);
>  	if (ret)
>  		goto err_kfree;
>  
> @@ -1016,24 +1030,17 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
>  	 * Read mode requires pre queuing of all buffers.
>  	 */
>  	if (read) {
> -		bool is_multiplanar = q->is_multiplanar;
> -
>  		/*
>  		 * Queue all buffers.
>  		 */
>  		for (i = 0; i < q->num_buffers; i++) {
> -			struct v4l2_buffer *b = &fileio->b;
> +			struct vb2_buffer *b = fileio->b;
>  
> -			memset(b, 0, sizeof(*b));
> +			memset(b, 0, q->buf_struct_size);
>  			b->type = q->type;
> -			if (is_multiplanar) {
> -				memset(&fileio->p, 0, sizeof(fileio->p));
> -				b->m.planes = &fileio->p;
> -				b->length = 1;
> -			}
>  			b->memory = q->memory;
>  			b->index = i;
> -			ret = vb2_internal_qbuf(q, b);
> +			ret = vb2_core_qbuf(q, i, b);
>  			if (ret)
>  				goto err_reqbufs;
>  			fileio->bufs[i].queued = 1;
> @@ -1056,8 +1063,8 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
>  	return ret;
>  
>  err_reqbufs:
> -	fileio->req.count = 0;
> -	vb2_core_reqbufs(q, fileio->req.memory, &fileio->req.count);
> +	fileio->count = 0;
> +	vb2_core_reqbufs(q, fileio->memory, &fileio->count);
>  
>  err_kfree:
>  	q->fileio = NULL;
> @@ -1076,8 +1083,9 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q)
>  	if (fileio) {
>  		vb2_core_streamoff(q, q->type);
>  		q->fileio = NULL;
> -		fileio->req.count = 0;
> -		vb2_reqbufs(q, &fileio->req);
> +		fileio->count = 0;
> +		vb2_core_reqbufs(q, fileio->memory, &fileio->count);
> +		kfree(fileio->b);
>  		kfree(fileio);
>  		dprintk(3, "file io emulator closed\n");
>  	}
> @@ -1130,24 +1138,21 @@ 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;
> +
>  		/*
>  		 * Call vb2_dqbuf to get buffer back.
>  		 */
> -		memset(&fileio->b, 0, sizeof(fileio->b));
> -		fileio->b.type = q->type;
> -		fileio->b.memory = q->memory;
> -		if (is_multiplanar) {
> -			memset(&fileio->p, 0, sizeof(fileio->p));
> -			fileio->b.m.planes = &fileio->p;
> -			fileio->b.length = 1;
> -		}
> -		ret = vb2_internal_dqbuf(q, &fileio->b, nonblock);
> +		memset(b, 0, q->buf_struct_size);
> +		b->type = q->type;
> +		b->memory = q->memory;
> +		ret = vb2_core_dqbuf(q, b, nonblock);
>  		dprintk(5, "vb2_dqbuf result: %d\n", ret);
>  		if (ret)
>  			return ret;
>  		fileio->dq_count += 1;
>  
> -		fileio->cur_index = index = fileio->b.index;
> +		fileio->cur_index = index = b->index;
>  		buf = &fileio->bufs[index];
>  
>  		/*
> @@ -1159,8 +1164,8 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
>  				 : vb2_plane_size(q->bufs[index], 0);
>  		/* Compensate for data_offset on read in the multiplanar case. */
>  		if (is_multiplanar && read &&
> -		    fileio->b.m.planes[0].data_offset < buf->size) {
> -			buf->pos = fileio->b.m.planes[0].data_offset;
> +				b->planes[0].data_offset < buf->size) {
> +			buf->pos = b->planes[0].data_offset;
>  			buf->size -= buf->pos;
>  		}
>  	} else {
> @@ -1199,6 +1204,8 @@ 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;
> +
>  		/*
>  		 * Check if this is the last buffer to read.
>  		 */
> @@ -1210,20 +1217,15 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
>  		/*
>  		 * Call vb2_qbuf and give buffer to the driver.
>  		 */
> -		memset(&fileio->b, 0, sizeof(fileio->b));
> -		fileio->b.type = q->type;
> -		fileio->b.memory = q->memory;
> -		fileio->b.index = index;
> -		fileio->b.bytesused = buf->pos;
> -		if (is_multiplanar) {
> -			memset(&fileio->p, 0, sizeof(fileio->p));
> -			fileio->p.bytesused = buf->pos;
> -			fileio->b.m.planes = &fileio->p;
> -			fileio->b.length = 1;
> -		}
> +		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 (set_timestamp)
> -			v4l2_get_timestamp(&fileio->b.timestamp);
> -		ret = vb2_internal_qbuf(q, &fileio->b);
> +			vb2_get_timestamp(&b->timestamp);
> +		ret = vb2_core_qbuf(q, index, b);
>  		dprintk(5, "vb2_dbuf result: %d\n", ret);
>  		if (ret)
>  			return ret;
> @@ -1300,20 +1302,21 @@ 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(&fileio->b, 0, sizeof(fileio->b));
> -		fileio->b.type = q->type;
> -		fileio->b.memory = q->memory;
> +		memset(b, 0, q->buf_struct_size);
> +		b->type = q->type;
> +		b->memory = q->memory;
>  		if (prequeue) {
> -			fileio->b.index = index++;
> +			b->index = index++;
>  			prequeue--;
>  		} else {
>  			call_void_qop(q, wait_finish, q);
>  			if (!threadio->stop)
> -				ret = vb2_internal_dqbuf(q, &fileio->b, 0);
> +				ret = vb2_core_dqbuf(q, b, 0);
>  			call_void_qop(q, wait_prepare, q);
>  			dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
>  		}
> @@ -1321,15 +1324,15 @@ static int vb2_thread(void *data)
>  			break;
>  		try_to_freeze();
>  
> -		vb = q->bufs[fileio->b.index];
> -		if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR))
> +		vb = q->bufs[b->index];
> +		if (b->state == VB2_BUF_STATE_DONE)
>  			if (threadio->fnc(vb, threadio->priv))
>  				break;
>  		call_void_qop(q, wait_finish, q);
>  		if (set_timestamp)
> -			v4l2_get_timestamp(&fileio->b.timestamp);
> +			vb2_get_timestamp(&b->timestamp);
>  		if (!threadio->stop)
> -			ret = vb2_internal_qbuf(q, &fileio->b);
> +			ret = vb2_core_qbuf(q, b->index, b);
>  		call_void_qop(q, wait_prepare, q);
>  		if (ret || threadio->stop)
>  			break;
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer
  2015-10-29  2:27   ` Hans Verkuil
@ 2015-10-29  2:34     ` Hans Verkuil
  0 siblings, 0 replies; 13+ messages in thread
From: Hans Verkuil @ 2015-10-29  2:34 UTC (permalink / raw)
  To: Junghak Sung, linux-media, mchehab, laurent.pinchart,
	sakari.ailus, pawel
  Cc: inki.dae, sw0312.kim, nenggun.kim, sangbae90.lee, rany.kwon

Correction:

On 10/29/2015 11:27, Hans Verkuil wrote:
>> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
>> index 647ebfe..f1e7169 100644
>> --- a/include/media/videobuf2-core.h
>> +++ b/include/media/videobuf2-core.h
>> @@ -211,6 +211,7 @@ struct vb2_queue;
>>   * @num_planes:		number of planes in the buffer
>>   *			on an internal driver queue
>>   * @planes:		private per-plane information; do not change
>> + * @timestamp:		frame timestamp
>>   */
>>  struct vb2_buffer {
>>  	struct vb2_queue	*vb2_queue;
>> @@ -219,6 +220,7 @@ struct vb2_buffer {
>>  	unsigned int		memory;
>>  	unsigned int		num_planes;
>>  	struct vb2_plane	planes[VB2_MAX_PLANES];
>> +	struct timeval		timestamp;
> 
> This should become a u64 timestamp that's filled using ktime_get_ns().
> In the v4l2 code this should be converted to a timeval when v4l2_buffer
> is filled. Using ktime_get_ns() is the recommended method to do timestamping
> without having to worry about the y2038 problem and this should be used in
> vb2 core.
> 
> v4l2_set_timestamp should be updated accordingly.

This can't be done since v4l2_set_timestamp is also used by non-vb2 drivers.
Instead vb2 drivers should just call ktime_get_ns() directly instead of calling
v4l2_set_timestamp().

Sorry for the confusion.

	Hans

> 
> Regards,
> 
> 	Hans
> 
>>  
>>  	/* private: internal use only
>>  	 *
>> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
>> index 5abab1e..110062e 100644
>> --- a/include/media/videobuf2-v4l2.h
>> +++ b/include/media/videobuf2-v4l2.h
>> @@ -28,7 +28,6 @@
>>   * @vb2_buf:	video buffer 2
>>   * @flags:	buffer informational flags
>>   * @field:	enum v4l2_field; field order of the image in the buffer
>> - * @timestamp:	frame timestamp
>>   * @timecode:	frame timecode
>>   * @sequence:	sequence count of this frame
>>   * Should contain enough information to be able to cover all the fields
>> @@ -39,7 +38,6 @@ struct vb2_v4l2_buffer {
>>  
>>  	__u32			flags;
>>  	__u32			field;
>> -	struct timeval		timestamp;
>>  	struct v4l2_timecode	timecode;
>>  	__u32			sequence;
>>  };
>> diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
>> index 04ef89b..5b57d0a 100644
>> --- a/include/trace/events/v4l2.h
>> +++ b/include/trace/events/v4l2.h
>> @@ -204,7 +204,7 @@ DECLARE_EVENT_CLASS(vb2_v4l2_event_class,
>>  		__entry->minor = owner ? owner->vdev->minor : -1;
>>  		__entry->flags = vbuf->flags;
>>  		__entry->field = vbuf->field;
>> -		__entry->timestamp = timeval_to_ns(&vbuf->timestamp);
>> +		__entry->timestamp = timeval_to_ns(&vb->timestamp);
>>  		__entry->timecode_type = vbuf->timecode.type;
>>  		__entry->timecode_flags = vbuf->timecode.flags;
>>  		__entry->timecode_frames = vbuf->timecode.frames;
>> diff --git a/include/trace/events/vb2.h b/include/trace/events/vb2.h
>> index bfeceeb..35c1589 100644
>> --- a/include/trace/events/vb2.h
>> +++ b/include/trace/events/vb2.h
>> @@ -18,6 +18,7 @@ DECLARE_EVENT_CLASS(vb2_event_class,
>>  		__field(u32, index)
>>  		__field(u32, type)
>>  		__field(u32, bytesused)
>> +		__field(s64, timestamp)
>>  	),
>>  
>>  	TP_fast_assign(
>> @@ -28,14 +29,16 @@ DECLARE_EVENT_CLASS(vb2_event_class,
>>  		__entry->index = vb->index;
>>  		__entry->type = vb->type;
>>  		__entry->bytesused = vb->planes[0].bytesused;
>> +		__entry->timestamp = timeval_to_ns(&vb->timestamp);
>>  	),
>>  
>>  	TP_printk("owner = %p, queued = %u, owned_by_drv = %d, index = %u, "
>> -		  "type = %u, bytesused = %u", __entry->owner,
>> +		  "type = %u, bytesused = %u, timestamp = %llu", __entry->owner,
>>  		  __entry->queued_count,
>>  		  __entry->owned_by_drv_count,
>>  		  __entry->index, __entry->type,
>> -		  __entry->bytesused
>> +		  __entry->bytesused,
>> +		  __entry->timestamp
>>  	)
>>  )
>>  
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-10-29  2:34 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-16  6:27 [RFC PATCH v7] Refactoring Videobuf2 for common use Junghak Sung
2015-10-16  6:27 ` [RFC PATCH v7 1/7] media: videobuf2: Fix a build warning on fimc-lite.c Junghak Sung
2015-10-16  6:27 ` [RFC PATCH v7 2/7] media: videobuf2: Move timestamp to vb2_buffer Junghak Sung
2015-10-29  2:27   ` Hans Verkuil
2015-10-29  2:34     ` Hans Verkuil
2015-10-16  6:27 ` [RFC PATCH v7 3/7] media: videobuf2: Add set_timestamp to struct vb2_queue Junghak Sung
2015-10-16 12:04   ` Sakari Ailus
2015-10-16  6:27 ` [RFC PATCH v7 4/7] media: videobuf2: Separate vb2_poll() Junghak Sung
2015-10-16  6:27 ` [RFC PATCH v7 5/7] media: videobuf2: last_buffer_queued is checked at fill_v4l2_buffer() Junghak Sung
2015-10-16  6:27 ` [RFC PATCH v7 6/7] media: videobuf2: Refactor vb2_fileio_data and vb2_thread Junghak Sung
2015-10-29  2:31   ` Hans Verkuil
2015-10-16  6:27 ` [RFC PATCH v7 7/7] media: videobuf2: Move vb2_fileio_data and vb2_thread to core part Junghak Sung
2015-10-19  7:56 ` [RFC PATCH v7] Refactoring Videobuf2 for common use Hans Verkuil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).