Skip to content

Commit

Permalink
ptp: add an ioctl to compare PHC time with system time
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Richard Cochran authored and David S. Miller committed Nov 1, 2012
1 parent a24006e commit 215b13d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/ptp/ptp_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand Down Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions include/uapi/linux/ptp_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down

0 comments on commit 215b13d

Please sign in to comment.