linux-2.5.45_delay-cleanup_A0.patch
PATCH 1/1 linux-2.5.45_delay-cleanup_A0.patch
Linus, All,
This patch moves __delay into the timer_ops infrastructure. This makes
it simple to use alternate time sources for the __delay function.
Please consider for inclusion.
-john
arch/i386/kernel/timers/timer_cyclone.c +2 -3
@@ -150,7 +150,6 @@ } -#if 0 /* XXX future work */ static void delay_cyclone (unsigned long loops) {unsigned long bclock, now;
@@ -162,12 +161,12 @@ now = cyclone_timer[0 ]; }while ((now-bclock) < loops); } -#endif /************************************************************/ /* cyclone timer_opts struct */ struct timer_opts timer_cyclone = { .init = init_cyclone, .mark_offset = mark_offset_cyclone, - .get_offset = get_offset_cyclone + .get_offset = get_offset_cyclone, + .delay = delay_cyclone, };
arch/i386/kernel/timers/timer_pit.c +14 -0
@@ -25,6 +25,19 @@/* nothing needed */ } +static void delay_pit (unsigned long loops) +{ +int d0; + __asm__ __volatile__( +"\tjmp 1f\n" +".align 16\n" +"1:\tjmp 2f\n" +".align 16\n" +"2:\tdecl %0\n\tjns 2b" + :"=&a" (d0) + :"0" (loops)); +} +/* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
@@ -127,4 +140,5 @@ .init = init_pit, .mark_offset = mark_offset_pit, .get_offset = get_offset_pit, + .delay = delay_pit, };
arch/i386/kernel/timers/timer_tsc.c +12 -3
@@ -12,7 +12,6 @@#include <asm/timer.h> #include <asm/io.h> -extern int x86_udelay_tsc;extern spinlock_t i8253_lock;static int use_tsc;
@@ -87,6 +86,17 @@ delay_at_last_interrupt = (count +LATCH /2 ) /LATCH ; } +static void delay_tsc (unsigned long loops) +{ +unsigned long bclock, now; + +rdtscl (bclock); +do + { +rep_nop (); +rdtscl (now); + }while ((now-bclock) < loops); +}/* ------ Calibrate the TSC ------- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
@@ -249,8 +259,6 @@* We could be more selective here I suspect * and just enable this for the next intel chips ? */ - x86_udelay_tsc =1 ; -/* report CPU clock rate in Hz. * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = * clock/second. Our precision is about 100 ppm.
@@ -278,4 +286,5 @@ .init = init_tsc, .mark_offset = mark_offset_tsc, .get_offset = get_offset_tsc, + .delay = delay_tsc, };
arch/i386/lib/delay.c +6 -23
@@ -15,35 +15,18 @@#include <linux/delay.h> #include <asm/processor.h> #include <asm/delay.h> +#include <asm/timer.h> #ifdef CONFIG_SMP #include <asm/smp.h> #endif -int x86_udelay_tsc =0 ;/* Delay via TSC */ +extern struct timer_opts * timer; -/* -* Do a udelay using the TSC for any CPU that happens -* to have one that we trust. +* Backup non-TSC based delay loop. +* Used until a timer is chosen. */ - -static void __rdtsc_delay (unsigned long loops) -{ -unsigned long bclock, now; - -rdtscl (bclock); -do - { -rep_nop (); -rdtscl (now); - }while ((now-bclock) < loops); -} - -/* -* Non TSC based delay loop for 386, 486, MediaGX -*/ -static void __loop_delay (unsigned long loops) {int d0;
@@ -59,8 +42,8 @@void __delay (unsigned long loops) { -if (x86_udelay_tsc) -__rdtsc_delay (loops); +if (timer) + timer->delay (loops);else __loop_delay (loops); }
include/asm-i386/timer.h +1 -0
@@ -14,6 +14,7 @@int (*init)(void );void (*mark_offset)(void );unsigned long (*get_offset)(void ); +void (*delay)(unsigned long ); };#define TICK_SIZE (tick_nsec / 1000)
er, make that 2.5.46
-john