diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2010-01-22 12:02:40 +0100 |
---|---|---|
committer | Francois Retief <fgretief@spaceteq.co.za> | 2015-12-03 13:15:49 +0200 |
commit | f376c42f3b28862326ea378b0b6cc6b9b699d0c0 (patch) | |
tree | f140bd7adb665301f4d9a79bb4834f1cecb3124f /arch/sparc/cpu/leon3/cpu_init.c | |
parent | 6c4359aa7284bf7bc6d9f83a2c6dceb406726388 (diff) | |
download | u-boot-imx-f376c42f3b28862326ea378b0b6cc6b9b699d0c0.zip u-boot-imx-f376c42f3b28862326ea378b0b6cc6b9b699d0c0.tar.gz u-boot-imx-f376c42f3b28862326ea378b0b6cc6b9b699d0c0.tar.bz2 |
sparc: leon3: Added busy wait function, made wait_ms() work when IRQ is disabled
Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
Diffstat (limited to 'arch/sparc/cpu/leon3/cpu_init.c')
-rw-r--r-- | arch/sparc/cpu/leon3/cpu_init.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 88f82c9..9e294bf 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,6 +11,7 @@ #include <asm/asi.h> #include <asm/leon.h> #include <asm/io.h> +#include <asm/irq.h> #include <ambapp.h> #include <grlib/irqmp.h> #include <grlib/gptimer.h> @@ -141,14 +142,41 @@ int cpu_init_r(void) 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 * pauses. Max 2 raised to 32 ticks * */ void cpu_wait_ticks(unsigned long ticks) { - unsigned long start = get_timer(0); - while (get_timer(start) < ticks) ; + unsigned long start; + + 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) |