]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/lib/delay_64.c
x86: provide delay loop for x86_64.
[linux-2.6-omap-h63xx.git] / arch / x86 / lib / delay_64.c
index 4c441be92641a3ae295c8dea3db10b86323e7de2..d0326d07c845bb9cfe806ae5b74a4ed14058e427 100644 (file)
 #include <asm/smp.h>
 #endif
 
-int __devinit read_current_timer(unsigned long *timer_value)
+/* simple loop based delay: */
+static void delay_loop(unsigned long loops)
 {
-       rdtscll(*timer_value);
-       return 0;
+       asm volatile(
+               "       test %0,%0      \n"
+               "       jz 3f           \n"
+               "       jmp 1f          \n"
+
+               ".align 16              \n"
+               "1:     jmp 2f          \n"
+
+               ".align 16              \n"
+               "2:     dec %0          \n"
+               "       jnz 2b          \n"
+               "3:     dec %0          \n"
+
+               : /* we don't need output */
+               :"a" (loops)
+       );
 }
 
-void __delay(unsigned long loops)
+static void delay_tsc(unsigned long loops)
 {
        unsigned bclock, now;
        int cpu;
@@ -63,6 +78,27 @@ void __delay(unsigned long loops)
        }
        preempt_enable();
 }
+
+static void (*delay_fn)(unsigned long) = delay_loop;
+
+void use_tsc_delay(void)
+{
+       delay_fn = delay_tsc;
+}
+
+int __devinit read_current_timer(unsigned long *timer_value)
+{
+       if (delay_fn == delay_tsc) {
+               rdtscll(*timer_value);
+               return 0;
+       }
+       return -1;
+}
+
+void __delay(unsigned long loops)
+{
+       delay_fn(loops);
+}
 EXPORT_SYMBOL(__delay);
 
 inline void __const_udelay(unsigned long xloops)