Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ae30ceac3c6bbacdb227816abe6f0c7ea867ac7c
Commit:     ae30ceac3c6bbacdb227816abe6f0c7ea867ac7c
Parent:     85802afeb010502471f64dccf9839f60995c8579
Author:     Catalin Marinas <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 4 17:26:55 2008 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Mon Feb 4 17:52:17 2008 +0000

    [ARM] 4812/1: RealView: clockevents support for the RealView platforms
    
    The patch updates the RealView code to the clockevents infrastructure.
    The SMP support is implemented in subsequent patches. Based on the
    Versatile implementation by Kevin Hilman.
    
    Signed-off-by: Catalin Marinas <[EMAIL PROTECTED]>
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/Kconfig              |    1 +
 arch/arm/mach-realview/core.c |   78 ++++++++++++++++++++++++++++++++++------
 2 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a2b7e4a..b82828e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -169,6 +169,7 @@ config ARCH_REALVIEW
        select ARM_AMBA
        select ICST307
        select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
        help
          This enables support for ARM Ltd RealView boards.
 
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index f805840..6c68dee 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -26,6 +26,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 #include <asm/system.h>
 #include <asm/hardware.h>
@@ -485,20 +486,77 @@ void realview_leds_event(led_event_t ledevt)
 #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,
+       .irq            = IRQ_TIMERINT0_1,
+       .cpumask        = CPU_MASK_ALL,
+};
+
+static void __init realview_clockevents_init(void)
+{
+       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)
 {
-       // ...clear the interrupt
-       writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
+       struct clock_event_device *evt = &timer0_clockevent;
 
-       timer_tick();
+       /* clear the interrupt */
+       writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
-#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
-       smp_send_timer();
-       update_process_times(user_mode(get_irq_regs()));
-#endif
+       evt->event_handler(evt);
 
        return IRQ_HANDLED;
 }
@@ -564,17 +622,13 @@ static void __init realview_timer_init(void)
        writel(0, TIMER2_VA_BASE + TIMER_CTRL);
        writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
-       writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-       writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
-       writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
-              TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
-
        /* 
         * Make irqs happen for the system timer
         */
        setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq);
 
        realview_clocksource_init();
+       realview_clockevents_init();
 }
 
 struct sys_timer realview_timer = {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to