diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-05-18 17:33:43 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-05-19 08:24:16 -0400 |
commit | ab0e08f15d23628dd8d50bf6ce1a935a8840c7dc (patch) | |
tree | 04cfc2202180f840d71a60e7ba4d48cc3003bc76 /arch/x86/kernel/hpet.c | |
parent | 61ee9a4ba05f0a4163d43a33dee7a0651e080b98 (diff) |
x86: hpet: Cleanup the clockevents init and register code
No need to recalculate the frequency and the conversion factors over
and over. Calculate the frequency once and use the new config/register
interface and let the core code do the math.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Link: http://lkml.kernel.org/r/%3C20110518210136.646482357%40linutronix.de%3E
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r-- | arch/x86/kernel/hpet.c | 72 |
1 files changed, 16 insertions, 56 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index bfe8f729e086..6781765b3a0d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -217,7 +217,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { } | |||
217 | /* | 217 | /* |
218 | * Common hpet info | 218 | * Common hpet info |
219 | */ | 219 | */ |
220 | static unsigned long hpet_period; | 220 | static unsigned long hpet_freq; |
221 | 221 | ||
222 | static void hpet_legacy_set_mode(enum clock_event_mode mode, | 222 | static void hpet_legacy_set_mode(enum clock_event_mode mode, |
223 | struct clock_event_device *evt); | 223 | struct clock_event_device *evt); |
@@ -232,7 +232,6 @@ static struct clock_event_device hpet_clockevent = { | |||
232 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 232 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
233 | .set_mode = hpet_legacy_set_mode, | 233 | .set_mode = hpet_legacy_set_mode, |
234 | .set_next_event = hpet_legacy_next_event, | 234 | .set_next_event = hpet_legacy_next_event, |
235 | .shift = 32, | ||
236 | .irq = 0, | 235 | .irq = 0, |
237 | .rating = 50, | 236 | .rating = 50, |
238 | }; | 237 | }; |
@@ -290,28 +289,12 @@ static void hpet_legacy_clockevent_register(void) | |||
290 | hpet_enable_legacy_int(); | 289 | hpet_enable_legacy_int(); |
291 | 290 | ||
292 | /* | 291 | /* |
293 | * The mult factor is defined as (include/linux/clockchips.h) | ||
294 | * mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h) | ||
295 | * hpet_period is in units of femtoseconds (per cycle), so | ||
296 | * mult/2^shift = cyc/ns = 10^6/hpet_period | ||
297 | * mult = (10^6 * 2^shift)/hpet_period | ||
298 | * mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period | ||
299 | */ | ||
300 | hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC, | ||
301 | hpet_period, hpet_clockevent.shift); | ||
302 | /* Calculate the min / max delta */ | ||
303 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | ||
304 | &hpet_clockevent); | ||
305 | /* Setup minimum reprogramming delta. */ | ||
306 | hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, | ||
307 | &hpet_clockevent); | ||
308 | |||
309 | /* | ||
310 | * Start hpet with the boot cpu mask and make it | 292 | * Start hpet with the boot cpu mask and make it |
311 | * global after the IO_APIC has been initialized. | 293 | * global after the IO_APIC has been initialized. |
312 | */ | 294 | */ |
313 | hpet_clockevent.cpumask = cpumask_of(smp_processor_id()); | 295 | hpet_clockevent.cpumask = cpumask_of(smp_processor_id()); |
314 | clockevents_register_device(&hpet_clockevent); | 296 | clockevents_config_and_register(&hpet_clockevent, hpet_freq, |
297 | HPET_MIN_PROG_DELTA, 0x7FFFFFFF); | ||
315 | global_clock_event = &hpet_clockevent; | 298 | global_clock_event = &hpet_clockevent; |
316 | printk(KERN_DEBUG "hpet clockevent registered\n"); | 299 | printk(KERN_DEBUG "hpet clockevent registered\n"); |
317 | } | 300 | } |
@@ -549,7 +532,6 @@ static int hpet_setup_irq(struct hpet_dev *dev) | |||
549 | static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) | 532 | static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) |
550 | { | 533 | { |
551 | struct clock_event_device *evt = &hdev->evt; | 534 | struct clock_event_device *evt = &hdev->evt; |
552 | uint64_t hpet_freq; | ||
553 | 535 | ||
554 | WARN_ON(cpu != smp_processor_id()); | 536 | WARN_ON(cpu != smp_processor_id()); |
555 | if (!(hdev->flags & HPET_DEV_VALID)) | 537 | if (!(hdev->flags & HPET_DEV_VALID)) |
@@ -571,24 +553,10 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) | |||
571 | 553 | ||
572 | evt->set_mode = hpet_msi_set_mode; | 554 | evt->set_mode = hpet_msi_set_mode; |
573 | evt->set_next_event = hpet_msi_next_event; | 555 | evt->set_next_event = hpet_msi_next_event; |
574 | evt->shift = 32; | ||
575 | |||
576 | /* | ||
577 | * The period is a femto seconds value. We need to calculate the | ||
578 | * scaled math multiplication factor for nanosecond to hpet tick | ||
579 | * conversion. | ||
580 | */ | ||
581 | hpet_freq = FSEC_PER_SEC; | ||
582 | do_div(hpet_freq, hpet_period); | ||
583 | evt->mult = div_sc((unsigned long) hpet_freq, | ||
584 | NSEC_PER_SEC, evt->shift); | ||
585 | /* Calculate the max delta */ | ||
586 | evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt); | ||
587 | /* 5 usec minimum reprogramming delta. */ | ||
588 | evt->min_delta_ns = 5000; | ||
589 | |||
590 | evt->cpumask = cpumask_of(hdev->cpu); | 556 | evt->cpumask = cpumask_of(hdev->cpu); |
591 | clockevents_register_device(evt); | 557 | |
558 | clockevents_config_and_register(evt, hpet_freq, HPET_MIN_PROG_DELTA, | ||
559 | 0x7FFFFFFF); | ||
592 | } | 560 | } |
593 | 561 | ||
594 | #ifdef CONFIG_HPET | 562 | #ifdef CONFIG_HPET |
@@ -792,7 +760,6 @@ static struct clocksource clocksource_hpet = { | |||
792 | static int hpet_clocksource_register(void) | 760 | static int hpet_clocksource_register(void) |
793 | { | 761 | { |
794 | u64 start, now; | 762 | u64 start, now; |
795 | u64 hpet_freq; | ||
796 | cycle_t t1; | 763 | cycle_t t1; |
797 | 764 | ||
798 | /* Start the counter */ | 765 | /* Start the counter */ |
@@ -819,24 +786,7 @@ static int hpet_clocksource_register(void) | |||
819 | return -ENODEV; | 786 | return -ENODEV; |
820 | } | 787 | } |
821 | 788 | ||
822 | /* | ||
823 | * The definition of mult is (include/linux/clocksource.h) | ||
824 | * mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc | ||
825 | * so we first need to convert hpet_period to ns/cyc units: | ||
826 | * mult/2^shift = ns/cyc = hpet_period/10^6 | ||
827 | * mult = (hpet_period * 2^shift)/10^6 | ||
828 | * mult = (hpet_period << shift)/FSEC_PER_NSEC | ||
829 | */ | ||
830 | |||
831 | /* Need to convert hpet_period (fsec/cyc) to cyc/sec: | ||
832 | * | ||
833 | * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc) | ||
834 | * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period | ||
835 | */ | ||
836 | hpet_freq = FSEC_PER_SEC; | ||
837 | do_div(hpet_freq, hpet_period); | ||
838 | clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); | 789 | clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); |
839 | |||
840 | return 0; | 790 | return 0; |
841 | } | 791 | } |
842 | 792 | ||
@@ -845,7 +795,9 @@ static int hpet_clocksource_register(void) | |||
845 | */ | 795 | */ |
846 | int __init hpet_enable(void) | 796 | int __init hpet_enable(void) |
847 | { | 797 | { |
798 | unsigned long hpet_period; | ||
848 | unsigned int id; | 799 | unsigned int id; |
800 | u64 freq; | ||
849 | int i; | 801 | int i; |
850 | 802 | ||
851 | if (!is_hpet_capable()) | 803 | if (!is_hpet_capable()) |
@@ -884,6 +836,14 @@ int __init hpet_enable(void) | |||
884 | goto out_nohpet; | 836 | goto out_nohpet; |
885 | 837 | ||
886 | /* | 838 | /* |
839 | * The period is a femto seconds value. Convert it to a | ||
840 | * frequency. | ||
841 | */ | ||
842 | freq = FSEC_PER_SEC; | ||
843 | do_div(freq, hpet_period); | ||
844 | hpet_freq = freq; | ||
845 | |||
846 | /* | ||
887 | * Read the HPET ID register to retrieve the IRQ routing | 847 | * Read the HPET ID register to retrieve the IRQ routing |
888 | * information and the number of channels | 848 | * information and the number of channels |
889 | */ | 849 | */ |