From: Luotao Fu <[EMAIL PROTECTED]>

Add a clockevent driver for ep93xx systems.

Signed-off-by: Luotao Fu <[EMAIL PROTECTED]>
Signed-off-by: Sascha Hauer <[EMAIL PROTECTED]>

Index: arch/arm/mach-ep93xx/core.c
===================================================================
--- arch/arm/mach-ep93xx/core.c.orig
+++ arch/arm/mach-ep93xx/core.c
@@ -33,6 +33,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -51,6 +52,8 @@
 
 #include <asm/hardware/vic.h>
 
+static int __init ep93xx_clockevent_init(void);
+static struct clock_event_device clockevent_ep93xx;
 
 /*************************************************************************
  * Static I/O mappings that are needed for all EP93xx platforms
@@ -99,18 +102,15 @@ void __init ep93xx_map_io(void)
 
 static int ep93xx_timer_interrupt(int irq, void *dev_id)
 {
-       write_seqlock(&xtime_lock);
-
        __raw_writel(1, EP93XX_TIMER1_CLEAR);
        while ((signed long)
                (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
                                                >= TIMER4_TICKS_PER_JIFFY) {
                last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
-               timer_tick();
+               if (clockevent_ep93xx.event_handler)
+                       clockevent_ep93xx.event_handler(regs);
        }
 
-       write_sequnlock(&xtime_lock);
-
        return IRQ_HANDLED;
 }
 
@@ -128,6 +128,8 @@ static void __init ep93xx_timer_init(voi
        __raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
 
        setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
+
+       ep93xx_clockevent_init();
 }
 
 /* timer4 is a 40 Bit timer, separated in a 32bit and a 8 bit register, 
EP93XX_TIMER4_VALUE_LOW
@@ -491,3 +493,41 @@ void __init ep93xx_init_devices(void)
        platform_device_register(&ep93xx_rtc_device);
        platform_device_register(&ep93xx_ohci_device);
 }
+
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_PERIODIC;
+
+static void ep93xx_set_next_event(unsigned long evt,
+                                  struct clock_event_device *unused)
+{
+        u32 mode = (clockevent_mode == CLOCK_EVT_ONESHOT) ?
+                0 : EP93XX_TC123_PERIODIC;
+       __raw_writel(evt, EP93XX_TIMER1_LOAD);
+       __raw_writel( mode | EP93XX_TC123_ENABLE | EP93XX_TC123_SEL_508KHZ, 
EP93XX_TIMER1_CONTROL);
+}
+
+static void ep93xx_set_mode(enum clock_event_mode mode, struct 
clock_event_device *evt)
+{
+       clockevent_mode = mode;
+}
+
+static struct clock_event_device clockevent_ep93xx = {
+       .name           = "ep93xx timer1",
+       .capabilities   = CLOCK_CAP_NEXTEVT | CLOCK_CAP_TICK |
+                         CLOCK_CAP_UPDATE | CLOCK_CAP_PROFILE,
+       .shift          = 32,
+       .set_mode       = ep93xx_set_mode,
+       .set_next_event = ep93xx_set_next_event,
+};
+
+static int __init ep93xx_clockevent_init(void)
+{
+       clockevent_ep93xx.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+                                       clockevent_ep93xx.shift);
+       clockevent_ep93xx.max_delta_ns =
+               clockevent_delta2ns(0xfffffffe, &clockevent_ep93xx);
+       clockevent_ep93xx.min_delta_ns =
+               clockevent_delta2ns(0xf, &clockevent_ep93xx);
+       register_local_clockevent(&clockevent_ep93xx);
+
+       return 0;
+}
Index: include/asm-arm/arch-ep93xx/ep93xx-regs.h
===================================================================
--- include/asm-arm/arch-ep93xx/ep93xx-regs.h.orig
+++ include/asm-arm/arch-ep93xx/ep93xx-regs.h
@@ -67,6 +67,12 @@
 #define EP93XX_TIMER3_CONTROL          EP93XX_TIMER_REG(0x88)
 #define EP93XX_TIMER3_CLEAR            EP93XX_TIMER_REG(0x8c)
 
+#define EP93XX_TC_CLEAR                        0x00000001
+#define EP93XX_TC123_ENABLE            0x00000080
+#define EP93XX_TC123_PERIODIC          0x00000040
+#define EP93XX_TC123_SEL_508KHZ                0x00000008
+#define EP93XX_TC4_ENABLE              0x00000100
+
 #define EP93XX_I2S_BASE                        (EP93XX_APB_VIRT_BASE + 
0x00020000)
 
 #define EP93XX_SECURITY_BASE           (EP93XX_APB_VIRT_BASE + 0x00030000)

--
 Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry
   Handelsregister:  Amtsgericht Hildesheim, HRA 2686
     Hannoversche Str. 2, 31134 Hildesheim, Germany
   Phone: +49-5121-206917-0 |  Fax: +49-5121-206917-9

-
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to