diff options
-rw-r--r-- | arch/x86/include/asm/tsc.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 39 |
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 | ||
33 | extern struct system_counterval_t convert_art_to_tsc(u64 art); | 33 | extern struct system_counterval_t convert_art_to_tsc(u64 art); |
34 | extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns); | ||
34 | 35 | ||
35 | extern void tsc_early_delay_calibrate(void); | 36 | extern void tsc_early_delay_calibrate(void); |
36 | extern void tsc_init(void); | 37 | extern 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 | } |
1180 | EXPORT_SYMBOL(convert_art_to_tsc); | 1180 | EXPORT_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 | |||
1203 | struct 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 | } | ||
1218 | EXPORT_SYMBOL(convert_art_ns_to_tsc); | ||
1219 | |||
1220 | |||
1182 | static void tsc_refine_calibration_work(struct work_struct *work); | 1221 | static void tsc_refine_calibration_work(struct work_struct *work); |
1183 | static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work); | 1222 | static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work); |
1184 | /** | 1223 | /** |