]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-sa1100/time.c
Merge branches 'release' and 'gpe-ack' into release
[linux-2.6-omap-h63xx.git] / arch / arm / mach-sa1100 / time.c
index 29c89f9eb2ceed1e345fb193d6bf0a2bd0f6f9a9..c2677368d6af9568d97616b6d0d6becb1a3a5385 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/timex.h>
 #include <linux/signal.h>
+#include <linux/clocksource.h>
 
 #include <asm/mach/time.h>
 #include <asm/hardware.h>
 #define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM            0
 
-static unsigned long __init sa1100_get_rtc_time(void)
-{
-       /*
-        * According to the manual we should be able to let RTTR be zero
-        * and then a default diviser for a 32.768KHz clock is used.
-        * Apparently this doesn't work, at least for my SA1110 rev 5.
-        * If the clock divider is uninitialized then reset it to the
-        * default value to get the 1Hz clock.
-        */
-       if (RTTR == 0) {
-               RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-               printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n");
-               /* The current RTC value probably doesn't make sense either */
-               RCNR = 0;
-               return 0;
-       }
-       return RCNR;
-}
-
 static int sa1100_set_rtc(void)
 {
        unsigned long current_time = xtime.tv_sec;
@@ -54,23 +36,6 @@ static int sa1100_set_rtc(void)
        return 0;
 }
 
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long sa1100_gettimeoffset (void)
-{
-       unsigned long ticks_to_match, elapsed, usec;
-
-       /* Get ticks before next timer match */
-       ticks_to_match = OSMR0 - OSCR;
-
-       /* We need elapsed ticks since last match */
-       elapsed = LATCH - ticks_to_match;
-
-       /* Now convert them to usec */
-       usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
-       return usec;
-}
-
 #ifdef CONFIG_NO_IDLE_HZ
 static unsigned long initial_match;
 static int match_posponed;
@@ -81,8 +46,6 @@ sa1100_timer_interrupt(int irq, void *dev_id)
 {
        unsigned int next_match;
 
-       write_seqlock(&xtime_lock);
-
 #ifdef CONFIG_NO_IDLE_HZ
        if (match_posponed) {
                match_posponed = 0;
@@ -104,28 +67,35 @@ sa1100_timer_interrupt(int irq, void *dev_id)
                next_match = (OSMR0 += LATCH);
        } while ((signed long)(next_match - OSCR) <= 0);
 
-       write_sequnlock(&xtime_lock);
-
        return IRQ_HANDLED;
 }
 
 static struct irqaction sa1100_timer_irq = {
        .name           = "SA11xx Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = sa1100_timer_interrupt,
 };
 
+static cycle_t sa1100_read_oscr(void)
+{
+       return OSCR;
+}
+
+static struct clocksource cksrc_sa1100_oscr = {
+       .name           = "oscr",
+       .rating         = 200,
+       .read           = sa1100_read_oscr,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 20,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
 static void __init sa1100_timer_init(void)
 {
-       struct timespec tv;
        unsigned long flags;
 
        set_rtc = sa1100_set_rtc;
 
-       tv.tv_nsec = 0;
-       tv.tv_sec = sa1100_get_rtc_time();
-       do_settimeofday(&tv);
-
        OIER = 0;               /* disable any timer interrupts */
        OSSR = 0xf;             /* clear status on all timers */
        setup_irq(IRQ_OST0, &sa1100_timer_irq);
@@ -133,6 +103,11 @@ static void __init sa1100_timer_init(void)
        OIER = OIER_E0;         /* enable match on timer 0 to cause interrupts */
        OSMR0 = OSCR + LATCH;   /* set initial match */
        local_irq_restore(flags);
+
+       cksrc_sa1100_oscr.mult =
+               clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
+
+       clocksource_register(&cksrc_sa1100_oscr);
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -206,7 +181,6 @@ struct sys_timer sa1100_timer = {
        .init           = sa1100_timer_init,
        .suspend        = sa1100_timer_suspend,
        .resume         = sa1100_timer_resume,
-       .offset         = sa1100_gettimeoffset,
 #ifdef CONFIG_NO_IDLE_HZ
        .dyn_tick       = &sa1100_dyn_tick,
 #endif