summaryrefslogtreecommitdiffstats
path: root/drivers/ptp/ptp_chardev.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-03-21 10:47:40 +0100
committerIngo Molnar <mingo@kernel.org>2016-03-21 10:47:40 +0100
commit42e405f7b1d252c90a2468dd2140f47b8142b7a0 (patch)
treebaeda52d8726fe694d3344a0d0fda1dadc30a901 /drivers/ptp/ptp_chardev.c
parentsched/cputime: Fix steal time accounting vs. CPU hotplug (diff)
parentMerge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/ke... (diff)
downloadlinux-42e405f7b1d252c90a2468dd2140f47b8142b7a0.tar.xz
linux-42e405f7b1d252c90a2468dd2140f47b8142b7a0.zip
Merge branch 'linus' into sched/urgent, to pick up dependencies
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/ptp/ptp_chardev.c')
-rw-r--r--drivers/ptp/ptp_chardev.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index da7bae991552..579fd65299a0 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -22,6 +22,7 @@
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/timekeeping.h>
#include "ptp_private.h"
@@ -120,11 +121,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 = NULL;
+ struct ptp_sys_offset_precise precise_offset;
struct ptp_pin_desc pd;
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct ptp_clock_info *ops = ptp->info;
struct ptp_clock_time *pct;
struct timespec64 ts;
+ struct system_device_crosststamp xtstamp;
int enable, err = 0;
unsigned int i, pin_index;
@@ -138,6 +141,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
caps.n_per_out = ptp->info->n_per_out;
caps.pps = ptp->info->pps;
caps.n_pins = ptp->info->n_pins;
+ caps.cross_timestamping = ptp->info->getcrosststamp != NULL;
if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
err = -EFAULT;
break;
@@ -180,6 +184,29 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = ops->enable(ops, &req, enable);
break;
+ case PTP_SYS_OFFSET_PRECISE:
+ if (!ptp->info->getcrosststamp) {
+ err = -EOPNOTSUPP;
+ break;
+ }
+ err = ptp->info->getcrosststamp(ptp->info, &xtstamp);
+ if (err)
+ break;
+
+ ts = ktime_to_timespec64(xtstamp.device);
+ precise_offset.device.sec = ts.tv_sec;
+ precise_offset.device.nsec = ts.tv_nsec;
+ ts = ktime_to_timespec64(xtstamp.sys_realtime);
+ precise_offset.sys_realtime.sec = ts.tv_sec;
+ precise_offset.sys_realtime.nsec = ts.tv_nsec;
+ ts = ktime_to_timespec64(xtstamp.sys_monoraw);
+ precise_offset.sys_monoraw.sec = ts.tv_sec;
+ precise_offset.sys_monoraw.nsec = ts.tv_nsec;
+ if (copy_to_user((void __user *)arg, &precise_offset,
+ sizeof(precise_offset)))
+ err = -EFAULT;
+ break;
+
case PTP_SYS_OFFSET:
sysoff = kmalloc(sizeof(*sysoff), GFP_KERNEL);
if (!sysoff) {