aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/tsc.h1
-rw-r--r--arch/x86/kernel/tsc.c39
2 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index cf5d53c3f9ea..2701d221583a 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -31,6 +31,7 @@ static inline cycles_t get_cycles(void)
31} 31}
32 32
33extern struct system_counterval_t convert_art_to_tsc(u64 art); 33extern struct system_counterval_t convert_art_to_tsc(u64 art);
34extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
34 35
35extern void tsc_early_delay_calibrate(void); 36extern void tsc_early_delay_calibrate(void);
36extern void tsc_init(void); 37extern void tsc_init(void);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index fb4302738410..ef32297ff17e 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1179,6 +1179,45 @@ struct system_counterval_t convert_art_to_tsc(u64 art)
1179} 1179}
1180EXPORT_SYMBOL(convert_art_to_tsc); 1180EXPORT_SYMBOL(convert_art_to_tsc);
1181 1181
1182/**
1183 * convert_art_ns_to_tsc() - Convert ART in nanoseconds to TSC.
1184 * @art_ns: ART (Always Running Timer) in unit of nanoseconds
1185 *
1186 * PTM requires all timestamps to be in units of nanoseconds. When user
1187 * software requests a cross-timestamp, this function converts system timestamp
1188 * to TSC.
1189 *
1190 * This is valid when CPU feature flag X86_FEATURE_TSC_KNOWN_FREQ is set
1191 * indicating the tsc_khz is derived from CPUID[15H]. Drivers should check
1192 * that this flag is set before conversion to TSC is attempted.
1193 *
1194 * Return:
1195 * struct system_counterval_t - system counter value with the pointer to the
1196 * corresponding clocksource
1197 * @cycles: System counter value
1198 * @cs: Clocksource corresponding to system counter value. Used
1199 * by timekeeping code to verify comparibility of two cycle
1200 * values.
1201 */
1202
1203struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
1204{
1205 u64 tmp, res, rem;
1206
1207 rem = do_div(art_ns, USEC_PER_SEC);
1208
1209 res = art_ns * tsc_khz;
1210 tmp = rem * tsc_khz;
1211
1212 do_div(tmp, USEC_PER_SEC);
1213 res += tmp;
1214
1215 return (struct system_counterval_t) { .cs = art_related_clocksource,
1216 .cycles = res};
1217}
1218EXPORT_SYMBOL(convert_art_ns_to_tsc);
1219
1220
1182static void tsc_refine_calibration_work(struct work_struct *work); 1221static void tsc_refine_calibration_work(struct work_struct *work);
1183static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work); 1222static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
1184/** 1223/**