{
int next_match;
+ write_seqlock(&xtime_lock);
+
/* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time accuracy.
* IRQs are disabled inside the loop to ensure coherence between
next_match = (OSMR0 += LATCH);
} while( (signed long)(next_match - OSCR) <= 8 );
+ write_sequnlock(&xtime_lock);
+
return IRQ_HANDLED;
}
.handler = pxa_timer_interrupt
};
-void __init pxa_init_time(void)
+static void __init pxa_timer_init(void)
{
struct timespec tv;
- gettimeoffset = pxa_gettimeoffset;
set_rtc = pxa_set_rtc;
tv.tv_nsec = 0;
OSCR = 0; /* initialize free-running timer, force first match */
}
+#ifdef CONFIG_PM
+static unsigned long osmr[4], oier;
+
+static void pxa_timer_suspend(void)
+{
+ osmr[0] = OSMR0;
+ osmr[1] = OSMR1;
+ osmr[2] = OSMR2;
+ osmr[3] = OSMR3;
+ oier = OIER;
+}
+
+static void pxa_timer_resume(void)
+{
+ OSMR0 = osmr[0];
+ OSMR1 = osmr[1];
+ OSMR2 = osmr[2];
+ OSMR3 = osmr[3];
+ OIER = oier;
+
+ /*
+ * OSMR0 is the system timer: make sure OSCR is sufficiently behind
+ */
+ OSCR = OSMR0 - LATCH;
+}
+#else
+#define pxa_timer_suspend NULL
+#define pxa_timer_resume NULL
+#endif
+
+struct sys_timer pxa_timer = {
+ .init = pxa_timer_init,
+ .suspend = pxa_timer_suspend,
+ .resume = pxa_timer_resume,
+ .offset = pxa_gettimeoffset,
+};