patch-2.4.9 linux/include/asm-arm/arch-sa1100/time.h
Next file: linux/include/asm-arm/arch-sa1100/uncompress.h
Previous file: linux/include/asm-arm/arch-sa1100/system.h
Back to the patch index
Back to the overall index
- Lines: 79
- Date:
Sun Aug 12 11:14:00 2001
- Orig file:
v2.4.8/linux/include/asm-arm/arch-sa1100/time.h
- Orig date:
Mon Jun 19 17:59:35 2000
diff -u --recursive --new-file v2.4.8/linux/include/asm-arm/arch-sa1100/time.h linux/include/asm-arm/arch-sa1100/time.h
@@ -5,11 +5,47 @@
* Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com>
*
* 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
- * Rewritten: big cleanup, much simpler, better HZ acuracy.
+ * Rewritten: big cleanup, much simpler, better HZ accuracy.
*
*/
+#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;
+
+ if (RTSR & RTSR_ALE) {
+ /* make sure not to forward the clock over an alarm */
+ unsigned long alarm = RTAR;
+ if (current_time >= alarm && alarm >= RCNR)
+ return -ERESTARTSYS;
+ }
+ RCNR = current_time;
+ return 0;
+}
+
/* IRQs are disabled before entering here from do_gettimeofday() */
static unsigned long sa1100_gettimeoffset (void)
{
@@ -27,7 +63,6 @@
return usec;
}
-
static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
long flags;
@@ -41,6 +76,7 @@
*/
do {
do_leds();
+ do_set_rtc();
save_flags_cli( flags );
do_timer(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */
@@ -49,10 +85,11 @@
} while( (signed long)(next_match - OSCR) <= 0 );
}
-
-extern inline void setup_timer (void)
+static inline void setup_timer (void)
{
gettimeoffset = sa1100_gettimeoffset;
+ set_rtc = sa1100_set_rtc;
+ xtime.tv_sec = sa1100_get_rtc_time();
timer_irq.handler = sa1100_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)