Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / arm / mach-s3c2410 / time.c
index 715d65a..9d7b799 100644 (file)
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/time.c
  *
- * Copyright (C) 2003,2004 Simtec Electronics
+ * Copyright (C) 2003-2005 Simtec Electronics
  *     Ben Dooks, <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,9 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
@@ -35,6 +38,7 @@
 #include <asm/mach/time.h>
 
 #include "clock.h"
+#include "cpu.h"
 
 static unsigned long timer_startval;
 static unsigned long timer_usec_ticks;
@@ -134,10 +138,16 @@ s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction s3c2410_timer_irq = {
        .name           = "S3C2410 Timer Tick",
-       .flags          = SA_INTERRUPT,
-       .handler        = s3c2410_timer_interrupt
+       .flags          = SA_INTERRUPT | SA_TIMER,
+       .handler        = s3c2410_timer_interrupt,
 };
 
+#define use_tclk1_12() ( \
+       machine_is_bast()       || \
+       machine_is_vr1000()     || \
+       machine_is_anubis()     || \
+       machine_is_osiris() )
+
 /*
  * Set up timer interrupt, and return the current time in seconds.
  *
@@ -161,7 +171,7 @@ static void s3c2410_timer_setup (void)
 
        /* configure the system for whichever machine is in use */
 
-       if (machine_is_bast() || machine_is_vr1000()) {
+       if (use_tclk1_12()) {
                /* timer is at 12MHz, scaler is 1 */
                timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
                tcnt = 12000000 / HZ;
@@ -169,6 +179,9 @@ static void s3c2410_timer_setup (void)
                tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
                tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
        } else {
+               unsigned long pclk;
+               struct clk *clk;
+
                /* for the h1940 (and others), we use the pclk from the core
                 * to generate the timer values. since values around 50 to
                 * 70MHz are not values we can directly generate the timer
@@ -180,7 +193,17 @@ static void s3c2410_timer_setup (void)
 
                /* this is used as default if no other timer can be found */
 
-               timer_usec_ticks = timer_mask_usec_ticks(6, s3c24xx_pclk);
+               clk = clk_get(NULL, "timers");
+               if (IS_ERR(clk))
+                       panic("failed to get clock for system timer");
+
+               clk_enable(clk);
+
+               pclk = clk_get_rate(clk);
+
+               /* configure clock tick */
+
+               timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
 
                tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
                tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
@@ -188,7 +211,7 @@ static void s3c2410_timer_setup (void)
                tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
                tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
 
-               tcnt = (s3c24xx_pclk / 6) / HZ;
+               tcnt = (pclk / 6) / HZ;
        }
 
        /* timers reload after counting zero, so reduce the count by 1 */