aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/hpet.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r--arch/x86/kernel/hpet.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 9b5cfcdfc426..ea230ec69057 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -17,7 +17,7 @@
17 17
18/* FSEC = 10^-15 18/* FSEC = 10^-15
19 NSEC = 10^-9 */ 19 NSEC = 10^-9 */
20#define FSEC_PER_NSEC 1000000 20#define FSEC_PER_NSEC 1000000L
21 21
22/* 22/*
23 * HPET address is set in acpi/boot.c, when an ACPI entry exists 23 * HPET address is set in acpi/boot.c, when an ACPI entry exists
@@ -206,20 +206,19 @@ static void hpet_enable_legacy_int(void)
206 206
207static void hpet_legacy_clockevent_register(void) 207static void hpet_legacy_clockevent_register(void)
208{ 208{
209 uint64_t hpet_freq;
210
211 /* Start HPET legacy interrupts */ 209 /* Start HPET legacy interrupts */
212 hpet_enable_legacy_int(); 210 hpet_enable_legacy_int();
213 211
214 /* 212 /*
215 * The period is a femto seconds value. We need to calculate the 213 * The mult factor is defined as (include/linux/clockchips.h)
216 * scaled math multiplication factor for nanosecond to hpet tick 214 * mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h)
217 * conversion. 215 * hpet_period is in units of femtoseconds (per cycle), so
216 * mult/2^shift = cyc/ns = 10^6/hpet_period
217 * mult = (10^6 * 2^shift)/hpet_period
218 * mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period
218 */ 219 */
219 hpet_freq = 1000000000000000ULL; 220 hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC,
220 do_div(hpet_freq, hpet_period); 221 hpet_period, hpet_clockevent.shift);
221 hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
222 NSEC_PER_SEC, hpet_clockevent.shift);
223 /* Calculate the min / max delta */ 222 /* Calculate the min / max delta */
224 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, 223 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
225 &hpet_clockevent); 224 &hpet_clockevent);
@@ -324,7 +323,7 @@ static struct clocksource clocksource_hpet = {
324 323
325static int hpet_clocksource_register(void) 324static int hpet_clocksource_register(void)
326{ 325{
327 u64 tmp, start, now; 326 u64 start, now;
328 cycle_t t1; 327 cycle_t t1;
329 328
330 /* Start the counter */ 329 /* Start the counter */
@@ -351,21 +350,15 @@ static int hpet_clocksource_register(void)
351 return -ENODEV; 350 return -ENODEV;
352 } 351 }
353 352
354 /* Initialize and register HPET clocksource 353 /*
355 * 354 * The definition of mult is (include/linux/clocksource.h)
356 * hpet period is in femto seconds per cycle 355 * mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc
357 * so we need to convert this to ns/cyc units 356 * so we first need to convert hpet_period to ns/cyc units:
358 * approximated by mult/2^shift 357 * mult/2^shift = ns/cyc = hpet_period/10^6
359 * 358 * mult = (hpet_period * 2^shift)/10^6
360 * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift 359 * mult = (hpet_period << shift)/FSEC_PER_NSEC
361 * fsec/cyc * 1ns/1000000fsec * 2^shift = mult
362 * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
363 * (fsec/cyc << shift)/1000000 = mult
364 * (hpet_period << shift)/FSEC_PER_NSEC = mult
365 */ 360 */
366 tmp = (u64)hpet_period << HPET_SHIFT; 361 clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
367 do_div(tmp, FSEC_PER_NSEC);
368 clocksource_hpet.mult = (u32)tmp;
369 362
370 clocksource_register(&clocksource_hpet); 363 clocksource_register(&clocksource_hpet);
371 364