Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / x86 / kernel / hpet.c
index bfe8f72..0f4b065 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/sysdev.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/i8253.h>
 #include <linux/slab.h>
 #include <linux/hpet.h>
 #include <linux/init.h>
@@ -12,8 +13,8 @@
 #include <linux/io.h>
 
 #include <asm/fixmap.h>
-#include <asm/i8253.h>
 #include <asm/hpet.h>
+#include <asm/time.h>
 
 #define HPET_MASK                      CLOCKSOURCE_MASK(32)
 
@@ -217,7 +218,7 @@ static void hpet_reserve_platform_timers(unsigned int id) { }
 /*
  * Common hpet info
  */
-static unsigned long hpet_period;
+static unsigned long hpet_freq;
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
                          struct clock_event_device *evt);
@@ -232,7 +233,6 @@ static struct clock_event_device hpet_clockevent = {
        .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
        .set_mode       = hpet_legacy_set_mode,
        .set_next_event = hpet_legacy_next_event,
-       .shift          = 32,
        .irq            = 0,
        .rating         = 50,
 };
@@ -289,29 +289,13 @@ static void hpet_legacy_clockevent_register(void)
        /* Start HPET legacy interrupts */
        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
         * global after the IO_APIC has been initialized.
         */
        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;
        printk(KERN_DEBUG "hpet clockevent registered\n");
 }
@@ -549,7 +533,6 @@ static int hpet_setup_irq(struct hpet_dev *dev)
 static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
 {
        struct clock_event_device *evt = &hdev->evt;
-       uint64_t hpet_freq;
 
        WARN_ON(cpu != smp_processor_id());
        if (!(hdev->flags & HPET_DEV_VALID))
@@ -571,24 +554,10 @@ static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
 
        evt->set_mode = hpet_msi_set_mode;
        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);
-       clockevents_register_device(evt);
+
+       clockevents_config_and_register(evt, hpet_freq, HPET_MIN_PROG_DELTA,
+                                       0x7FFFFFFF);
 }
 
 #ifdef CONFIG_HPET
@@ -792,7 +761,6 @@ static struct clocksource clocksource_hpet = {
 static int hpet_clocksource_register(void)
 {
        u64 start, now;
-       u64 hpet_freq;
        cycle_t t1;
 
        /* Start the counter */
@@ -819,24 +787,7 @@ static int hpet_clocksource_register(void)
                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);
-
        return 0;
 }
 
@@ -845,7 +796,9 @@ static int hpet_clocksource_register(void)
  */
 int __init hpet_enable(void)
 {
+       unsigned long hpet_period;
        unsigned int id;
+       u64 freq;
        int i;
 
        if (!is_hpet_capable())
@@ -883,6 +836,14 @@ int __init hpet_enable(void)
        if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
                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
         * information and the number of channels