Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64...
[sfrench/cifs-2.6.git] / arch / x86 / kernel / tsc.c
index fb430273841023fd1ebf3507440cd5510f37b012..ef32297ff17e5bdc6a852bb38f88546f90e0af22 100644 (file)
@@ -1179,6 +1179,45 @@ struct system_counterval_t convert_art_to_tsc(u64 art)
 }
 EXPORT_SYMBOL(convert_art_to_tsc);
 
+/**
+ * convert_art_ns_to_tsc() - Convert ART in nanoseconds to TSC.
+ * @art_ns: ART (Always Running Timer) in unit of nanoseconds
+ *
+ * PTM requires all timestamps to be in units of nanoseconds. When user
+ * software requests a cross-timestamp, this function converts system timestamp
+ * to TSC.
+ *
+ * This is valid when CPU feature flag X86_FEATURE_TSC_KNOWN_FREQ is set
+ * indicating the tsc_khz is derived from CPUID[15H]. Drivers should check
+ * that this flag is set before conversion to TSC is attempted.
+ *
+ * Return:
+ * struct system_counterval_t - system counter value with the pointer to the
+ *     corresponding clocksource
+ *     @cycles:        System counter value
+ *     @cs:            Clocksource corresponding to system counter value. Used
+ *                     by timekeeping code to verify comparibility of two cycle
+ *                     values.
+ */
+
+struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
+{
+       u64 tmp, res, rem;
+
+       rem = do_div(art_ns, USEC_PER_SEC);
+
+       res = art_ns * tsc_khz;
+       tmp = rem * tsc_khz;
+
+       do_div(tmp, USEC_PER_SEC);
+       res += tmp;
+
+       return (struct system_counterval_t) { .cs = art_related_clocksource,
+                                             .cycles = res};
+}
+EXPORT_SYMBOL(convert_art_ns_to_tsc);
+
+
 static void tsc_refine_calibration_work(struct work_struct *work);
 static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
 /**