Merge branch 'iommu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[safe/jmp/linux-2.6] / arch / x86 / kernel / vmiclock_32.c
index b1b5ab0..33a788d 100644 (file)
 
 #include <asm/vmi.h>
 #include <asm/vmi_time.h>
-#include <asm/arch_hooks.h>
 #include <asm/apicdef.h>
 #include <asm/apic.h>
 #include <asm/timer.h>
 #include <asm/i8253.h>
-
-#include <irq_vectors.h>
-#include "io_ports.h"
+#include <asm/irq_vectors.h>
 
 #define VMI_ONESHOT  (VMI_ALARM_IS_ONESHOT  | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
 #define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring())
@@ -71,8 +68,8 @@ unsigned long long vmi_sched_clock(void)
        return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
 }
 
-/* paravirt_ops.get_cpu_khz = vmi_cpu_khz */
-unsigned long vmi_cpu_khz(void)
+/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
+unsigned long vmi_tsc_khz(void)
 {
        unsigned long long khz;
        khz = vmi_timer_ops.get_cycle_frequency();
@@ -204,7 +201,7 @@ static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id)
 static struct irqaction vmi_clock_action  = {
        .name           = "vmi-timer",
        .handler        = vmi_timer_interrupt,
-       .flags          = IRQF_DISABLED | IRQF_NOBALANCING,
+       .flags          = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
        .mask           = CPU_MASK_ALL,
 };
 
@@ -228,7 +225,7 @@ static void __devinit vmi_time_init_clockevent(void)
        /* Upper bound is clockevent's use of ulong for cycle deltas. */
        evt->max_delta_ns = clockevent_delta2ns(ULONG_MAX, evt);
        evt->min_delta_ns = clockevent_delta2ns(1, evt);
-       evt->cpumask = cpumask_of_cpu(cpu);
+       evt->cpumask = cpumask_of(cpu);
 
        printk(KERN_WARNING "vmi: registering clock event %s. mult=%lu shift=%u\n",
               evt->name, evt->mult, evt->shift);
@@ -237,11 +234,14 @@ static void __devinit vmi_time_init_clockevent(void)
 
 void __init vmi_time_init(void)
 {
+       unsigned int cpu;
        /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */
-       outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
+       outb_pit(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
 
        vmi_time_init_clockevent();
        setup_irq(0, &vmi_clock_action);
+       for_each_possible_cpu(cpu)
+               per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -255,7 +255,7 @@ void __devinit vmi_time_bsp_init(void)
         */
        clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
        local_irq_disable();
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
        /*
         * XXX handle_percpu_irq only defined for SMP; we need to switch over
         * to using it, since this is a local interrupt, which each CPU must
@@ -282,10 +282,12 @@ void __devinit vmi_time_ap_init(void)
 #endif
 
 /** vmi clocksource */
+static struct clocksource clocksource_vmi;
 
 static cycle_t read_real_cycles(void)
 {
-       return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
+       cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
+       return max(ret, clocksource_vmi.cycle_last);
 }
 
 static struct clocksource clocksource_vmi = {