diff options
Diffstat (limited to 'drivers/ptp/ptp_clock.c')
-rw-r--r-- | drivers/ptp/ptp_clock.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 15b804ba4868..3aaf1a3430c5 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -44,18 +44,31 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue, struct ptp_clock_event *src) { struct ptp_extts_event *dst; + struct timespec64 offset_ts; unsigned long flags; s64 seconds; u32 remainder; - seconds = div_u64_rem(src->timestamp, 1000000000, &remainder); + if (src->type == PTP_CLOCK_EXTTS) { + seconds = div_u64_rem(src->timestamp, 1000000000, &remainder); + } else if (src->type == PTP_CLOCK_EXTOFF) { + offset_ts = ns_to_timespec64(src->offset); + seconds = offset_ts.tv_sec; + remainder = offset_ts.tv_nsec; + } else { + WARN(1, "%s: unknown type %d\n", __func__, src->type); + return; + } spin_lock_irqsave(&queue->lock, flags); dst = &queue->buf[queue->tail]; dst->index = src->index; + dst->flags = PTP_EXTTS_EVENT_VALID; dst->t.sec = seconds; dst->t.nsec = remainder; + if (src->type == PTP_CLOCK_EXTOFF) + dst->flags |= PTP_EXT_OFFSET; /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ if (!queue_free(queue)) @@ -417,6 +430,7 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) break; case PTP_CLOCK_EXTTS: + case PTP_CLOCK_EXTOFF: /* Enqueue timestamp on selected queues */ spin_lock_irqsave(&ptp->tsevqs_lock, flags); list_for_each_entry(tsevq, &ptp->tsevqs, qlist) { |