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 | * and the timecode field and flag if needed. | 146 | * and the timecode field and flag if needed. |
| 147 | */ | 147 | */ |
| 148 | if (q->copy_timestamp) | 148 | if (q->copy_timestamp) |
| 149 | vb->timestamp = v4l2_timeval_to_ns(&b->timestamp); | 149 | vb->timestamp = v4l2_buffer_get_timestamp(b); |
| 150 | vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; | 150 | vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE; |
| 151 | if (b->flags & V4L2_BUF_FLAG_TIMECODE) | 151 | if (b->flags & V4L2_BUF_FLAG_TIMECODE) |
| 152 | vbuf->timecode = b->timecode; | 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 | b->flags = vbuf->flags; | 483 | b->flags = vbuf->flags; |
| 484 | b->field = vbuf->field; | 484 | b->field = vbuf->field; |
| 485 | b->timestamp = ns_to_timeval(vb->timestamp); | 485 | v4l2_buffer_set_timestamp(b, vb->timestamp); |
| 486 | b->timecode = vbuf->timecode; | 486 | b->timecode = vbuf->timecode; |
| 487 | b->sequence = vbuf->sequence; | 487 | b->sequence = vbuf->sequence; |
| 488 | b->reserved2 = 0; | 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 | buf->flags |= V4L2_BUF_FLAG_DONE; | 1266 | buf->flags |= V4L2_BUF_FLAG_DONE; |
| 1267 | 1267 | ||
| 1268 | buf->field = V4L2_FIELD_NONE; | 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 | buf->sequence = meye.grab_buffer[index].sequence; | 1270 | buf->sequence = meye.grab_buffer[index].sequence; |
| 1271 | buf->memory = V4L2_MEMORY_MMAP; | 1271 | buf->memory = V4L2_MEMORY_MMAP; |
| 1272 | buf->m.offset = index * gbufsize; | 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 | buf->bytesused = meye.grab_buffer[reqnr].size; | 1332 | buf->bytesused = meye.grab_buffer[reqnr].size; |
| 1333 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1333 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 1334 | buf->field = V4L2_FIELD_NONE; | 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 | buf->sequence = meye.grab_buffer[reqnr].sequence; | 1336 | buf->sequence = meye.grab_buffer[reqnr].sequence; |
| 1337 | buf->memory = V4L2_MEMORY_MMAP; | 1337 | buf->memory = V4L2_MEMORY_MMAP; |
| 1338 | buf->m.offset = reqnr * gbufsize; | 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 | break; | 800 | break; |
| 801 | case FRAME_READY: | 801 | case FRAME_READY: |
| 802 | buf->bytesused = cam->buffers[buf->index].length; | 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 | buf->sequence = cam->buffers[buf->index].seq; | 804 | buf->sequence = cam->buffers[buf->index].seq; |
| 805 | buf->flags = V4L2_BUF_FLAG_DONE; | 805 | buf->flags = V4L2_BUF_FLAG_DONE; |
| 806 | break; | 806 | break; |
| @@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 100 unmodified lines | |||
| 907 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE | 907 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE |
| 908 | | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 908 | | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 909 | buf->field = V4L2_FIELD_NONE; | 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 | buf->sequence = cam->buffers[buf->index].seq; | 911 | buf->sequence = cam->buffers[buf->index].seq; |
| 912 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; | 912 | buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; |
| 913 | buf->length = cam->frame_size; | 913 | buf->length = cam->frame_size; |
| @@ -1125,7 +1125,7 @@ static int stk_vidioc_dqbuf(struct file *filp, · 1124 unmodified lines | |||
| 1125 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; | 1125 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; |
| 1126 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; | 1126 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; |
| 1127 | sbuf->v4lbuf.sequence = ++dev->sequence; | 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 | *buf = sbuf->v4lbuf; | 1130 | *buf = sbuf->v4lbuf; |
| 1131 | return 0; | 1131 | return 0; |
| @@ -696,7 +696,7 @@ static int vidioc_querybuf(struct file *file, · 695 unmodified lines | |||
| 696 | vb->length = usbvision->curwidth * | 696 | vb->length = usbvision->curwidth * |
| 697 | usbvision->curheight * | 697 | usbvision->curheight * |
| 698 | usbvision->palette.bytes_per_pixel; | 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 | vb->sequence = usbvision->frame[vb->index].sequence; | 700 | vb->sequence = usbvision->frame[vb->index].sequence; |
| 701 | return 0; | 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 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 765 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| 766 | vb->index = f->index; | 766 | vb->index = f->index; |
| 767 | vb->sequence = f->sequence; | 767 | vb->sequence = f->sequence; |
| 768 | vb->timestamp = ns_to_timeval(f->ts); | 768 | v4l2_buffer_set_timestamp(vb, f->ts); |
| 769 | vb->field = V4L2_FIELD_NONE; | 769 | vb->field = V4L2_FIELD_NONE; |
| 770 | vb->bytesused = f->scanlength; | 770 | vb->bytesused = f->scanlength; |
| 771 | 771 | ||
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | 20 | ||
| 21 | #include <media/videobuf-core.h> | 21 | #include <media/videobuf-core.h> |
| 22 | #include <media/v4l2-common.h> | ||
| 22 | 23 | ||
| 23 | #define MAGIC_BUFFER 0x20070728 | 24 | #define MAGIC_BUFFER 0x20070728 |
| 24 | #define MAGIC_CHECK(is, should) \ | 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 | b->field = vb->field; | 367 | b->field = vb->field; |
| 367 | b->timestamp = ns_to_timeval(vb->ts); | 368 | v4l2_buffer_set_timestamp(b, vb->ts); |
| 368 | b->bytesused = vb->size; | 369 | b->bytesused = vb->size; |
| 369 | b->sequence = vb->field_count >> 1; | 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 | || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) { | 579 | || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) { |
| 579 | buf->size = b->bytesused; | 580 | buf->size = b->bytesused; |
| 580 | buf->field = b->field; | 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 | break; | 584 | break; |
| 584 | case V4L2_MEMORY_USERPTR: | 585 | case V4L2_MEMORY_USERPTR: |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #ifndef V4L2_COMMON_H_ | 14 | #ifndef V4L2_COMMON_H_ |
| 15 | #define V4L2_COMMON_H_ | 15 | #define V4L2_COMMON_H_ |
| 16 | 16 | ||
| 17 | #include <linux/time.h> | ||
| 17 | #include <media/v4l2-dev.h> | 18 | #include <media/v4l2-dev.h> |
| 18 | 19 | ||
| 19 | /* Common printk constructs for v4l-i2c drivers. These macros create a unique | 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 | int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, | 519 | int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, |
| 519 | u32 width, u32 height); | 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 | #endif /* V4L2_COMMON_H_ */ | 542 | #endif /* V4L2_COMMON_H_ */ |
| @@ -130,7 +130,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class, · 129 unmodified lines | |||
| 130 | __entry->bytesused = buf->bytesused; | 130 | __entry->bytesused = buf->bytesused; |
| 131 | __entry->flags = buf->flags; | 131 | __entry->flags = buf->flags; |
| 132 | __entry->field = buf->field; | 132 | __entry->field = buf->field; |
| 133 | __entry->timestamp = timeval_to_ns(&buf->timestamp); | 133 | __entry->timestamp = v4l2_buffer_get_timestamp(buf); |
| 134 | __entry->timecode_type = buf->timecode.type; | 134 | __entry->timecode_type = buf->timecode.type; |
| 135 | __entry->timecode_flags = buf->timecode.flags; | 135 | __entry->timecode_flags = buf->timecode.flags; |
| 136 | __entry->timecode_frames = buf->timecode.frames; | 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 | * v4l2_timeval_to_ns - Convert timeval to nanoseconds | 1022 | * v4l2_timeval_to_ns - Convert timeval to nanoseconds |
| 1022 | * @ts: pointer to the timeval variable to be converted | 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 | return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000; | 1030 | return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000; |
| 1030 | } | 1031 | } |
| 1032 | #endif | ||
| 1031 | 1033 | ||
| 1032 | /* Flags for 'flags' field */ | 1034 | /* Flags for 'flags' field */ |
| 1033 | /* Buffer is mapped (flag) */ | 1035 | /* Buffer is mapped (flag) */ |