aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ptp
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2012-10-31 02:19:07 -0400
committerDavid S. Miller <davem@davemloft.net>2012-11-01 11:41:34 -0400
commit215b13dd288c2e1e4461c1530a801f5f83e8cd90 (patch)
treef4963077f13ab200a676636fe2d48993e73a2a8a /drivers/ptp
parenta24006ed12616bde1bbdb26868495906a212d8dc (diff)
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. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Acked-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp')
-rw-r--r--drivers/ptp/ptp_chardev.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index e7f301da2902..4f8ae8057a7e 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -33,9 +33,13 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
33{ 33{
34 struct ptp_clock_caps caps; 34 struct ptp_clock_caps caps;
35 struct ptp_clock_request req; 35 struct ptp_clock_request req;
36 struct ptp_sys_offset sysoff;
36 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); 37 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
37 struct ptp_clock_info *ops = ptp->info; 38 struct ptp_clock_info *ops = ptp->info;
39 struct ptp_clock_time *pct;
40 struct timespec ts;
38 int enable, err = 0; 41 int enable, err = 0;
42 unsigned int i;
39 43
40 switch (cmd) { 44 switch (cmd) {
41 45
@@ -88,6 +92,34 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
88 err = ops->enable(ops, &req, enable); 92 err = ops->enable(ops, &req, enable);
89 break; 93 break;
90 94
95 case PTP_SYS_OFFSET:
96 if (copy_from_user(&sysoff, (void __user *)arg,
97 sizeof(sysoff))) {
98 err = -EFAULT;
99 break;
100 }
101 if (sysoff.n_samples > PTP_MAX_SAMPLES) {
102 err = -EINVAL;
103 break;
104 }
105 pct = &sysoff.ts[0];
106 for (i = 0; i < sysoff.n_samples; i++) {
107 getnstimeofday(&ts);
108 pct->sec = ts.tv_sec;
109 pct->nsec = ts.tv_nsec;
110 pct++;
111 ptp->info->gettime(ptp->info, &ts);
112 pct->sec = ts.tv_sec;
113 pct->nsec = ts.tv_nsec;
114 pct++;
115 }
116 getnstimeofday(&ts);
117 pct->sec = ts.tv_sec;
118 pct->nsec = ts.tv_nsec;
119 if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff)))
120 err = -EFAULT;
121 break;
122
91 default: 123 default:
92 err = -ENOTTY; 124 err = -ENOTTY;
93 break; 125 break;