media: v4l2-event: keep track of the timestamp in ns

Internally use ktime_get_ns() to get the timestamp of the event.
Only convert to timespec when interfacing with userspace.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Hans Verkuil 2019-01-21 08:32:22 -05:00 committed by Mauro Carvalho Chehab
parent 81a43d10b8
commit 63635b54e0
2 changed files with 11 additions and 10 deletions

View File

@ -52,6 +52,7 @@ static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
kev->event.pending = fh->navailable; kev->event.pending = fh->navailable;
*event = kev->event; *event = kev->event;
event->timestamp = ns_to_timespec(kev->ts);
kev->sev->first = sev_pos(kev->sev, 1); kev->sev->first = sev_pos(kev->sev, 1);
kev->sev->in_use--; kev->sev->in_use--;
@ -103,8 +104,8 @@ static struct v4l2_subscribed_event *v4l2_event_subscribed(
return NULL; return NULL;
} }
static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev, static void __v4l2_event_queue_fh(struct v4l2_fh *fh,
const struct timespec *ts) const struct v4l2_event *ev, u64 ts)
{ {
struct v4l2_subscribed_event *sev; struct v4l2_subscribed_event *sev;
struct v4l2_kevent *kev; struct v4l2_kevent *kev;
@ -144,7 +145,7 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e
if (copy_payload) if (copy_payload)
kev->event.u = ev->u; kev->event.u = ev->u;
kev->event.id = ev->id; kev->event.id = ev->id;
kev->event.timestamp = *ts; kev->ts = ts;
kev->event.sequence = fh->sequence; kev->event.sequence = fh->sequence;
sev->in_use++; sev->in_use++;
list_add_tail(&kev->list, &fh->available); list_add_tail(&kev->list, &fh->available);
@ -158,17 +159,17 @@ void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
{ {
struct v4l2_fh *fh; struct v4l2_fh *fh;
unsigned long flags; unsigned long flags;
struct timespec timestamp; u64 ts;
if (vdev == NULL) if (vdev == NULL)
return; return;
ktime_get_ts(&timestamp); ts = ktime_get_ns();
spin_lock_irqsave(&vdev->fh_lock, flags); spin_lock_irqsave(&vdev->fh_lock, flags);
list_for_each_entry(fh, &vdev->fh_list, list) list_for_each_entry(fh, &vdev->fh_list, list)
__v4l2_event_queue_fh(fh, ev, &timestamp); __v4l2_event_queue_fh(fh, ev, ts);
spin_unlock_irqrestore(&vdev->fh_lock, flags); spin_unlock_irqrestore(&vdev->fh_lock, flags);
} }
@ -177,12 +178,10 @@ EXPORT_SYMBOL_GPL(v4l2_event_queue);
void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev) void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev)
{ {
unsigned long flags; unsigned long flags;
struct timespec timestamp; u64 ts = ktime_get_ns();
ktime_get_ts(&timestamp);
spin_lock_irqsave(&fh->vdev->fh_lock, flags); spin_lock_irqsave(&fh->vdev->fh_lock, flags);
__v4l2_event_queue_fh(fh, ev, &timestamp); __v4l2_event_queue_fh(fh, ev, ts);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
} }
EXPORT_SYMBOL_GPL(v4l2_event_queue_fh); EXPORT_SYMBOL_GPL(v4l2_event_queue_fh);

View File

@ -34,11 +34,13 @@ struct video_device;
* @list: List node for the v4l2_fh->available list. * @list: List node for the v4l2_fh->available list.
* @sev: Pointer to parent v4l2_subscribed_event. * @sev: Pointer to parent v4l2_subscribed_event.
* @event: The event itself. * @event: The event itself.
* @ts: The timestamp of the event.
*/ */
struct v4l2_kevent { struct v4l2_kevent {
struct list_head list; struct list_head list;
struct v4l2_subscribed_event *sev; struct v4l2_subscribed_event *sev;
struct v4l2_event event; struct v4l2_event event;
u64 ts;
}; };
/** /**