]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sh/kernel/time_32.c
r8169: shuffle some registers handling around (8168 operation only)
[linux-2.6-omap-h63xx.git] / arch / sh / kernel / time_32.c
index 2bc04bfee73891045e92df6506287aa5ce1e102b..0758b5ee818079b3fd2f3948da6dfe7af5825d0b 100644 (file)
@@ -120,10 +120,6 @@ static long last_rtc_update;
  */
 void handle_timer_tick(void)
 {
-       do_timer(1);
-#ifndef CONFIG_SMP
-       update_process_times(user_mode(get_irq_regs()));
-#endif
        if (current->pid)
                profile_tick(CPU_PROFILING);
 
@@ -132,6 +128,16 @@ void handle_timer_tick(void)
                sh_mv.mv_heartbeat();
 #endif
 
+       /*
+        * Here we are in the timer irq handler. We just have irqs locally
+        * disabled but we don't know if the timer_bh is running on the other
+        * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+        * the irq version of write_lock because as just said we have irq
+        * locally disabled. -arca
+        */
+       write_seqlock(&xtime_lock);
+       do_timer(1);
+
        /*
         * If we have an externally synchronized Linux clock, then update
         * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
@@ -147,6 +153,11 @@ void handle_timer_tick(void)
                        /* do it again in 60s */
                        last_rtc_update = xtime.tv_sec - 600;
        }
+       write_sequnlock(&xtime_lock);
+
+#ifndef CONFIG_SMP
+       update_process_times(user_mode(get_irq_regs()));
+#endif
 }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
@@ -200,7 +211,7 @@ unsigned long sh_hpt_frequency = 0;
 
 #define NSEC_PER_CYC_SHIFT     10
 
-struct clocksource clocksource_sh = {
+static struct clocksource clocksource_sh = {
        .name           = "SuperH",
        .rating         = 200,
        .mask           = CLOCKSOURCE_MASK(32),