The v4l2 API uses a 'struct timeval' to communicate time stamps to user
space. This is broken on 32-bit architectures as soon as we have a C library
that defines time_t as 64 bit, which then changes the structure layout of
struct v4l2_buffer.

Since existing user space source code relies on the type to be 'struct
timeva' and we want to preserve compile-time compatibility when moving
to a new libc, we cannot make user-visible changes to the header file.

In this patch, we change the type of the timestamp to 'struct v4l2_timeval'
as a preparation for a follow-up that adds API compatiblity for both
32-bit and 64-bit time_t. This patch should have no impact on generated
code in either user space or kernel.

Signed-off-by: Arnd Bergmann <a...@arndb.de>
---
 drivers/media/pci/bt8xx/bttv-driver.c      |  2 +-
 drivers/media/pci/meye/meye.h              |  2 +-
 drivers/media/pci/zoran/zoran.h            |  2 +-
 drivers/media/platform/coda/coda.h         |  2 +-
 drivers/media/platform/omap/omap_vout.c    |  4 ++--
 drivers/media/platform/omap3isp/ispstat.c  |  3 ++-
 drivers/media/platform/omap3isp/ispstat.h  |  2 +-
 drivers/media/platform/vim2m.c             |  2 +-
 drivers/media/platform/vivid/vivid-ctrls.c |  2 +-
 drivers/media/usb/cpia2/cpia2.h            |  2 +-
 drivers/media/usb/cpia2/cpia2_v4l.c        |  2 +-
 drivers/media/usb/gspca/gspca.c            |  2 +-
 drivers/media/usb/usbvision/usbvision.h    |  2 +-
 drivers/media/v4l2-core/v4l2-common.c      |  6 +++---
 include/media/v4l2-common.h                |  2 +-
 include/media/videobuf-core.h              |  2 +-
 include/trace/events/v4l2.h                | 12 ++++++++++--
 include/uapi/linux/videodev2.h             | 17 +++++++++++++++++
 18 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/media/pci/bt8xx/bttv-driver.c 
b/drivers/media/pci/bt8xx/bttv-driver.c
index 15a4ebc2844d..b0ed8d799c14 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3585,7 +3585,7 @@ static void
 bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
                      struct bttv_buffer_set *curr, unsigned int state)
 {
-       struct timeval ts;
+       struct v4l2_timeval ts;
 
        v4l2_get_timestamp(&ts);
 
diff --git a/drivers/media/pci/meye/meye.h b/drivers/media/pci/meye/meye.h
index 751be5e533c7..a06aa5ba9abc 100644
--- a/drivers/media/pci/meye/meye.h
+++ b/drivers/media/pci/meye/meye.h
@@ -281,7 +281,7 @@
 struct meye_grab_buffer {
        int state;                      /* state of buffer */
        unsigned long size;             /* size of jpg frame */
-       struct timeval timestamp;       /* timestamp */
+       struct v4l2_timeval timestamp;  /* timestamp */
        unsigned long sequence;         /* sequence number */
 };
 
diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h
index 4e7db8939c2b..9a9f782cede9 100644
--- a/drivers/media/pci/zoran/zoran.h
+++ b/drivers/media/pci/zoran/zoran.h
@@ -39,7 +39,7 @@ struct zoran_sync {
        unsigned long frame;    /* number of buffer that has been free'd */
        unsigned long length;   /* number of code bytes in buffer (capture 
only) */
        unsigned long seq;      /* frame sequence number */
-       struct timeval timestamp;       /* timestamp */
+       struct v4l2_timeval timestamp;  /* timestamp */
 };
 
 
diff --git a/drivers/media/platform/coda/coda.h 
b/drivers/media/platform/coda/coda.h
index 59b2af9c7749..fa1e15a757cd 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -138,7 +138,7 @@ struct coda_buffer_meta {
        struct list_head        list;
        u32                     sequence;
        struct v4l2_timecode    timecode;
-       struct timeval          timestamp;
+       struct v4l2_timeval     timestamp;
        u32                     start;
        u32                     end;
 };
diff --git a/drivers/media/platform/omap/omap_vout.c 
b/drivers/media/platform/omap/omap_vout.c
index 70c28d19ea04..974a238a86fe 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -513,7 +513,7 @@ static int omapvid_apply_changes(struct omap_vout_device 
*vout)
 }
 
 static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
-               unsigned int irqstatus, struct timeval timevalue)
+               unsigned int irqstatus, struct v4l2_timeval timevalue)
 {
        u32 fid;
 
@@ -557,7 +557,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
        int ret, fid, mgr_id;
        u32 addr, irq;
        struct omap_overlay *ovl;
-       struct timeval timevalue;
+       struct v4l2_timeval timevalue;
        struct omapvideo_info *ovid;
        struct omap_dss_device *cur_display;
        struct omap_vout_device *vout = (struct omap_vout_device *)arg;
diff --git a/drivers/media/platform/omap3isp/ispstat.c 
b/drivers/media/platform/omap3isp/ispstat.c
index 94d4c295d3d0..fa96e330c563 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -496,7 +496,8 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
                return PTR_ERR(buf);
        }
 
-       data->ts = buf->ts;
+       data->ts.tv_sec = buf->ts.tv_sec;
+       data->ts.tv_usec = buf->ts.tv_usec;
        data->config_counter = buf->config_counter;
        data->frame_number = buf->frame_number;
        data->buf_size = buf->buf_size;
diff --git a/drivers/media/platform/omap3isp/ispstat.h 
b/drivers/media/platform/omap3isp/ispstat.h
index 6d9b0244f320..7b4f136567a3 100644
--- a/drivers/media/platform/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -39,7 +39,7 @@ struct ispstat_buffer {
        struct sg_table sgt;
        void *virt_addr;
        dma_addr_t dma_addr;
-       struct timeval ts;
+       struct v4l2_timeval ts;
        u32 buf_size;
        u32 frame_number;
        u16 config_counter;
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index 295fde5fdb75..df5daac6d099 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,
        in_vb->v4l2_buf.sequence = q_data->sequence++;
        memcpy(&out_vb->v4l2_buf.timestamp,
                        &in_vb->v4l2_buf.timestamp,
-                       sizeof(struct timeval));
+                       sizeof(struct v4l2_timeval));
        if (in_vb->v4l2_buf.flags & V4L2_BUF_FLAG_TIMECODE)
                memcpy(&out_vb->v4l2_buf.timecode, &in_vb->v4l2_buf.timecode,
                        sizeof(struct v4l2_timecode));
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c 
b/drivers/media/platform/vivid/vivid-ctrls.c
index 339c8b7e53c8..065f3d6c2409 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -935,7 +935,7 @@ static const struct v4l2_ctrl_config 
vivid_ctrl_has_scaler_out = {
 static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, 
ctrl_hdl_streaming);
-       struct timeval tv;
+       struct v4l2_timeval tv;
 
        switch (ctrl->id) {
        case VIVID_CID_DQBUF_ERROR:
diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h
index cdef677d57ec..3e7c523784e7 100644
--- a/drivers/media/usb/cpia2/cpia2.h
+++ b/drivers/media/usb/cpia2/cpia2.h
@@ -354,7 +354,7 @@ struct cpia2_sbuf {
 };
 
 struct framebuf {
-       struct timeval timestamp;
+       struct v4l2_timeval timestamp;
        unsigned long seq;
        int num;
        int length;
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c 
b/drivers/media/usb/cpia2/cpia2_v4l.c
index 9caea8344547..ce50d7ef4da7 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -892,7 +892,7 @@ static int find_earliest_filled_buffer(struct camera_data 
*cam)
                                found = i;
                        } else {
                                /* find which buffer is earlier */
-                               struct timeval *tv1, *tv2;
+                               struct v4l2_timeval *tv1, *tv2;
                                tv1 = &cam->buffers[i].timestamp;
                                tv2 = &cam->buffers[found].timestamp;
                                if(tv1->tv_sec < tv2->tv_sec ||
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index af5cd8213e8b..c977937da9c4 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1898,7 +1898,7 @@ static ssize_t dev_read(struct file *file, char __user 
*data,
        struct gspca_dev *gspca_dev = video_drvdata(file);
        struct gspca_frame *frame;
        struct v4l2_buffer v4l2_buf;
-       struct timeval timestamp;
+       struct v4l2_timeval timestamp;
        int n, ret, ret2;
 
        PDEBUG(D_FRAM, "read (%zd)", count);
diff --git a/drivers/media/usb/usbvision/usbvision.h 
b/drivers/media/usb/usbvision/usbvision.h
index 4f2e4fde38f2..512de31613df 100644
--- a/drivers/media/usb/usbvision/usbvision.h
+++ b/drivers/media/usb/usbvision/usbvision.h
@@ -320,7 +320,7 @@ struct usbvision_frame {
        long bytes_read;                                /* amount of scanlength 
that has been read from data */
        struct usbvision_v4l2_format_st v4l2_format;    /* format the user 
needs*/
        int v4l2_linesize;                              /* bytes for one 
videoline*/
-       struct timeval timestamp;
+       struct v4l2_timeval timestamp;
        int sequence;                                   /* How many video 
frames we send to user */
 };
 
diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index 5b808500e7e7..589fab615f21 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -396,11 +396,11 @@ const struct v4l2_frmsize_discrete 
*v4l2_find_nearest_format(
 }
 EXPORT_SYMBOL_GPL(v4l2_find_nearest_format);
 
-void v4l2_get_timestamp(struct timeval *tv)
+void v4l2_get_timestamp(struct v4l2_timeval *tv)
 {
-       struct timespec ts;
+       struct timespec64 ts;
 
-       ktime_get_ts(&ts);
+       ktime_get_ts64(&ts);
        tv->tv_sec = ts.tv_sec;
        tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 }
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1cc0c5ba16b3..6e77d889c3f8 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -187,6 +187,6 @@ const struct v4l2_frmsize_discrete 
*v4l2_find_nearest_format(
                const struct v4l2_discrete_probe *probe,
                s32 width, s32 height);
 
-void v4l2_get_timestamp(struct timeval *tv);
+void v4l2_get_timestamp(struct v4l2_timeval *tv);
 
 #endif /* V4L2_COMMON_H_ */
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index d760aa73ebbb..6381338a9588 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -80,7 +80,7 @@ struct videobuf_buffer {
        struct list_head        queue;
        wait_queue_head_t       done;
        unsigned int            field_count;
-       struct timeval          ts;
+       struct v4l2_timeval     ts;
 
        /* Memory type */
        enum v4l2_memory        memory;
diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
index dbf017bfddd9..a88be48dc473 100644
--- a/include/trace/events/v4l2.h
+++ b/include/trace/events/v4l2.h
@@ -6,6 +6,14 @@
 
 #include <linux/tracepoint.h>
 
+#ifndef v4l2_timeval_to_ns
+#define v4l2_timeval_to_ns v4l2_timeval_to_ns
+static inline u64 v4l2_timeval_to_ns(struct v4l2_timeval *tv)
+{
+       return (u64)tv->tv_sec * NSEC_PER_SEC + tv->tv_usec * NSEC_PER_USEC;
+}
+#endif
+
 /* Enums require being exported to userspace, for user tool parsing */
 #undef EM
 #undef EMe
@@ -126,7 +134,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class,
                __entry->bytesused = buf->bytesused;
                __entry->flags = buf->flags;
                __entry->field = buf->field;
-               __entry->timestamp = timeval_to_ns(&buf->timestamp);
+               __entry->timestamp = v4l2_timeval_to_ns(&buf->timestamp);
                __entry->timecode_type = buf->timecode.type;
                __entry->timecode_flags = buf->timecode.flags;
                __entry->timecode_frames = buf->timecode.frames;
@@ -211,7 +219,7 @@ DECLARE_EVENT_CLASS(vb2_event_class,
                __entry->bytesused = vb->v4l2_planes[0].bytesused;
                __entry->flags = vb->v4l2_buf.flags;
                __entry->field = vb->v4l2_buf.field;
-               __entry->timestamp = timeval_to_ns(&vb->v4l2_buf.timestamp);
+               __entry->timestamp = 
v4l2_timeval_to_ns(&vb->v4l2_buf.timestamp);
                __entry->timecode_type = vb->v4l2_buf.timecode.type;
                __entry->timecode_flags = vb->v4l2_buf.timecode.flags;
                __entry->timecode_frames = vb->v4l2_buf.timecode.frames;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 3e2c497c31fd..450b3249ba30 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -803,6 +803,19 @@ struct v4l2_plane {
        __u32                   reserved[11];
 };
 
+#ifdef __KERNEL__
+/*
+ * This is used for the in-kernel version of v4l2_buffer, as we are
+ * migrating away from using time_t based structures in the kernel.
+ * User space might see this defined either using 32-bit or 64-bit
+ * time_t, so we have to convert it when accessing user data.
+ */
+struct v4l2_timeval {
+       long tv_sec;
+       long tv_usec;
+};
+#endif
+
 /**
  * struct v4l2_buffer - video buffer info
  * @index:     id number of the buffer
@@ -839,7 +852,11 @@ struct v4l2_buffer {
        __u32                   bytesused;
        __u32                   flags;
        __u32                   field;
+#ifdef __KERNEL__
+       struct v4l2_timeval     timestamp;
+#else
        struct timeval          timestamp;
+#endif
        struct v4l2_timecode    timecode;
        __u32                   sequence;
 
-- 
2.1.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to