--- v13
+++ v12
@@ -8,22 +8,22 @@
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
- Documentation/ABI/testing/sysfs-ptp | 98 +++++++++
+ Documentation/ABI/testing/sysfs-ptp | 98 ++++++++++
Documentation/ptp/ptp.txt | 89 +++++++++
- Documentation/ptp/testptp.c | 368 +++++++++++++++++++++++++++++++++++
- Documentation/ptp/testptp.mk | 33 +++
+ Documentation/ptp/testptp.c | 352 +++++++++++++++++++++++++++++++++++
+ Documentation/ptp/testptp.mk | 33 ++++
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/ptp/Kconfig | 30 +++
drivers/ptp/Makefile | 6 +
- drivers/ptp/ptp_chardev.c | 155 +++++++++++++++
- drivers/ptp/ptp_clock.c | 339 ++++++++++++++++++++++++++++++++
- drivers/ptp/ptp_private.h | 91 +++++++++
- drivers/ptp/ptp_sysfs.c | 230 ++++++++++++++++++++++
+ drivers/ptp/ptp_chardev.c | 156 ++++++++++++++++
+ drivers/ptp/ptp_clock.c | 320 +++++++++++++++++++++++++++++++
+ drivers/ptp/ptp_private.h | 86 +++++++++
+ drivers/ptp/ptp_sysfs.c | 230 +++++++++++++++++++++++
include/linux/Kbuild | 1 +
- include/linux/ptp_clock.h | 84 ++++++++
- include/linux/ptp_clock_kernel.h | 139 +++++++++++++
- 15 files changed, 1666 insertions(+), 0 deletions(-)
+ include/linux/ptp_clock.h | 84 +++++++++
+ include/linux/ptp_clock_kernel.h | 139 ++++++++++++++
+ 15 files changed, 1627 insertions(+), 0 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-ptp
create mode 100644 Documentation/ptp/ptp.txt
create mode 100644 Documentation/ptp/testptp.c
@@ -238,10 +238,10 @@
+ - Target Time (optional interrupt)
diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c
new file mode 100644
-index 0000000..dd53e44
+index 0000000..a1d2bf1
--- /dev/null
+++ b/Documentation/ptp/testptp.c
-@@ -0,0 +1,368 @@
+@@ -0,0 +1,352 @@
+/*
+ * PTP 1588 clock support - User space test program
+ *
@@ -326,22 +326,6 @@
+ sigaction(signum, &action, NULL);
+
+ return 0;
-+}
-+
-+static long ppb_to_scaled_ppm(int ppb)
-+{
-+ /*
-+ * The 'freq' field in the 'struct timex' is in parts per
-+ * million, but with a 16 bit binary fractional field.
-+ * Instead of calculating either one of
-+ *
-+ * scaled_ppm = (ppb / 1000) << 16 [1]
-+ * scaled_ppm = (ppb << 16) / 1000 [2]
-+ *
-+ * we simply use double precision math, in order to avoid the
-+ * truncation in [1] and the possible overflow in [2].
-+ */
-+ return (long) (ppb * 65.536);
+}
+
+static void usage(char *progname)
@@ -472,7 +456,7 @@
+ if (0x7fffffff != adjfreq) {
+ memset(&tx, 0, sizeof(tx));
+ tx.modes = ADJ_FREQUENCY;
-+ tx.freq = ppb_to_scaled_ppm(adjfreq);
++ tx.freq = (long) (adjfreq * 65.536);
+ if (clock_adjtime(clkid, &tx)) {
+ perror("clock_adjtime");
+ } else {
@@ -650,7 +634,7 @@
+distclean: clean
+ rm -f $(PROGS)
diff --git a/drivers/Kconfig b/drivers/Kconfig
-index 177c7d1..6fd7446 100644
+index 9bfb71f..82ddceb 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -54,6 +54,8 @@ source "drivers/spi/Kconfig"
@@ -663,7 +647,7 @@
source "drivers/w1/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
-index 3f135b6..71ebbf9 100644
+index b423bb1..f9b3087 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_I2O) += message/
@@ -724,10 +708,10 @@
+obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
new file mode 100644
-index 0000000..1005987
+index 0000000..c806192
--- /dev/null
+++ b/drivers/ptp/ptp_chardev.c
-@@ -0,0 +1,155 @@
+@@ -0,0 +1,156 @@
+/*
+ * PTP 1588 clock support - character device implementation.
+ *
@@ -824,7 +808,7 @@
+ return err;
+}
+
-+unsigned int ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
++uint ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+{
+ struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+
@@ -842,9 +826,6 @@
+ unsigned long flags;
+ size_t qcnt, i;
+
-+ if (cnt % sizeof(struct ptp_extts_event) != 0)
-+ return -EINVAL;
-+
+ if (cnt > sizeof(event))
+ cnt = sizeof(event);
+
@@ -874,21 +855,25 @@
+
+ cnt = cnt * sizeof(struct ptp_extts_event);
+
-+ mutex_unlock(&ptp->tsevq_mux);
-+
+ if (copy_to_user(buf, event, cnt)) {
+ mutex_unlock(&ptp->tsevq_mux);
+ return -EFAULT;
+ }
+
++ mutex_unlock(&ptp->tsevq_mux);
+ return cnt;
++}
++
++int ptp_release(struct posix_clock *pc)
++{
++ return 0;
+}
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
new file mode 100644
-index 0000000..ef42a11
+index 0000000..1786a74
--- /dev/null
+++ b/drivers/ptp/ptp_clock.c
-@@ -0,0 +1,339 @@
+@@ -0,0 +1,320 @@
+/*
+ * PTP 1588 clock support
+ *
@@ -948,17 +933,15 @@
+{
+ struct ptp_extts_event *dst;
+ unsigned long flags;
-+ s64 seconds;
+ u32 remainder;
+
-+ seconds = div_u64_rem(src->timestamp, 1000000000, &remainder);
++ dst = &queue->buf[queue->tail];
++
++ dst->index = src->index;
++ dst->t.sec = div_u64_rem(src->timestamp, 1000000000, &remainder);
++ dst->t.nsec = remainder;
+
+ spin_lock_irqsave(&queue->lock, flags);
-+
-+ dst = &queue->buf[queue->tail];
-+ dst->index = src->index;
-+ dst->t.sec = seconds;
-+ dst->t.nsec = remainder;
+
+ if (!queue_free(queue))
+ queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
@@ -966,26 +949,6 @@
+ queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS;
+
+ spin_unlock_irqrestore(&queue->lock, flags);
-+}
-+
-+static s32 scaled_ppm_to_ppb(long ppm)
-+{
-+ /*
-+ * The 'freq' field in the 'struct timex' is in parts per
-+ * million, but with a 16 bit binary fractional field.
-+ *
-+ * We want to calculate
-+ *
-+ * ppb = scaled_ppm * 1000 / 2^16
-+ *
-+ * which simplifies to
-+ *
-+ * ppb = scaled_ppm * 125 / 2^13
-+ */
-+ s64 ppb = 1 + ppm;
-+ ppb *= 125;
-+ ppb >>= 13;
-+ return (s32) ppb;
+}
+
+/* posix clock implementation */
@@ -1034,8 +997,10 @@
+ err = ops->adjtime(ops, delta);
+
+ } else if (tx->modes & ADJ_FREQUENCY) {
-+
-+ err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
++ s64 ppb = 1 + tx->freq;
++ ppb *= 125;
++ ppb >>= 13;
++ err = ops->adjfreq(ops, (s32)ppb);
+ }
+
+ return err;
@@ -1051,6 +1016,7 @@
+ .open = ptp_open,
+ .poll = ptp_poll,
+ .read = ptp_read,
++ .release = ptp_release,
+};
+
+static void delete_ptp_clock(struct posix_clock *pc)
@@ -1230,10 +1196,10 @@
+MODULE_LICENSE("GPL");
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
new file mode 100644
-index 0000000..04fff62
+index 0000000..2f76266
--- /dev/null
+++ b/drivers/ptp/ptp_private.h
-@@ -0,0 +1,91 @@
+@@ -0,0 +1,86 @@
+/*
+ * PTP 1588 clock support - private declarations for the core module.
+ *
@@ -1286,13 +1252,6 @@
+ wait_queue_head_t tsev_wq;
+};
+
-+/*
-+ * The function queue_cnt() is safe for readers to call without
-+ * holding q->lock. Readers use this function to verify that the queue
-+ * is nonempty before proceeding with a dequeue operation. The fact
-+ * that a writer might concurrently increment the tail does not
-+ * matter, since the queue remains nonempty nonetheless.
-+ */
+static inline int queue_cnt(struct timestamp_event_queue *q)
+{
+ int cnt = q->tail - q->head;
@@ -1310,6 +1269,8 @@
+
+ssize_t ptp_read(struct posix_clock *pc,
+ uint flags, char __user *buf, size_t cnt);
++
++int ptp_release(struct posix_clock *pc);
+
+uint ptp_poll(struct posix_clock *pc,
+ struct file *fp, poll_table *wait);
@@ -1562,10 +1523,10 @@
+ return err;
+}
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
-index 75cf611..4585836 100644
+index b0ada6f..985ab2a 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
-@@ -302,6 +302,7 @@ header-y += ppp-comp.h
+@@ -300,6 +300,7 @@ header-y += ppp-comp.h
header-y += ppp_defs.h
header-y += pps.h
header-y += prctl.h