aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDaniel Hellstrom2010-01-22 12:02:40 +0100
committerFrancois Retief2015-12-03 13:15:49 +0200
commitf376c42f3b28862326ea378b0b6cc6b9b699d0c0 (patch)
treef140bd7adb665301f4d9a79bb4834f1cecb3124f /arch
parent6c4359aa7284bf7bc6d9f83a2c6dceb406726388 (diff)
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')
-rw-r--r--arch/sparc/cpu/leon3/cpu_init.c32
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 88f82c95a8b..9e294bfd0eb 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)