mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-21 11:44:01 +08:00
defbb2c929
The original ia64 udelay() was simple, but flawed for platforms without synchronized ITCs: a preemption and migration to another CPU during the while-loop likely resulted in too-early termination or very, very lengthy looping. The first fix (now in 2.6.15) broke the delay loop into smaller, non-preemptible chunks, reenabling preemption between the chunks. This fix is flawed in that the total udelay is computed to be the sum of just the non-premptible while-loop pieces, i.e., not counting the time spent in the interim preemptible periods. If an interrupt or a migration occurs during one of these interim periods, then that time is invisible and only serves to lengthen the effective udelay(). This new fix backs out the current flawed fix and returns to a simple udelay(), fully preemptible and interruptible. It implements two simple alternative udelay() routines: one a default generic version that uses ia64_get_itc(), and the other an sn-specific version that uses that platform's RTC. Signed-off-by: John Hawkes <hawkes@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
43 lines
1.3 KiB
C
43 lines
1.3 KiB
C
#ifndef _ASM_IA64_TIMEX_H
|
|
#define _ASM_IA64_TIMEX_H
|
|
|
|
/*
|
|
* Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
|
|
* David Mosberger-Tang <davidm@hpl.hp.com>
|
|
*/
|
|
/*
|
|
* 2001/01/18 davidm Removed CLOCK_TICK_RATE. It makes no sense on IA-64.
|
|
* Also removed cacheflush_time as it's entirely unused.
|
|
*/
|
|
|
|
#include <asm/intrinsics.h>
|
|
#include <asm/processor.h>
|
|
|
|
typedef unsigned long cycles_t;
|
|
|
|
extern void (*ia64_udelay)(unsigned long usecs);
|
|
|
|
/*
|
|
* For performance reasons, we don't want to define CLOCK_TICK_TRATE as
|
|
* local_cpu_data->itc_rate. Fortunately, we don't have to, either: according to George
|
|
* Anzinger, 1/CLOCK_TICK_RATE is taken as the resolution of the timer clock. The time
|
|
* calculation assumes that you will use enough of these so that your tick size <= 1/HZ.
|
|
* If the calculation shows that your CLOCK_TICK_RATE can not supply exactly 1/HZ ticks,
|
|
* the actual value is calculated and used to update the wall clock each jiffie. Setting
|
|
* the CLOCK_TICK_RATE to x*HZ insures that the calculation will find no errors. Hence we
|
|
* pick a multiple of HZ which gives us a (totally virtual) CLOCK_TICK_RATE of about
|
|
* 100MHz.
|
|
*/
|
|
#define CLOCK_TICK_RATE (HZ * 100000UL)
|
|
|
|
static inline cycles_t
|
|
get_cycles (void)
|
|
{
|
|
cycles_t ret;
|
|
|
|
ret = ia64_getreg(_IA64_REG_AR_ITC);
|
|
return ret;
|
|
}
|
|
|
|
#endif /* _ASM_IA64_TIMEX_H */
|