An upcoming extension to the PTP IOCTL requires to return the system counter
value and the clocksource ID to user space. get_device_system_crosststamp() has
this information already.

Extend struct system_device_crosststamp with a system_counterval_t member
and fill in the data.

Signed-off-by: Thomas Gleixner <[email protected]>
---
 include/linux/timekeeping.h |   28 ++++++++++++++------------
 kernel/time/timekeeping.c   |   46 ++++++++++++++++++++------------------------
 2 files changed, 36 insertions(+), 38 deletions(-)

--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -297,19 +297,6 @@ struct system_time_snapshot {
 };
 
 /**
- * struct system_device_crosststamp - system/device cross-timestamp
- *                                   (synchronized capture)
- * @device:            Device time
- * @sys_realtime:      Realtime simultaneous with device time
- * @sys_monoraw:       Monotonic raw simultaneous with device time
- */
-struct system_device_crosststamp {
-       ktime_t device;
-       ktime_t sys_realtime;
-       ktime_t sys_monoraw;
-};
-
-/**
  * struct system_counterval_t - system counter value with the ID of the
  *                             corresponding clocksource
  * @cycles:    System counter value
@@ -325,6 +312,21 @@ struct system_counterval_t {
        bool                    use_nsecs;
 };
 
+/**
+ * struct system_device_crosststamp - system/device cross-timestamp
+ *                                   (synchronized capture)
+ * @device:            Device time
+ * @sys_counter:       Clocksource counter value simultaneous with device time
+ * @sys_realtime:      Realtime simultaneous with device time
+ * @sys_monoraw:       Monotonic raw simultaneous with device time
+ */
+struct system_device_crosststamp {
+       ktime_t                         device;
+       struct system_counterval_t      sys_counter;
+       ktime_t                         sys_realtime;
+       ktime_t                         sys_monoraw;
+};
+
 extern bool ktime_real_to_base_clock(ktime_t treal,
                                     enum clocksource_ids base_id, u64 *cycles);
 extern bool timekeeping_clocksource_has_base(enum clocksource_ids id);
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1419,6 +1419,8 @@ static bool convert_base_to_cs(struct sy
                return false;
 
        scv->cycles += base->offset;
+       /* Set the clocksource ID as scv::cycles is now clocksource based */
+       scv->cs_id = cs->id;
        return true;
 }
 
@@ -1486,11 +1488,11 @@ EXPORT_SYMBOL_GPL(ktime_real_to_base_clo
 
 /**
  * get_device_system_crosststamp - Synchronously capture system/device 
timestamp
- * @get_time_fn:       Callback to get simultaneous device time and
- *     system counter from the device driver
+ * @get_time_fn:       Callback to get simultaneous device time and system 
counter
+ *                     from the device driver
  * @ctx:               Context passed to get_time_fn()
- * @history_begin:     Historical reference point used to interpolate system
- *     time when counter provided by the driver is before the current interval
+ * @history_begin:     Historical reference point used to interpolate system 
time when
+ *                     the counter value provided by the driver is before the 
current interval
  * @xtstamp:           Receives simultaneously captured system and device time
  *
  * Reads a timestamp from a device and correlates it to system time
@@ -1503,14 +1505,12 @@ int get_device_system_crosststamp(int (*
                                  struct system_time_snapshot *history_begin,
                                  struct system_device_crosststamp *xtstamp)
 {
-       struct system_counterval_t system_counterval = {};
+       u64 syscnt_cycles, cycles, now, interval_start;
        struct timekeeper *tk = &tk_core.timekeeper;
-       u64 cycles, now, interval_start;
-       unsigned int clock_was_set_seq = 0;
+       unsigned int seq, clock_was_set_seq = 0;
        ktime_t base_real, base_raw;
        u64 nsec_real, nsec_raw;
        u8 cs_was_changed_seq;
-       unsigned int seq;
        bool do_interp;
        int ret;
 
@@ -1520,19 +1520,20 @@ int get_device_system_crosststamp(int (*
                 * Try to synchronously capture device time and a system
                 * counter value calling back into the device driver
                 */
-               ret = get_time_fn(&xtstamp->device, &system_counterval, ctx);
+               ret = get_time_fn(&xtstamp->device, &xtstamp->sys_counter, ctx);
                if (ret)
                        return ret;
 
                /*
                 * Verify that the clocksource ID associated with the captured
                 * system counter value is the same as for the currently
-                * installed timekeeper clocksource
+                * installed timekeeper clocksource and convert to it.
                 */
-               if (system_counterval.cs_id == CSID_GENERIC ||
-                   !convert_base_to_cs(&system_counterval))
+               if (xtstamp->sys_counter.cs_id == CSID_GENERIC ||
+                   !convert_base_to_cs(&xtstamp->sys_counter))
                        return -ENODEV;
-               cycles = system_counterval.cycles;
+
+               cycles = syscnt_cycles = xtstamp->sys_counter.cycles;
 
                /*
                 * Check whether the system counter value provided by the
@@ -1574,24 +1575,19 @@ int get_device_system_crosststamp(int (*
                 * clocksource change
                 */
                if (!history_begin ||
-                   !timestamp_in_interval(history_begin->cycles,
-                                          cycles, system_counterval.cycles) ||
+                   !timestamp_in_interval(history_begin->cycles, cycles, 
syscnt_cycles) ||
                    history_begin->cs_was_changed_seq != cs_was_changed_seq)
                        return -EINVAL;
-               partial_history_cycles = cycles - system_counterval.cycles;
+
+               partial_history_cycles = cycles - syscnt_cycles;
                total_history_cycles = cycles - history_begin->cycles;
-               discontinuity =
-                       history_begin->clock_was_set_seq != clock_was_set_seq;
+               discontinuity = history_begin->clock_was_set_seq != 
clock_was_set_seq;
 
-               ret = adjust_historical_crosststamp(history_begin,
-                                                   partial_history_cycles,
-                                                   total_history_cycles,
-                                                   discontinuity, xtstamp);
-               if (ret)
-                       return ret;
+               ret = adjust_historical_crosststamp(history_begin, 
partial_history_cycles,
+                                                   total_history_cycles, 
discontinuity, xtstamp);
        }
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(get_device_system_crosststamp);
 


Reply via email to