From: john stultz It simply uses the TSC for delay_pmtmr much as delay_tsc does. The only gotcha is that __delay will be affected by cpu-frequency changes (much as the existing loop based delay) until I hook in the cpufreq notificaiton into the ACPI PM timesource code. --- arch/i386/kernel/timers/timer_pm.c | 27 +++++++++++---------------- 1 files changed, 11 insertions(+), 16 deletions(-) diff -puN arch/i386/kernel/timers/timer_pm.c~use-TSC-for-delay_pmtmr arch/i386/kernel/timers/timer_pm.c --- 25/arch/i386/kernel/timers/timer_pm.c~use-TSC-for-delay_pmtmr 2004-01-23 17:47:39.000000000 -0800 +++ 25-akpm/arch/i386/kernel/timers/timer_pm.c 2004-01-23 17:47:39.000000000 -0800 @@ -68,6 +68,10 @@ static int init_pmtmr(char* override) if (!pmtmr_ioport) return -ENODEV; + /* we use the TSC for delay_pmtmr, so make sure it exists */ + if (!cpu_has_tsc) + return -ENODEV; + /* "verify" this timing source */ value1 = read_pmtmr(); for (i = 0; i < 10000; i++) { @@ -168,26 +172,17 @@ static unsigned long long monotonic_cloc return ret; } -static void delay_pmtmr(unsigned long total_loops) +static void delay_pmtmr(unsigned long loops) { - u32 then, now; - unsigned long loops; + unsigned long bclock, now; - do{ - if (total_loops > ACPI_PM_MASK) - loops = ACPI_PM_MASK; - else - loops = total_loops; - total_loops -= loops; - - then = read_pmtmr(); - do{ - now = read_pmtmr(); - } while (((now - then)&ACPI_PM_MASK) < loops); - } while (total_loops); + rdtscl(bclock); + do { + rep_nop(); + rdtscl(now); + } while ((now-bclock) < loops); } - /* * get the offset (in microseconds) from the last call to mark_offset() * - Called holding a reader xtime_lock _