Skip to contentSkip to conversation

ptp: add pseudo pps ioctl

PATCH Applied Richard Cochran 2 participants 3 messages Oct 31, 2012 – Nov 1, 2012

Subsystems (3)
lore
Share & tools
lore

Richard Cochran

author maintainer
#0 lore raw

v2 cover ptp: add pseudo pps ioctl

No changes in V2, except removing the RFC label and adding Jacob's ack.

This patch adds a kind of "poor man's PPS" for use with those PHC drivers which do not support a true PPS. Using this ioctl, user space can estimate the system-phc offset and tune one of the clocks as desired.

This patch has been tested on both the Intel igb (PCIe card) and the National Semiconductor phyter (PHY via MDIO bus), and the results seem quite promising.

This patch avoids the "timecompare" code on purpose, since experiments have shown that code to be quite brittle, having been tuned to only one specific kind of hardware.

Thanks,
Richard

Richard Cochran (1):
ptp: add an ioctl to compare PHC time with system time

 drivers/ptp/ptp_chardev.c      |   32 ++++++++++++++++++++++++++++++++
 include/uapi/linux/ptp_clock.h |   14 ++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)
Signature · 1 line
1.7.2.5
author maintainer
#1 lore raw

PATCH v2 1/1 ptp: add an ioctl to compare PHC time with system time

This patch adds an ioctl for PTP Hardware Clock (PHC) devices that allows user space to measure the time offset between the PHC and the system clock. Rather than hard coding any kind of estimation algorithm into the kernel, this patch takes the more flexible approach of just delivering an array of raw clock readings. In that way, the user space clock servo may be adapted to new and different hardware clocks.

---
 drivers/ptp/ptp_chardev.c      |   32 ++++++++++++++++++++++++++++++++
 include/uapi/linux/ptp_clock.h |   14 ++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)
drivers/ptp/ptp_chardev.c +32 -0
index e7f301da2..4f8ae80 100644
@@ -33,9 +33,13 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
 {
 	struct ptp_clock_caps caps;
 	struct ptp_clock_request req;
+	struct ptp_sys_offset sysoff;
 	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
 	struct ptp_clock_info *ops = ptp->info;
+	struct ptp_clock_time *pct;
+	struct timespec ts;
 	int enable, err = 0;
+	unsigned int i;
 
 	switch (cmd) {
 
@@ -88,6 +92,34 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
 		err = ops->enable(ops, &req, enable);
 		break;
 
+	case PTP_SYS_OFFSET:
+		if (copy_from_user(&sysoff, (void __user *)arg,
+				   sizeof(sysoff))) {
+			err = -EFAULT;
+			break;
+		}
+		if (sysoff.n_samples > PTP_MAX_SAMPLES) {
+			err = -EINVAL;
+			break;
+		}
+		pct = &sysoff.ts[0];
+		for (i = 0; i < sysoff.n_samples; i++) {
+			getnstimeofday(&ts);
+			pct->sec = ts.tv_sec;
+			pct->nsec = ts.tv_nsec;
+			pct++;
+			ptp->info->gettime(ptp->info, &ts);
+			pct->sec = ts.tv_sec;
+			pct->nsec = ts.tv_nsec;
+			pct++;
+		}
+		getnstimeofday(&ts);
+		pct->sec = ts.tv_sec;
+		pct->nsec = ts.tv_nsec;
+		if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff)))
+			err = -EFAULT;
+		break;
+
 	default:
 		err = -ENOTTY;
 		break;
include/uapi/linux/ptp_clock.h +14 -0
index 94e981f..b65c834 100644
@@ -67,12 +67,26 @@ struct ptp_perout_request {
 	unsigned int rsv[4];          /* Reserved for future use. */
 };
 
+#define PTP_MAX_SAMPLES 25 /* Maximum allowed offset measurement samples. */
+
+struct ptp_sys_offset {
+	unsigned int n_samples; /* Desired number of measurements. */
+	unsigned int rsv[3];    /* Reserved for future use. */
+	/*
+	 * Array of interleaved system/phc time stamps. The kernel
+	 * will provide 2*n_samples + 1 time stamps, with the last
+	 * one as a system time stamp.
+	 */
+	struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
+};
+
 #define PTP_CLK_MAGIC '='
 
 #define PTP_CLOCK_GETCAPS  _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps)
 #define PTP_EXTTS_REQUEST  _IOW(PTP_CLK_MAGIC, 2, struct ptp_extts_request)
 #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request)
 #define PTP_ENABLE_PPS     _IOW(PTP_CLK_MAGIC, 4, int)
+#define PTP_SYS_OFFSET     _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
 
 struct ptp_extts_event {
 	struct ptp_clock_time t; /* Time event occured. */
Signature · 1 line
1.7.2.5
maintainer Applied
#2 lore raw

Re: [PATCH V2 net-next 1/1] ptp: add an ioctl to compare PHC time with system time

From: Richard Cochran <[email protected]>
Date: Wed, 31 Oct 2012 17:19:07 +0100

Quoted 9 lines

This patch adds an ioctl for PTP Hardware Clock (PHC) devices that allows user space to measure the time offset between the PHC and the system clock. Rather than hard coding any kind of estimation algorithm into the kernel, this patch takes the more flexible approach of just delivering an array of raw clock readings. In that way, the user space clock servo may be adapted to new and different hardware clocks.

Applied.