[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210628184611.3024919-1-jonathan.lemon@gmail.com>
Date: Mon, 28 Jun 2021 11:46:11 -0700
From: Jonathan Lemon <jonathan.lemon@...il.com>
To: <netdev@...r.kernel.org>, <richardcochran@...il.com>
CC: <kernel-team@...com>
Subject: [PATCH] ptp: Add PTP_CLOCK_EXTTSUSR internal ptp_event
This event differs from CLOCK_EXTTS in two ways:
1) The caller provides the sec/nsec fields directly, instead of
needing to convert them from the timestamp field.
2) A 32 bit data field is attached to the event, which is returned
to userspace, which allows returning timestamped data information.
This may be used for things like returning the phase difference
between two time sources.
For discussion:
The data field is returned as rsv[0], which is part of the current UAPI.
Arguably, this should be renamed, and possibly a flag value set in the
'struct ptp_extts_event' indicating field validity.
Signed-off-by: Jonathan Lemon <jonathan.lemon@...il.com>
---
drivers/ptp/ptp_clock.c | 27 +++++++++++++++++++++++++++
include/linux/ptp_clock_kernel.h | 3 +++
2 files changed, 30 insertions(+)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 841d8900504d..c176fa82df85 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -63,6 +63,28 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue,
spin_unlock_irqrestore(&queue->lock, flags);
}
+static void enqueue_external_usr_timestamp(struct timestamp_event_queue *queue,
+ struct ptp_clock_event *src)
+{
+ struct ptp_extts_event *dst;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+
+ dst = &queue->buf[queue->tail];
+ dst->index = src->index;
+ dst->t.sec = src->pps_times.ts_real.tv_sec;
+ dst->t.nsec = src->pps_times.ts_real.tv_nsec;
+ dst->rsv[0] = src->data;
+
+ if (!queue_free(queue))
+ queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
+
+ queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS;
+
+ spin_unlock_irqrestore(&queue->lock, flags);
+}
+
/* posix clock implementation */
static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
@@ -311,6 +333,11 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
wake_up_interruptible(&ptp->tsev_wq);
break;
+ case PTP_CLOCK_EXTTSUSR:
+ enqueue_external_usr_timestamp(&ptp->tsevq, event);
+ wake_up_interruptible(&ptp->tsev_wq);
+ break;
+
case PTP_CLOCK_PPS:
pps_get_ts(&evt);
pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL);
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index aba237c0b3a2..ef1aa788350e 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -166,6 +166,7 @@ enum ptp_clock_events {
PTP_CLOCK_EXTTS,
PTP_CLOCK_PPS,
PTP_CLOCK_PPSUSR,
+ PTP_CLOCK_EXTTSUSR,
};
/**
@@ -175,6 +176,7 @@ enum ptp_clock_events {
* @index: Identifies the source of the event.
* @timestamp: When the event occurred (%PTP_CLOCK_EXTTS only).
* @pps_times: When the event occurred (%PTP_CLOCK_PPSUSR only).
+ * @data: Extra data for event (%PTP_CLOCK_EXTTSUSR only).
*/
struct ptp_clock_event {
@@ -184,6 +186,7 @@ struct ptp_clock_event {
u64 timestamp;
struct pps_event_time pps_times;
};
+ unsigned int data;
};
/**
--
2.30.2
Powered by blists - more mailing lists