sparc: leon3: Added busy wait function, made wait_ms() work when IRQ is disabled

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
This commit is contained in:
Daniel Hellstrom 2010-01-22 12:02:40 +01:00 committed by Francois Retief
parent 6c4359aa72
commit f376c42f3b

View file

@ -11,6 +11,7 @@
#include <asm/asi.h> #include <asm/asi.h>
#include <asm/leon.h> #include <asm/leon.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h>
#include <ambapp.h> #include <ambapp.h>
#include <grlib/irqmp.h> #include <grlib/irqmp.h>
#include <grlib/gptimer.h> #include <grlib/gptimer.h>
@ -141,14 +142,41 @@ int cpu_init_r(void)
return 0; return 0;
} }
/* Busy wait a number of ms */
void cpu_wait_ms_busy(unsigned long ms)
{
unsigned int ms_delay;
volatile unsigned int tmp;
/* ~10-20 cycles per decrement */
ms_delay = leon_cpu_freq / (1000 * 10);
do {
/* Wait ~1ms */
tmp = ms_delay;
while (tmp-- > 0)
;
} while (--ms > 0);
}
/* Uses Timer 0 to get accurate /* Uses Timer 0 to get accurate
* pauses. Max 2 raised to 32 ticks * pauses. Max 2 raised to 32 ticks
* *
*/ */
void cpu_wait_ticks(unsigned long ticks) void cpu_wait_ticks(unsigned long ticks)
{ {
unsigned long start = get_timer(0); unsigned long start;
while (get_timer(start) < ticks) ;
if (interrupt_is_enabled()) {
start = get_timer(0);
while (get_timer(start) < ticks)
;
} else {
/* Interrupts disabled, this means that we cannot
* use get_timer(), it relies on IRQ. Instead the
* CPU frequency is used.
*/
cpu_wait_ms_busy(ticks2usec(ticks) / 1000);
}
} }
int timer_interrupt_init_cpu(void) int timer_interrupt_init_cpu(void)