"  %d external time stamp channels\n"
                               "  %d programmable periodic signals\n"
                               "  %d pulse per second\n"
-                              "  %d programmable pins\n",
+                              "  %d programmable pins\n"
+                              "  %d cross timestamping\n",
                               caps.max_adj,
                               caps.n_alarm,
                               caps.n_ext_ts,
                               caps.n_per_out,
                               caps.pps,
-                              caps.n_pins);
+                              caps.n_pins,
+                              caps.cross_timestamping);
                }
        }
 
 
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #include "ptp_private.h"
 
        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;
 
                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;
                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) {
 
        };
 };
 
+struct system_device_crosststamp;
 /**
  * struct ptp_clock_info - decribes a PTP hardware clock
  *
  * @gettime64:  Reads the current time from the hardware clock.
  *              parameter ts: Holds the result.
  *
+ * @getcrosststamp:  Reads the current time from the hardware clock and
+ *                   system clock simultaneously.
+ *                   parameter cts: Contains timestamp (device,system) pair,
+ *                   where system time is realtime and monotonic.
+ *
  * @settime64:  Set the current time on the hardware clock.
  *              parameter ts: Time value to set.
  *
        int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
        int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
        int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
+       int (*getcrosststamp)(struct ptp_clock_info *ptp,
+                             struct system_device_crosststamp *cts);
        int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts);
        int (*enable)(struct ptp_clock_info *ptp,
                      struct ptp_clock_request *request, int on);
 
        int n_per_out; /* Number of programmable periodic signals. */
        int pps;       /* Whether the clock supports a PPS callback. */
        int n_pins;    /* Number of input/output pins. */
-       int rsv[14];   /* Reserved for future use. */
+       /* Whether the clock supports precise system-device cross timestamps */
+       int cross_timestamping;
+       int rsv[13];   /* Reserved for future use. */
 };
 
 struct ptp_extts_request {
        struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
 };
 
+struct ptp_sys_offset_precise {
+       struct ptp_clock_time device;
+       struct ptp_clock_time sys_realtime;
+       struct ptp_clock_time sys_monoraw;
+       unsigned int rsv[4];    /* Reserved for future use. */
+};
+
 enum ptp_pin_function {
        PTP_PF_NONE,
        PTP_PF_EXTTS,
 #define PTP_SYS_OFFSET     _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
 #define PTP_PIN_GETFUNC    _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
 #define PTP_PIN_SETFUNC    _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
+#define PTP_SYS_OFFSET_PRECISE \
+       _IOWR(PTP_CLK_MAGIC, 8, struct ptp_sys_offset_precise)
 
 struct ptp_extts_event {
        struct ptp_clock_time t; /* Time event occured. */