Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / arch / arm / mach-at91rm9200 / time.c
similarity index 79%
rename from arch/arm/mach-at91rm9200/at91rm9200_time.c
rename to arch/arm/mach-at91rm9200/time.c
index a92a862..7ffcf44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-at91rm9200/at91rm9200_time.c
+ * linux/arch/arm/mach-at91rm9200/time.c
  *
  *  Copyright (C) 2003 SAN People
  *  Copyright (C) 2003 ATMEL
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/time.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
+#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.
@@ -57,7 +56,7 @@ static unsigned long at91rm9200_gettimeoffset(void)
 {
        unsigned long elapsed;
 
-       elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
+       elapsed = (read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV;
 
        return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
 }
@@ -67,12 +66,15 @@ 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() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
+               while (((read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV) >= LATCH) {
                        timer_tick(regs);
-                       last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
+                       rtar = (at91_sys_read(AT91_ST_RTAR) + LATCH) & AT91_ST_ALMV;
+                       at91_sys_write(AT91_ST_RTAR, rtar);
                }
 
                write_sequnlock(&xtime_lock);
@@ -85,24 +87,10 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_r
 
 static struct irqaction at91rm9200_timer_irq = {
        .name           = "at91_tick",
-       .flags          = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+       .flags          = SA_SHIRQ | SA_INTERRUPT,
        .handler        = at91rm9200_timer_interrupt
 };
 
-void at91rm9200_timer_reset(void)
-{
-       last_crtr = 0;
-
-       /* Real time counter incremented every 30.51758 microseconds */
-       at91_sys_write(AT91_ST_RTMR, 1);
-
-       /* Set Period Interval timer */
-       at91_sys_write(AT91_ST_PIMR, LATCH);
-
-       /* Enable Period Interval Timer interrupt */
-       at91_sys_write(AT91_ST_IER, AT91_ST_PITS);
-}
-
 /*
  * Set up timer interrupt.
  */
@@ -112,30 +100,28 @@ void __init at91rm9200_timer_init(void)
        at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
        (void) at91_sys_read(AT91_ST_SR);       /* Clear any pending interrupts */
 
-       /* Make IRQs happen for the system timer */
+       /*
+        * Make IRQs happen for the system timer.
+        */
        setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
 
+       /* Set initial alarm to 0 */
+       at91_sys_write(AT91_ST_RTAR, 0);
+
+       /* Real time counter incremented every 30.51758 microseconds */
+       at91_sys_write(AT91_ST_RTMR, 1);
+
+       /* Set Period Interval timer */
+       at91_sys_write(AT91_ST_PIMR, LATCH);
+
        /* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */
        tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE;
 
-       /* Initialize and enable the timer interrupt */
-       at91rm9200_timer_reset();
-}
-
-#ifdef CONFIG_PM
-static void at91rm9200_timer_suspend(void)
-{
-       /* disable Period Interval Timer interrupt */
-       at91_sys_write(AT91_ST_IDR, AT91_ST_PITS);
+       /* Enable Period Interval Timer interrupt */
+       at91_sys_write(AT91_ST_IER, AT91_ST_PITS);
 }
-#else
-#define at91rm9200_timer_suspend       NULL
-#endif
 
 struct sys_timer at91rm9200_timer = {
        .init           = at91rm9200_timer_init,
        .offset         = at91rm9200_gettimeoffset,
-       .suspend        = at91rm9200_timer_suspend,
-       .resume         = at91rm9200_timer_reset,
 };
-