diff options
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r-- | arch/x86/kernel/hpet.c | 43 |
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 | ||
207 | static void hpet_legacy_clockevent_register(void) | 207 | static 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 | ||
325 | static int hpet_clocksource_register(void) | 324 | static 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 | ||