[ARM] 3579/1: AT91RM9200 Timer simplification
authorAndrew Victor <andrew@sanpeople.com>
Mon, 19 Jun 2006 14:23:41 +0000 (15:23 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 19 Jun 2006 14:23:41 +0000 (15:23 +0100)
Patch from Andrew Victor

Use a global variable 'last_crtr' to store the time of the last timer
tick instead of the ST_RTAR register.
It's faster, frees up the ST_RTAR register for other uses, and hopefully
makes the code more understandable.  [Patch from Peter Menzebach]

Also add the SA_TIMER flag to Timer IRQ.  (It seems to be required for
the realtime preempt patch).

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-at91rm9200/time.c

index 7ffcf44..36798a8 100644 (file)
@@ -31,6 +31,8 @@
 #include <asm/irq.h>
 #include <asm/mach/time.h>
 
+static unsigned long last_crtr;
+
 /*
  * The ST_CRTR is updated asynchronously to the master clock.  It is therefore
  *  necessary to read it twice (with the same value) to ensure accuracy.
@@ -56,7 +58,7 @@ static unsigned long at91rm9200_gettimeoffset(void)
 {
        unsigned long elapsed;
 
-       elapsed = (read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV;
+       elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
 
        return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
 }
@@ -66,15 +68,12 @@ static unsigned long at91rm9200_gettimeoffset(void)
  */
 static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       unsigned long rtar;
-
        if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */
                write_seqlock(&xtime_lock);
 
-               while (((read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV) >= LATCH) {
+               while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
                        timer_tick(regs);
-                       rtar = (at91_sys_read(AT91_ST_RTAR) + LATCH) & AT91_ST_ALMV;
-                       at91_sys_write(AT91_ST_RTAR, rtar);
+                       last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
                }
 
                write_sequnlock(&xtime_lock);
@@ -87,7 +86,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_r
 
 static struct irqaction at91rm9200_timer_irq = {
        .name           = "at91_tick",
-       .flags          = SA_SHIRQ | SA_INTERRUPT,
+       .flags          = SA_SHIRQ | SA_INTERRUPT | SA_TIMER,
        .handler        = at91rm9200_timer_interrupt
 };