Replace <asm/uaccess.h> with <linux/uaccess.h> globally
[linux-2.6-block.git] / arch / parisc / kernel / time.c
index 325f30d82b6434368425d652402fabf66fd4f8ee..037d81f00520db1e7f5b41fb4150f1820ac2f9ea 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/platform_device.h>
 #include <linux/ftrace.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/page.h>
@@ -59,10 +59,9 @@ static unsigned long clocktick __read_mostly;        /* timer cycles per tick */
  */
 irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
 {
-       unsigned long now, now2;
+       unsigned long now;
        unsigned long next_tick;
-       unsigned long cycles_elapsed, ticks_elapsed = 1;
-       unsigned long cycles_remainder;
+       unsigned long ticks_elapsed = 0;
        unsigned int cpu = smp_processor_id();
        struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
 
@@ -71,102 +70,49 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
 
        profile_tick(CPU_PROFILING);
 
-       /* Initialize next_tick to the expected tick time. */
+       /* Initialize next_tick to the old expected tick time. */
        next_tick = cpuinfo->it_value;
 
-       /* Get current cycle counter (Control Register 16). */
-       now = mfctl(16);
-
-       cycles_elapsed = now - next_tick;
-
-       if ((cycles_elapsed >> 6) < cpt) {
-               /* use "cheap" math (add/subtract) instead
-                * of the more expensive div/mul method
-                */
-               cycles_remainder = cycles_elapsed;
-               while (cycles_remainder > cpt) {
-                       cycles_remainder -= cpt;
-                       ticks_elapsed++;
-               }
-       } else {
-               /* TODO: Reduce this to one fdiv op */
-               cycles_remainder = cycles_elapsed % cpt;
-               ticks_elapsed += cycles_elapsed / cpt;
-       }
-
-       /* convert from "division remainder" to "remainder of clock tick" */
-       cycles_remainder = cpt - cycles_remainder;
-
-       /* Determine when (in CR16 cycles) next IT interrupt will fire.
-        * We want IT to fire modulo clocktick even if we miss/skip some.
-        * But those interrupts don't in fact get delivered that regularly.
-        */
-       next_tick = now + cycles_remainder;
+       /* Calculate how many ticks have elapsed. */
+       do {
+               ++ticks_elapsed;
+               next_tick += cpt;
+               now = mfctl(16);
+       } while (next_tick - now > cpt);
 
+       /* Store (in CR16 cycles) up to when we are accounting right now. */
        cpuinfo->it_value = next_tick;
 
-       /* Program the IT when to deliver the next interrupt.
-        * Only bottom 32-bits of next_tick are writable in CR16!
-        */
-       mtctl(next_tick, 16);
+       /* Go do system house keeping. */
+       if (cpu == 0)
+               xtime_update(ticks_elapsed);
+
+       update_process_times(user_mode(get_irq_regs()));
 
-       /* Skip one clocktick on purpose if we missed next_tick.
+       /* Skip clockticks on purpose if we know we would miss those.
         * The new CR16 must be "later" than current CR16 otherwise
         * itimer would not fire until CR16 wrapped - e.g 4 seconds
         * later on a 1Ghz processor. We'll account for the missed
-        * tick on the next timer interrupt.
+        * ticks on the next timer interrupt.
+        * We want IT to fire modulo clocktick even if we miss/skip some.
+        * But those interrupts don't in fact get delivered that regularly.
         *
         * "next_tick - now" will always give the difference regardless
         * if one or the other wrapped. If "now" is "bigger" we'll end up
         * with a very large unsigned number.
         */
-       now2 = mfctl(16);
-       if (next_tick - now2 > cpt)
-               mtctl(next_tick+cpt, 16);
+       while (next_tick - mfctl(16) > cpt)
+               next_tick += cpt;
 
-#if 1
-/*
- * GGG: DEBUG code for how many cycles programming CR16 used.
- */
-       if (unlikely(now2 - now > 0x3000))      /* 12K cycles */
-               printk (KERN_CRIT "timer_interrupt(CPU %d): SLOW! 0x%lx cycles!"
-                       " cyc %lX rem %lX "
-                       " next/now %lX/%lX\n",
-                       cpu, now2 - now, cycles_elapsed, cycles_remainder,
-                       next_tick, now );
-#endif
-
-       /* Can we differentiate between "early CR16" (aka Scenario 1) and
-        * "long delay" (aka Scenario 3)? I don't think so.
-        *
-        * Timer_interrupt will be delivered at least a few hundred cycles
-        * after the IT fires. But it's arbitrary how much time passes
-        * before we call it "late". I've picked one second.
-        *
-        * It's important NO printk's are between reading CR16 and
-        * setting up the next value. May introduce huge variance.
-        */
-       if (unlikely(ticks_elapsed > HZ)) {
-               /* Scenario 3: very long delay?  bad in any case */
-               printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
-                       " cycles %lX rem %lX "
-                       " next/now %lX/%lX\n",
-                       cpu,
-                       cycles_elapsed, cycles_remainder,
-                       next_tick, now );
-       }
-
-       /* Done mucking with unreliable delivery of interrupts.
-        * Go do system house keeping.
+       /* Program the IT when to deliver the next interrupt.
+        * Only bottom 32-bits of next_tick are writable in CR16!
+        * Timer interrupt will be delivered at least a few hundred cycles
+        * after the IT fires, so if we are too close (<= 500 cycles) to the
+        * next cycle, simply skip it.
         */
-
-       if (!--cpuinfo->prof_counter) {
-               cpuinfo->prof_counter = cpuinfo->prof_multiplier;
-               update_process_times(user_mode(get_irq_regs()));
-       }
-
-       if (cpu == 0)
-               xtime_update(ticks_elapsed);
+       if (next_tick - mfctl(16) <= 500)
+               next_tick += cpt;
+       mtctl(next_tick, 16);
 
        return IRQ_HANDLED;
 }