]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
clockevents: ARM sp804: obtain sp804 timer rate via clks
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 12 May 2011 14:45:16 +0000 (15:45 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 23 May 2011 17:04:53 +0000 (18:04 +0100)
This allows platforms to specify the rate of the SP804 clockevent via
the clk subsystem.  While ARM boards clock these at 1MHz, BCMRing also
has SP804 timers but are clocked at different rates.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/common/timer-sp.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/v2m.c

index 5b7e8c9046bef37d904feca7300c5b81582f137f..41df47875122a6fcd641a3c47df9ce1de696ce30 100644 (file)
 
 #include <asm/hardware/arm_timer.h>
 
-/*
- * These timers are currently always setup to be clocked at 1MHz.
- */
-#define TIMER_FREQ_KHZ (1000)
-#define TIMER_RELOAD   (TIMER_FREQ_KHZ * 1000 / HZ)
-
 static long __init sp804_get_clock_rate(const char *name)
 {
        struct clk *clk;
@@ -84,6 +78,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
 
 
 static void __iomem *clkevt_base;
+static unsigned long clkevt_reload;
 
 /*
  * IRQ handler for the timer
@@ -109,7 +104,7 @@ static void sp804_set_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD);
+               writel(clkevt_reload, clkevt_base + TIMER_LOAD);
                ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
                break;
 
@@ -158,12 +153,17 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
        const char *name)
 {
        struct clock_event_device *evt = &sp804_clockevent;
+       long rate = sp804_get_clock_rate(name);
+
+       if (rate < 0)
+               return;
 
        clkevt_base = base;
+       clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
 
        evt->name = name;
        evt->irq = irq;
-       evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift);
+       evt->mult = div_sc(rate, NSEC_PER_SEC, evt->shift);
        evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
        evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
 
index 271213384203182b8be69f97013daa421453bc41..2023a9e5211c68f85d7a8cd7c6840f54bc3117cd 100644 (file)
@@ -150,6 +150,10 @@ static struct clk_lookup lookups[] = {
        {       /* CLCD */
                .dev_id         = "ct:clcd",
                .clk            = &osc1_clk,
+       }, {    /* SP804 timers */
+               .dev_id         = "sp804",
+               .con_id         = "ct-timer0",
+               .clk            = &ct_sp804_clk,
        }, {    /* SP804 timers */
                .dev_id         = "sp804",
                .con_id         = "ct-timer1",
index f6fecdd0fbe8c5bb9b2308da1f0803747d7fb643..9d9d4af384e226716a0cc1c028bb0592186da45a 100644 (file)
@@ -368,6 +368,10 @@ static struct clk_lookup v2m_lookups[] = {
        }, {    /* CLCD */
                .dev_id         = "mb:clcd",
                .clk            = &osc1_clk,
+       }, {    /* SP804 timers */
+               .dev_id         = "sp804",
+               .con_id         = "v2m-timer0",
+               .clk            = &v2m_sp804_clk,
        }, {    /* SP804 timers */
                .dev_id         = "sp804",
                .con_id         = "v2m-timer1",