aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2017-06-06 19:59:04 (GMT)
committerHans Verkuil <hans.verkuil@cisco.com>2017-10-26 08:53:31 (GMT)
commit4a58dec83fa563a66996558507a521109380140a (patch)
treed22f528e2e598e923b24ba916dc3f10d6d9d0a6c
parenta95549df06d9900f3559afdbb9da06bd4b22d1f3 (diff)
v4l2-core: make VIDIOC_DQEVENT y2038 proof.v4l2-buffer
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-event.c22
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c6
-rw-r--r--include/uapi/linux/videodev2.h3
4 files changed, 20 insertions, 15 deletions
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa..2d48b0b 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -790,7 +790,8 @@ struct v4l2_event32 {
__u32 sequence;
struct compat_timespec timestamp;
__u32 id;
- __u32 reserved[8];
+ __u64 timestamp64;
+ __u32 reserved[6];
};
static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
@@ -803,6 +804,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
put_user(kp->id, &up->id) ||
+ put_user(kp->timestamp64, &up->timestamp64) ||
copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
return -EFAULT;
return 0;
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c
index 968c2eb..6fb8570 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -36,6 +36,7 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
{
struct v4l2_kevent *kev;
unsigned long flags;
+ u64 nsecs;
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
@@ -56,6 +57,9 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
kev->sev->in_use--;
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
+ event->timestamp.tv_sec = div64_u64_rem(event->timestamp64,
+ NSEC_PER_SEC, &nsecs);
+ event->timestamp.tv_nsec = nsecs;
return 0;
}
@@ -103,8 +107,8 @@ static struct v4l2_subscribed_event *v4l2_event_subscribed(
return NULL;
}
-static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev,
- const struct timespec *ts)
+static void __v4l2_event_queue_fh(struct v4l2_fh *fh,
+ const struct v4l2_event *ev, u64 ts)
{
struct v4l2_subscribed_event *sev;
struct v4l2_kevent *kev;
@@ -152,7 +156,7 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e
if (copy_payload)
kev->event.u = ev->u;
kev->event.id = ev->id;
- kev->event.timestamp = *ts;
+ kev->event.timestamp64 = ts;
kev->event.sequence = fh->sequence;
sev->in_use++;
list_add_tail(&kev->list, &fh->available);
@@ -166,17 +170,15 @@ void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
{
struct v4l2_fh *fh;
unsigned long flags;
- struct timespec timestamp;
+ u64 timestamp = ktime_get_ns();
if (vdev == NULL)
return;
- ktime_get_ts(&timestamp);
-
spin_lock_irqsave(&vdev->fh_lock, flags);
list_for_each_entry(fh, &vdev->fh_list, list)
- __v4l2_event_queue_fh(fh, ev, &timestamp);
+ __v4l2_event_queue_fh(fh, ev, timestamp);
spin_unlock_irqrestore(&vdev->fh_lock, flags);
}
@@ -185,12 +187,10 @@ EXPORT_SYMBOL_GPL(v4l2_event_queue);
void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev)
{
unsigned long flags;
- struct timespec timestamp;
-
- ktime_get_ts(&timestamp);
+ u64 timestamp = ktime_get_ns();
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
- __v4l2_event_queue_fh(fh, ev, &timestamp);
+ __v4l2_event_queue_fh(fh, ev, timestamp);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
}
EXPORT_SYMBOL_GPL(v4l2_event_queue_fh);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index b014904..b60b829 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -805,10 +805,12 @@ static void v4l_print_event(const void *arg, bool write_only)
{
const struct v4l2_event *p = arg;
const struct v4l2_event_ctrl *c;
+ u64 secs, nsecs;
- pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n",
+ secs = div64_u64_rem(p->timestamp64, NSEC_PER_SEC, &nsecs);
+ pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp64=%llu.%9.9llu\n",
p->type, p->pending, p->sequence, p->id,
- p->timestamp.tv_sec, p->timestamp.tv_nsec);
+ secs, nsecs);
switch (p->type) {
case V4L2_EVENT_VSYNC:
printk(KERN_DEBUG "field=%s\n",
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 908eeaa..898d5d2 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -2264,7 +2264,8 @@ struct v4l2_event {
__u32 sequence;
struct timespec timestamp;
__u32 id;
- __u32 reserved[8];
+ __u64 timestamp64;
+ __u32 reserved[6];
};
#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0)

Privacy Policy