efi: ia64: move IA64-only declarations to new asm/efi.h header
[linux-2.6-microblaze.git] / arch / ia64 / kernel / time.c
index 733e0e3..a37f161 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sched/cputime.h>
 
 #include <asm/delay.h>
+#include <asm/efi.h>
 #include <asm/hw_irq.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
@@ -171,39 +172,29 @@ void vtime_account_hardirq(struct task_struct *tsk)
 static irqreturn_t
 timer_interrupt (int irq, void *dev_id)
 {
-       unsigned long new_itm;
+       unsigned long cur_itm, new_itm, ticks;
 
        if (cpu_is_offline(smp_processor_id())) {
                return IRQ_HANDLED;
        }
 
        new_itm = local_cpu_data->itm_next;
+       cur_itm = ia64_get_itc();
 
-       if (!time_after(ia64_get_itc(), new_itm))
+       if (!time_after(cur_itm, new_itm)) {
                printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
-                      ia64_get_itc(), new_itm);
-
-       profile_tick(CPU_PROFILING);
-
-       while (1) {
-               update_process_times(user_mode(get_irq_regs()));
-
-               new_itm += local_cpu_data->itm_delta;
-
-               if (smp_processor_id() == time_keeper_id)
-                       xtime_update(1);
-
-               local_cpu_data->itm_next = new_itm;
+                      cur_itm, new_itm);
+               ticks = 1;
+       } else {
+               ticks = DIV_ROUND_UP(cur_itm - new_itm,
+                                    local_cpu_data->itm_delta);
+               new_itm += ticks * local_cpu_data->itm_delta;
+       }
 
-               if (time_after(new_itm, ia64_get_itc()))
-                       break;
+       if (smp_processor_id() != time_keeper_id)
+               ticks = 0;
 
-               /*
-                * Allow IPIs to interrupt the timer loop.
-                */
-               local_irq_enable();
-               local_irq_disable();
-       }
+       legacy_timer_tick(ticks);
 
        do {
                /*