diff options
author | Carlos R. Mafra <crmafra2@gmail.com> | 2008-05-05 19:11:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-05-12 15:27:54 -0400 |
commit | 6fd592daae2182adc47f405e20d07f34f52d07dd (patch) | |
tree | f550699d83e803c99e758aca80b79e9608770170 /arch/x86/kernel/hpet.c | |
parent | 492c2e476eac010962850006c49df326919b284c (diff) |
x86: clean up computation of HPET .mult variables
While reading through the HPET code I realized that the
computation of .mult variables could be done with less
lines of code, resulting in a 1.6% text size saving
for hpet.o
So I propose the following patch, which applies against
today's Linus -git tree.
>From 0c6507e400e9ca5f7f14331e18f8c12baf75a9d3 Mon Sep 17 00:00:00 2001
From: Carlos R. Mafra <crmafra@ift.unesp.br>
Date: Mon, 5 May 2008 19:38:53 -0300
The computation of clocksource_hpet.mult
tmp = (u64)hpet_period << HPET_SHIFT;
do_div(tmp, FSEC_PER_NSEC);
clocksource_hpet.mult = (u32)tmp;
can be streamlined if we note that it is equal to
clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
Furthermore, the computation of hpet_clockevent.mult
uint64_t hpet_freq;
hpet_freq = 1000000000000000ULL;
do_div(hpet_freq, hpet_period);
hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
NSEC_PER_SEC, hpet_clockevent.shift);
can also be streamlined with the observation that hpet_period and hpet_freq are
inverse to each other (in proper units).
So instead of computing hpet_freq and using (schematically)
div_sc(hpet_freq, 10^9, shift) we use the trick of calling with the
arguments in reverse order, div_sc(10^6, hpet_period, shift).
The different power of ten is due to frequency being in Hertz (1/sec)
and the period being in units of femtosecond. Explicitly,
mult = (hpet_freq * 2^shift)/10^9 (before)
mult = (10^6 * 2^shift)/hpet_period (after)
because hpet_freq = 10^15/hpet_period.
The comments in the code are also updated to reflect the changes.
As a result,
text data bss dec hex filename
2957 425 92 3474 d92 arch/x86/kernel/hpet.o
3006 425 92 3523 dc3 arch/x86/kernel/hpet.o.old
a 1.6% reduction in text size.
Signed-off-by: Carlos R. Mafra <crmafra@ift.unesp.br>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
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 9b5cfcdfc42..ea230ec6905 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 | ||