]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/time/tick-common.c
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
[linux-2.6-omap-h63xx.git] / kernel / time / tick-common.c
index bfda3f7f0716a9ad4915dd2191390f8bbf59ddd8..77a21abc87167482ff63efea9480c4ed11cbb21b 100644 (file)
@@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
  */
 ktime_t tick_next_period;
 ktime_t tick_period;
-static int tick_do_timer_cpu = -1;
+int tick_do_timer_cpu __read_mostly = -1;
 DEFINE_SPINLOCK(tick_device_lock);
 
 /*
@@ -295,6 +295,12 @@ static void tick_shutdown(unsigned int *cpup)
                clockevents_exchange_device(dev, NULL);
                td->evtdev = NULL;
        }
+       /* Transfer the do_timer job away from this cpu */
+       if (*cpup == tick_do_timer_cpu) {
+               int cpu = first_cpu(cpu_online_map);
+
+               tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
+       }
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -312,12 +318,17 @@ static void tick_resume(void)
 {
        struct tick_device *td = &__get_cpu_var(tick_cpu_device);
        unsigned long flags;
+       int broadcast = tick_resume_broadcast();
 
        spin_lock_irqsave(&tick_device_lock, flags);
-       if (td->mode == TICKDEV_MODE_PERIODIC)
-               tick_setup_periodic(td->evtdev, 0);
-       else
-               tick_resume_oneshot();
+       clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
+
+       if (!broadcast) {
+               if (td->mode == TICKDEV_MODE_PERIODIC)
+                       tick_setup_periodic(td->evtdev, 0);
+               else
+                       tick_resume_oneshot();
+       }
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -354,8 +365,7 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
                break;
 
        case CLOCK_EVT_NOTIFY_RESUME:
-               if (!tick_resume_broadcast())
-                       tick_resume();
+               tick_resume();
                break;
 
        default: