ARM: Realview/Versatile: separate out common SP804 timer code
[safe/jmp/linux-2.6] / arch / arm / mach-realview / core.c
index 17eb7eb..80b8142 100644 (file)
@@ -25,8 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
@@ -51,6 +49,7 @@
 #include <mach/clkdev.h>
 #include <mach/platform.h>
 #include <mach/irqs.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
 
@@ -646,133 +645,6 @@ void __iomem *timer2_va_base;
 void __iomem *timer3_va_base;
 
 /*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV256)
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV16)
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV1)
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *clk)
-{
-       unsigned long ctrl;
-
-       switch(mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD);
-
-               ctrl = TIMER_CTRL_PERIODIC;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* period set, and timer enabled in 'next_event' hook */
-               ctrl = TIMER_CTRL_ONESHOT;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       default:
-               ctrl = 0;
-       }
-
-       writel(ctrl, timer0_va_base + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-                               struct clock_event_device *unused)
-{
-       unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL);
-
-       writel(evt, timer0_va_base + TIMER_LOAD);
-       writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL);
-
-       return 0;
-}
-
-static struct clock_event_device timer0_clockevent =    {
-       .name           = "timer0",
-       .shift          = 32,
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = timer_set_mode,
-       .set_next_event = timer_set_next_event,
-       .rating         = 300,
-       .cpumask        = cpu_all_mask,
-};
-
-static void __init realview_clockevents_init(unsigned int timer_irq)
-{
-       timer0_clockevent.irq = timer_irq;
-       timer0_clockevent.mult =
-               div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-       timer0_clockevent.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-       timer0_clockevent.min_delta_ns =
-               clockevent_delta2ns(0xf, &timer0_clockevent);
-
-       clockevents_register_device(&timer0_clockevent);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &timer0_clockevent;
-
-       /* clear the interrupt */
-       writel(1, timer0_va_base + TIMER_INTCLR);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction realview_timer_irq = {
-       .name           = "RealView Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = realview_timer_interrupt,
-};
-
-static cycle_t realview_get_cycles(struct clocksource *cs)
-{
-       return ~readl(timer3_va_base + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_realview = {
-       .name   = "timer3",
-       .rating = 200,
-       .read   = realview_get_cycles,
-       .mask   = CLOCKSOURCE_MASK(32),
-       .shift  = 20,
-       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static void __init realview_clocksource_init(void)
-{
-       /* setup timer 0 as free-running clocksource */
-       writel(0, timer3_va_base + TIMER_CTRL);
-       writel(0xffffffff, timer3_va_base + TIMER_LOAD);
-       writel(0xffffffff, timer3_va_base + TIMER_VALUE);
-       writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-               timer3_va_base + TIMER_CTRL);
-
-       clocksource_realview.mult =
-               clocksource_khz2mult(1000, clocksource_realview.shift);
-       clocksource_register(&clocksource_realview);
-}
-
-/*
  * Set up the clock source and clock events devices
  */
 void __init realview_timer_init(unsigned int timer_irq)
@@ -799,13 +671,8 @@ void __init realview_timer_init(unsigned int timer_irq)
        writel(0, timer2_va_base + TIMER_CTRL);
        writel(0, timer3_va_base + TIMER_CTRL);
 
-       /* 
-        * Make irqs happen for the system timer
-        */
-       setup_irq(timer_irq, &realview_timer_irq);
-
-       realview_clocksource_init();
-       realview_clockevents_init(timer_irq);
+       sp804_clocksource_init(timer3_va_base);
+       sp804_clockevents_init(timer0_va_base, timer_irq);
 }
 
 /*