Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ptp: introduce PTP_CLOCK_EXTOFF event for the measured external offset

This change is for the PHC devices that can measure the phase offset
between PHC signal and the external signal, such as the 1PPS signal of
GNSS. Reporting PTP_CLOCK_EXTOFF to user space will be piggy-backed to
the existing ptp_extts_event so that application such as ts2phc can
poll the external offset the same way as extts. Hence, ts2phc can use
the offset to achieve the alignment between PHC and the external signal
by the help of either SW or HW filters.

Signed-off-by: Min Li <min.li.xe@renesas.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Min Li and committed by
David S. Miller
ea1cc3ee cf8e51ef

+28 -4
+15 -1
drivers/ptp/ptp_clock.c
··· 44 44 struct ptp_clock_event *src) 45 45 { 46 46 struct ptp_extts_event *dst; 47 + struct timespec64 offset_ts; 47 48 unsigned long flags; 48 49 s64 seconds; 49 50 u32 remainder; 50 51 51 - seconds = div_u64_rem(src->timestamp, 1000000000, &remainder); 52 + if (src->type == PTP_CLOCK_EXTTS) { 53 + seconds = div_u64_rem(src->timestamp, 1000000000, &remainder); 54 + } else if (src->type == PTP_CLOCK_EXTOFF) { 55 + offset_ts = ns_to_timespec64(src->offset); 56 + seconds = offset_ts.tv_sec; 57 + remainder = offset_ts.tv_nsec; 58 + } else { 59 + WARN(1, "%s: unknown type %d\n", __func__, src->type); 60 + return; 61 + } 52 62 53 63 spin_lock_irqsave(&queue->lock, flags); 54 64 55 65 dst = &queue->buf[queue->tail]; 56 66 dst->index = src->index; 67 + dst->flags = PTP_EXTTS_EVENT_VALID; 57 68 dst->t.sec = seconds; 58 69 dst->t.nsec = remainder; 70 + if (src->type == PTP_CLOCK_EXTOFF) 71 + dst->flags |= PTP_EXT_OFFSET; 59 72 60 73 /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ 61 74 if (!queue_free(queue)) ··· 430 417 break; 431 418 432 419 case PTP_CLOCK_EXTTS: 420 + case PTP_CLOCK_EXTOFF: 433 421 /* Enqueue timestamp on selected queues */ 434 422 spin_lock_irqsave(&ptp->tsevqs_lock, flags); 435 423 list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
+3
include/linux/ptp_clock_kernel.h
··· 200 200 enum ptp_clock_events { 201 201 PTP_CLOCK_ALARM, 202 202 PTP_CLOCK_EXTTS, 203 + PTP_CLOCK_EXTOFF, 203 204 PTP_CLOCK_PPS, 204 205 PTP_CLOCK_PPSUSR, 205 206 }; ··· 211 210 * @type: One of the ptp_clock_events enumeration values. 212 211 * @index: Identifies the source of the event. 213 212 * @timestamp: When the event occurred (%PTP_CLOCK_EXTTS only). 213 + * @offset: When the event occurred (%PTP_CLOCK_EXTOFF only). 214 214 * @pps_times: When the event occurred (%PTP_CLOCK_PPSUSR only). 215 215 */ 216 216 ··· 220 218 int index; 221 219 union { 222 220 u64 timestamp; 221 + s64 offset; 223 222 struct pps_event_time pps_times; 224 223 }; 225 224 };
+10 -3
include/uapi/linux/ptp_clock.h
··· 32 32 #define PTP_RISING_EDGE (1<<1) 33 33 #define PTP_FALLING_EDGE (1<<2) 34 34 #define PTP_STRICT_FLAGS (1<<3) 35 + #define PTP_EXT_OFFSET (1<<4) 35 36 #define PTP_EXTTS_EDGES (PTP_RISING_EDGE | PTP_FALLING_EDGE) 36 37 37 38 /* ··· 41 40 #define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \ 42 41 PTP_RISING_EDGE | \ 43 42 PTP_FALLING_EDGE | \ 44 - PTP_STRICT_FLAGS) 43 + PTP_STRICT_FLAGS | \ 44 + PTP_EXT_OFFSET) 45 45 46 46 /* 47 47 * flag fields valid for the original PTP_EXTTS_REQUEST ioctl. ··· 51 49 #define PTP_EXTTS_V1_VALID_FLAGS (PTP_ENABLE_FEATURE | \ 52 50 PTP_RISING_EDGE | \ 53 51 PTP_FALLING_EDGE) 52 + 53 + /* 54 + * flag fields valid for the ptp_extts_event report. 55 + */ 56 + #define PTP_EXTTS_EVENT_VALID (PTP_ENABLE_FEATURE) 54 57 55 58 /* 56 59 * Bits of the ptp_perout_request.flags field: ··· 235 228 #define PTP_MASK_EN_SINGLE _IOW(PTP_CLK_MAGIC, 20, unsigned int) 236 229 237 230 struct ptp_extts_event { 238 - struct ptp_clock_time t; /* Time event occured. */ 231 + struct ptp_clock_time t; /* Time event occurred. */ 239 232 unsigned int index; /* Which channel produced the event. */ 240 - unsigned int flags; /* Reserved for future use. */ 233 + unsigned int flags; /* Event type. */ 241 234 unsigned int rsv[2]; /* Reserved for future use. */ 242 235 }; 243 236