]> Pileus Git - ~andy/linux/blobdiff - arch/arm/plat-orion/time.c
ARM: Remove dependency of plat-orion time code on mach directory includes.
[~andy/linux] / arch / arm / plat-orion / time.c
index c3da2478b2aa0d29ac605606d095733843566c03..742b0323c57ba84f012a066e8b2bd9713f79b37f 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/sched_clock.h>
-#include <asm/mach/time.h>
-#include <mach/bridge-regs.h>
-#include <mach/hardware.h>
 
 /*
- * Number of timer ticks per jiffy.
+ * MBus bridge block registers.
  */
-static u32 ticks_per_jiffy;
+#define BRIDGE_CAUSE_OFF       0x0110
+#define BRIDGE_MASK_OFF                0x0114
+#define  BRIDGE_INT_TIMER0      0x0002
+#define  BRIDGE_INT_TIMER1      0x0004
 
 
 /*
  * Timer block registers.
  */
-#define TIMER_CTRL             (TIMER_VIRT_BASE + 0x0000)
-#define  TIMER0_EN             0x0001
-#define  TIMER0_RELOAD_EN      0x0002
-#define  TIMER1_EN             0x0004
-#define  TIMER1_RELOAD_EN      0x0008
-#define TIMER0_RELOAD          (TIMER_VIRT_BASE + 0x0010)
-#define TIMER0_VAL             (TIMER_VIRT_BASE + 0x0014)
-#define TIMER1_RELOAD          (TIMER_VIRT_BASE + 0x0018)
-#define TIMER1_VAL             (TIMER_VIRT_BASE + 0x001c)
+#define TIMER_CTRL_OFF         0x0000
+#define  TIMER0_EN              0x0001
+#define  TIMER0_RELOAD_EN       0x0002
+#define  TIMER1_EN              0x0004
+#define  TIMER1_RELOAD_EN       0x0008
+#define TIMER0_RELOAD_OFF      0x0010
+#define TIMER0_VAL_OFF         0x0014
+#define TIMER1_RELOAD_OFF      0x0018
+#define TIMER1_VAL_OFF         0x001c
+
+
+/*
+ * SoC-specific data.
+ */
+static void __iomem *bridge_base;
+static u32 bridge_timer1_clr_mask;
+static void __iomem *timer_base;
+
+
+/*
+ * Number of timer ticks per jiffy.
+ */
+static u32 ticks_per_jiffy;
 
 
 /*
@@ -50,14 +64,14 @@ static DEFINE_CLOCK_DATA(cd);
 
 unsigned long long notrace sched_clock(void)
 {
-       u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+       u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
        return cyc_to_sched_clock(&cd, cyc, (u32)~0);
 }
 
 
 static void notrace orion_update_sched_clock(void)
 {
-       u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+       u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
        update_sched_clock(&cd, cyc, (u32)~0);
 }
 
@@ -71,7 +85,7 @@ static void __init setup_sched_clock(unsigned long tclk)
  */
 static cycle_t orion_clksrc_read(struct clocksource *cs)
 {
-       return 0xffffffff - readl(TIMER0_VAL);
+       return 0xffffffff - readl(timer_base + TIMER0_VAL_OFF);
 }
 
 static struct clocksource orion_clksrc = {
@@ -101,23 +115,23 @@ orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
        /*
         * Clear and enable clockevent timer interrupt.
         */
-       writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);
+       writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
 
-       u = readl(BRIDGE_MASK);
+       u = readl(bridge_base + BRIDGE_MASK_OFF);
        u |= BRIDGE_INT_TIMER1;
-       writel(u, BRIDGE_MASK);
+       writel(u, bridge_base + BRIDGE_MASK_OFF);
 
        /*
         * Setup new clockevent timer value.
         */
-       writel(delta, TIMER1_VAL);
+       writel(delta, timer_base + TIMER1_VAL_OFF);
 
        /*
         * Enable the timer.
         */
-       u = readl(TIMER_CTRL);
+       u = readl(timer_base + TIMER_CTRL_OFF);
        u = (u & ~TIMER1_RELOAD_EN) | TIMER1_EN;
-       writel(u, TIMER_CTRL);
+       writel(u, timer_base + TIMER_CTRL_OFF);
 
        local_irq_restore(flags);
 
@@ -135,37 +149,38 @@ orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
                /*
                 * Setup timer to fire at 1/HZ intervals.
                 */
-               writel(ticks_per_jiffy - 1, TIMER1_RELOAD);
-               writel(ticks_per_jiffy - 1, TIMER1_VAL);
+               writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
+               writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
 
                /*
                 * Enable timer interrupt.
                 */
-               u = readl(BRIDGE_MASK);
-               writel(u | BRIDGE_INT_TIMER1, BRIDGE_MASK);
+               u = readl(bridge_base + BRIDGE_MASK_OFF);
+               writel(u | BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
 
                /*
                 * Enable timer.
                 */
-               u = readl(TIMER_CTRL);
-               writel(u | TIMER1_EN | TIMER1_RELOAD_EN, TIMER_CTRL);
+               u = readl(timer_base + TIMER_CTRL_OFF);
+               writel(u | TIMER1_EN | TIMER1_RELOAD_EN,
+                      timer_base + TIMER_CTRL_OFF);
        } else {
                /*
                 * Disable timer.
                 */
-               u = readl(TIMER_CTRL);
-               writel(u & ~TIMER1_EN, TIMER_CTRL);
+               u = readl(timer_base + TIMER_CTRL_OFF);
+               writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
 
                /*
                 * Disable timer interrupt.
                 */
-               u = readl(BRIDGE_MASK);
-               writel(u & ~BRIDGE_INT_TIMER1, BRIDGE_MASK);
+               u = readl(bridge_base + BRIDGE_MASK_OFF);
+               writel(u & ~BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
 
                /*
                 * ACK pending timer interrupt.
                 */
-               writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);
+               writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
 
        }
        local_irq_restore(flags);
@@ -185,7 +200,7 @@ static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
        /*
         * ACK timer interrupt and call event handler.
         */
-       writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);
+       writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
        orion_clkevt.event_handler(&orion_clkevt);
 
        return IRQ_HANDLED;
@@ -197,31 +212,45 @@ static struct irqaction orion_timer_irq = {
        .handler        = orion_timer_interrupt
 };
 
-void __init orion_time_init(unsigned int irq, unsigned int tclk)
+void __init
+orion_time_set_base(u32 _timer_base)
+{
+       timer_base = (void __iomem *)_timer_base;
+}
+
+void __init
+orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask,
+               unsigned int irq, unsigned int tclk)
 {
        u32 u;
 
+       /*
+        * Set SoC-specific data.
+        */
+       bridge_base = (void __iomem *)_bridge_base;
+       bridge_timer1_clr_mask = _bridge_timer1_clr_mask;
+
        ticks_per_jiffy = (tclk + HZ/2) / HZ;
 
        /*
-        * Set scale and timer for sched_clock
+        * Set scale and timer for sched_clock.
         */
        setup_sched_clock(tclk);
 
        /*
         * Setup free-running clocksource timer (interrupts
-        * disabled.)
+        * disabled).
         */
-       writel(0xffffffff, TIMER0_VAL);
-       writel(0xffffffff, TIMER0_RELOAD);
-       u = readl(BRIDGE_MASK);
-       writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK);
-       u = readl(TIMER_CTRL);
-       writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL);
+       writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
+       writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
+       u = readl(bridge_base + BRIDGE_MASK_OFF);
+       writel(u & ~BRIDGE_INT_TIMER0, bridge_base + BRIDGE_MASK_OFF);
+       u = readl(timer_base + TIMER_CTRL_OFF);
+       writel(u | TIMER0_EN | TIMER0_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
        clocksource_register_hz(&orion_clksrc, tclk);
 
        /*
-        * Setup clockevent timer (interrupt-driven.)
+        * Setup clockevent timer (interrupt-driven).
         */
        setup_irq(irq, &orion_timer_irq);
        orion_clkevt.mult = div_sc(tclk, NSEC_PER_SEC, orion_clkevt.shift);