Commit ab0e08f1 authored by Thomas Gleixner's avatar Thomas Gleixner

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: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Reviewed-by: default avatarIngo Molnar <mingo@elte.hu>
Link: http://lkml.kernel.org/r/%3C20110518210136.646482357%40linutronix.de%3E
parent 61ee9a4b
...@@ -217,7 +217,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { } ...@@ -217,7 +217,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
/* /*
* Common hpet info * Common hpet info
*/ */
static unsigned long hpet_period; static unsigned long hpet_freq;
static void hpet_legacy_set_mode(enum clock_event_mode mode, static void hpet_legacy_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt); struct clock_event_device *evt);
...@@ -232,7 +232,6 @@ static struct clock_event_device hpet_clockevent = { ...@@ -232,7 +232,6 @@ static struct clock_event_device hpet_clockevent = {
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = hpet_legacy_set_mode, .set_mode = hpet_legacy_set_mode,
.set_next_event = hpet_legacy_next_event, .set_next_event = hpet_legacy_next_event,
.shift = 32,
.irq = 0, .irq = 0,
.rating = 50, .rating = 50,
}; };
...@@ -289,29 +288,13 @@ static void hpet_legacy_clockevent_register(void) ...@@ -289,29 +288,13 @@ static void hpet_legacy_clockevent_register(void)
/* Start HPET legacy interrupts */ /* Start HPET legacy interrupts */
hpet_enable_legacy_int(); hpet_enable_legacy_int();
/*
* The mult factor is defined as (include/linux/clockchips.h)
* mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h)
* hpet_period is in units of femtoseconds (per cycle), so
* mult/2^shift = cyc/ns = 10^6/hpet_period
* mult = (10^6 * 2^shift)/hpet_period
* mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period
*/
hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC,
hpet_period, hpet_clockevent.shift);
/* Calculate the min / max delta */
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
&hpet_clockevent);
/* Setup minimum reprogramming delta. */
hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
&hpet_clockevent);
/* /*
* Start hpet with the boot cpu mask and make it * Start hpet with the boot cpu mask and make it
* global after the IO_APIC has been initialized. * global after the IO_APIC has been initialized.
*/ */
hpet_clockevent.cpumask = cpumask_of(smp_processor_id()); hpet_clockevent.cpumask = cpumask_of(smp_processor_id());
clockevents_register_device(&hpet_clockevent); clockevents_config_and_register(&hpet_clockevent, hpet_freq,
HPET_MIN_PROG_DELTA, 0x7FFFFFFF);
global_clock_event = &hpet_clockevent; global_clock_event = &hpet_clockevent;
printk(KERN_DEBUG "hpet clockevent registered\n"); printk(KERN_DEBUG "hpet clockevent registered\n");
} }
...@@ -549,7 +532,6 @@ static int hpet_setup_irq(struct hpet_dev *dev) ...@@ -549,7 +532,6 @@ static int hpet_setup_irq(struct hpet_dev *dev)
static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
{ {
struct clock_event_device *evt = &hdev->evt; struct clock_event_device *evt = &hdev->evt;
uint64_t hpet_freq;
WARN_ON(cpu != smp_processor_id()); WARN_ON(cpu != smp_processor_id());
if (!(hdev->flags & HPET_DEV_VALID)) if (!(hdev->flags & HPET_DEV_VALID))
...@@ -571,24 +553,10 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu) ...@@ -571,24 +553,10 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
evt->set_mode = hpet_msi_set_mode; evt->set_mode = hpet_msi_set_mode;
evt->set_next_event = hpet_msi_next_event; evt->set_next_event = hpet_msi_next_event;
evt->shift = 32;
/*
* The period is a femto seconds value. We need to calculate the
* scaled math multiplication factor for nanosecond to hpet tick
* conversion.
*/
hpet_freq = FSEC_PER_SEC;
do_div(hpet_freq, hpet_period);
evt->mult = div_sc((unsigned long) hpet_freq,
NSEC_PER_SEC, evt->shift);
/* Calculate the max delta */
evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt);
/* 5 usec minimum reprogramming delta. */
evt->min_delta_ns = 5000;
evt->cpumask = cpumask_of(hdev->cpu); evt->cpumask = cpumask_of(hdev->cpu);
clockevents_register_device(evt);
clockevents_config_and_register(evt, hpet_freq, HPET_MIN_PROG_DELTA,
0x7FFFFFFF);
} }
#ifdef CONFIG_HPET #ifdef CONFIG_HPET
...@@ -792,7 +760,6 @@ static struct clocksource clocksource_hpet = { ...@@ -792,7 +760,6 @@ static struct clocksource clocksource_hpet = {
static int hpet_clocksource_register(void) static int hpet_clocksource_register(void)
{ {
u64 start, now; u64 start, now;
u64 hpet_freq;
cycle_t t1; cycle_t t1;
/* Start the counter */ /* Start the counter */
...@@ -819,24 +786,7 @@ static int hpet_clocksource_register(void) ...@@ -819,24 +786,7 @@ static int hpet_clocksource_register(void)
return -ENODEV; return -ENODEV;
} }
/*
* The definition of mult is (include/linux/clocksource.h)
* mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc
* so we first need to convert hpet_period to ns/cyc units:
* mult/2^shift = ns/cyc = hpet_period/10^6
* mult = (hpet_period * 2^shift)/10^6
* mult = (hpet_period << shift)/FSEC_PER_NSEC
*/
/* Need to convert hpet_period (fsec/cyc) to cyc/sec:
*
* cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
* cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
*/
hpet_freq = FSEC_PER_SEC;
do_div(hpet_freq, hpet_period);
clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq); clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
return 0; return 0;
} }
...@@ -845,7 +795,9 @@ static int hpet_clocksource_register(void) ...@@ -845,7 +795,9 @@ static int hpet_clocksource_register(void)
*/ */
int __init hpet_enable(void) int __init hpet_enable(void)
{ {
unsigned long hpet_period;
unsigned int id; unsigned int id;
u64 freq;
int i; int i;
if (!is_hpet_capable()) if (!is_hpet_capable())
...@@ -883,6 +835,14 @@ int __init hpet_enable(void) ...@@ -883,6 +835,14 @@ int __init hpet_enable(void)
if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
goto out_nohpet; goto out_nohpet;
/*
* The period is a femto seconds value. Convert it to a
* frequency.
*/
freq = FSEC_PER_SEC;
do_div(freq, hpet_period);
hpet_freq = freq;
/* /*
* Read the HPET ID register to retrieve the IRQ routing * Read the HPET ID register to retrieve the IRQ routing
* information and the number of channels * information and the number of channels
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment