]> err.no Git - linux-2.6/blobdiff - kernel/time/tick-common.c
[IPV6]: Add v4mapped address inline
[linux-2.6] / kernel / time / tick-common.c
index 0986a2bfab49e6a83a02660fa19c01479808b4d4..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,40 @@ 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);
+}
+
+static void tick_suspend(void)
+{
+       struct tick_device *td = &__get_cpu_var(tick_cpu_device);
+       unsigned long flags;
+
+       spin_lock_irqsave(&tick_device_lock, flags);
+       clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
+       spin_unlock_irqrestore(&tick_device_lock, flags);
+}
+
+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);
+       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);
 }
 
@@ -325,6 +359,15 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
                tick_shutdown(dev);
                break;
 
+       case CLOCK_EVT_NOTIFY_SUSPEND:
+               tick_suspend();
+               tick_suspend_broadcast();
+               break;
+
+       case CLOCK_EVT_NOTIFY_RESUME:
+               tick_resume();
+               break;
+
        default:
                break;
        }