As a preparation for adding 64-bit time_t support in the uapi, change the drivers to no longer care about the format of the timestamp field in struct v4l2_buffer. The v4l2_timeval_to_ns() function is no longer needed in the kernel after this, but there is userspace code relying on it to be part of the uapi header.
Unified · Split
| @@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb) · 145 unmodified lines | ||
| 146 | 146 | * and the timecode field and flag if needed. |
| 147 | 147 | */ |
| 148 | 148 | if (q->copy_timestamp) |
| 149 | − vb->timestamp = v4l2_timeval_to_ns(&b->timestamp); | |
| 149 | + vb->timestamp = v4l2_buffer_get_timestamp(b); | |
| 150 | 150 | vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; |
| 151 | 151 | if (b->flags & V4L2_BUF_FLAG_TIMECODE) |
| 152 | 152 | vbuf->timecode = b->timecode; |
| @@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) · 329 unmodified lines | ||
| 482 | 482 | |
| 483 | 483 | b->flags = vbuf->flags; |
| 484 | 484 | b->field = vbuf->field; |
| 485 | − b->timestamp = ns_to_timeval(vb->timestamp); | |
| 485 | + v4l2_buffer_set_timestamp(b, vb->timestamp); | |
| 486 | 486 | b->timecode = vbuf->timecode; |
| 487 | 487 | b->sequence = vbuf->sequence; |
| 488 | 488 | b->reserved2 = 0; |
| @@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 1265 unmodified lines | ||
| 1266 | 1266 | buf->flags |= V4L2_BUF_FLAG_DONE; |
| 1267 | 1267 | |
| 1268 | 1268 | buf->field = V4L2_FIELD_NONE; |
| 1269 | − buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts); | |
| 1269 | + v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts); | |
| 1270 | 1270 | buf->sequence = meye.grab_buffer[index].sequence; |
| 1271 | 1271 | buf->memory = V4L2_MEMORY_MMAP; |
| 1272 | 1272 | buf->m.offset = index * gbufsize; |
| @@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 59 unmodified lines | ||
| 1332 | 1332 | buf->bytesused = meye.grab_buffer[reqnr].size; |
| 1333 | 1333 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 1334 | 1334 | buf->field = V4L2_FIELD_NONE; |
| 1335 | − buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts); | |
| 1335 | + v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts); | |
| 1336 | 1336 | buf->sequence = meye.grab_buffer[reqnr].sequence; |
| 1337 | 1337 | buf->memory = V4L2_MEMORY_MMAP; |
| 1338 | 1338 | buf->m.offset = reqnr * gbufsize; |
| @@ -800,7 +800,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 799 unmodified lines | ||
| 800 | 800 | break; |
| 801 | 801 | case FRAME_READY: |
| 802 | 802 | buf->bytesused = cam->buffers[buf->index].length; |
| 803 | − buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); | |
| 803 | + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); | |
| 804 | 804 | buf->sequence = cam->buffers[buf->index].seq; |
| 805 | 805 | buf->flags = V4L2_BUF_FLAG_DONE; |
| 806 | 806 | break; |
| @@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 100 unmodified lines | ||
| 907 | 907 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE |
| 908 | 908 | | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 909 | 909 | buf->field = V4L2_FIELD_NONE; |
| 910 | − buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); | |
| 910 | + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); | |
| 911 | 911 | buf->sequence = cam->buffers[buf->index].seq; |
| 912 | 912 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; |
| 913 | 913 | buf->length = cam->frame_size; |
| @@ -1125,7 +1125,7 @@ static int stk_vidioc_dqbuf(struct file *filp, · 1124 unmodified lines | ||
| 1125 | 1125 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; |
| 1126 | 1126 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; |
| 1127 | 1127 | sbuf->v4lbuf.sequence = ++dev->sequence; |
| 1128 | − sbuf->v4lbuf.timestamp = ns_to_timeval(ktime_get_ns()); | |
| 1128 | + v4l2_buffer_set_timestamp(&sbuf->v4lbuf, ktime_get_ns()); | |
| 1129 | 1129 | |
| 1130 | 1130 | *buf = sbuf->v4lbuf; |
| 1131 | 1131 | return 0; |
| @@ -696,7 +696,7 @@ static int vidioc_querybuf(struct file *file, · 695 unmodified lines | ||
| 696 | 696 | vb->length = usbvision->curwidth * |
| 697 | 697 | usbvision->curheight * |
| 698 | 698 | usbvision->palette.bytes_per_pixel; |
| 699 | − vb->timestamp = ns_to_timeval(usbvision->frame[vb->index].ts); | |
| 699 | + v4l2_buffer_set_timestamp(vb, usbvision->frame[vb->index].ts); | |
| 700 | 700 | vb->sequence = usbvision->frame[vb->index].sequence; |
| 701 | 701 | return 0; |
| 702 | 702 | } |
| @@ -765,7 +765,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb) · 62 unmodified lines | ||
| 765 | 765 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 766 | 766 | vb->index = f->index; |
| 767 | 767 | vb->sequence = f->sequence; |
| 768 | − vb->timestamp = ns_to_timeval(f->ts); | |
| 768 | + v4l2_buffer_set_timestamp(vb, f->ts); | |
| 769 | 769 | vb->field = V4L2_FIELD_NONE; |
| 770 | 770 | vb->bytesused = f->scanlength; |
| 771 | 771 | |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/interrupt.h> |
| 20 | 20 | |
| 21 | 21 | #include <media/videobuf-core.h> |
| 22 | +#include <media/v4l2-common.h> | |
| 22 | 23 | |
| 23 | 24 | #define MAGIC_BUFFER 0x20070728 |
| 24 | 25 | #define MAGIC_CHECK(is, should) \ |
| @@ -364,7 +365,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, · 339 unmodified lines | ||
| 364 | 365 | } |
| 365 | 366 | |
| 366 | 367 | b->field = vb->field; |
| 367 | − b->timestamp = ns_to_timeval(vb->ts); | |
| 368 | + v4l2_buffer_set_timestamp(b, vb->ts); | |
| 368 | 369 | b->bytesused = vb->size; |
| 369 | 370 | b->sequence = vb->field_count >> 1; |
| 370 | 371 | } |
| @@ -578,7 +579,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) · 207 unmodified lines | ||
| 578 | 579 | || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) { |
| 579 | 580 | buf->size = b->bytesused; |
| 580 | 581 | buf->field = b->field; |
| 581 | − buf->ts = v4l2_timeval_to_ns(&b->timestamp); | |
| 582 | + buf->ts = v4l2_buffer_get_timestamp(b); | |
| 582 | 583 | } |
| 583 | 584 | break; |
| 584 | 585 | case V4L2_MEMORY_USERPTR: |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #ifndef V4L2_COMMON_H_ |
| 15 | 15 | #define V4L2_COMMON_H_ |
| 16 | 16 | |
| 17 | +#include <linux/time.h> | |
| 17 | 18 | #include <media/v4l2-dev.h> |
| 18 | 19 | |
| 19 | 20 | /* Common printk constructs for v4l-i2c drivers. These macros create a unique |
| @@ -518,4 +519,24 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, · 498 unmodified lines | ||
| 518 | 519 | int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, |
| 519 | 520 | u32 width, u32 height); |
| 520 | 521 | |
| 522 | +static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf) | |
| 523 | +{ | |
| 524 | + /* | |
| 525 | + * When the timestamp comes from 32-bit user space, there may be | |
| 526 | + * uninitialized data in tv_usec, so cast it to u32. | |
| 527 | + * Otherwise allow invalid input for backwards compatibility. | |
| 528 | + */ | |
| 529 | + return buf->timestamp.tv_sec * NSEC_PER_SEC + | |
| 530 | + (u32)buf->timestamp.tv_usec * NSEC_PER_USEC; | |
| 531 | +} | |
| 532 | + | |
| 533 | +static inline void v4l2_buffer_set_timestamp(struct v4l2_buffer *buf, | |
| 534 | + u64 timestamp) | |
| 535 | +{ | |
| 536 | + struct timespec64 ts = ns_to_timespec64(timestamp); | |
| 537 | + | |
| 538 | + buf->timestamp.tv_sec = ts.tv_sec; | |
| 539 | + buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | |
| 540 | +} | |
| 541 | + | |
| 521 | 542 | #endif /* V4L2_COMMON_H_ */ |
| @@ -130,7 +130,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class, · 129 unmodified lines | ||
| 130 | 130 | __entry->bytesused = buf->bytesused; |
| 131 | 131 | __entry->flags = buf->flags; |
| 132 | 132 | __entry->field = buf->field; |
| 133 | − __entry->timestamp = timeval_to_ns(&buf->timestamp); | |
| 133 | + __entry->timestamp = v4l2_buffer_get_timestamp(buf); | |
| 134 | 134 | __entry->timecode_type = buf->timecode.type; |
| 135 | 135 | __entry->timecode_flags = buf->timecode.flags; |
| 136 | 136 | __entry->timecode_frames = buf->timecode.frames; |
| @@ -1017,6 +1017,7 @@ struct v4l2_buffer { · 1016 unmodified lines | ||
| 1017 | 1017 | }; |
| 1018 | 1018 | }; |
| 1019 | 1019 | |
| 1020 | +#ifndef __KERNEL__ | |
| 1020 | 1021 | /** |
| 1021 | 1022 | * v4l2_timeval_to_ns - Convert timeval to nanoseconds |
| 1022 | 1023 | * @ts: pointer to the timeval variable to be converted |
| @@ -1028,6 +1029,7 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv) · 5 unmodified lines | ||
| 1028 | 1029 | { |
| 1029 | 1030 | return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000; |
| 1030 | 1031 | } |
| 1032 | +#endif | |
| 1031 | 1033 | |
| 1032 | 1034 | /* Flags for 'flags' field */ |
| 1033 | 1035 | /* Buffer is mapped (flag) */ |