[POWERPC] Implement SLB shadow buffer
[powerpc.git] / kernel / timer.c
index acfa557..b650f04 100644 (file)
@@ -84,7 +84,7 @@ typedef struct tvec_t_base_s tvec_base_t;
 
 tvec_base_t boot_tvec_bases;
 EXPORT_SYMBOL(boot_tvec_bases);
-static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = { &boot_tvec_bases };
+static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
 
 static inline void set_running_timer(tvec_base_t *base,
                                        struct timer_list *timer)
@@ -408,7 +408,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
  * This function cascades all vectors and executes all expired timer
  * vectors.
  */
-#define INDEX(N) (base->timer_jiffies >> (TVR_BITS + N * TVN_BITS)) & TVN_MASK
+#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
 
 static inline void __run_timers(tvec_base_t *base)
 {
@@ -969,6 +969,7 @@ void __init timekeeping_init(void)
 }
 
 
+static int timekeeping_suspended;
 /*
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  * @dev:       unused
@@ -984,6 +985,18 @@ static int timekeeping_resume(struct sys_device *dev)
        write_seqlock_irqsave(&xtime_lock, flags);
        /* restart the last cycle value */
        clock->cycle_last = clocksource_read(clock);
+       clock->error = 0;
+       timekeeping_suspended = 0;
+       write_sequnlock_irqrestore(&xtime_lock, flags);
+       return 0;
+}
+
+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
+{
+       unsigned long flags;
+
+       write_seqlock_irqsave(&xtime_lock, flags);
+       timekeeping_suspended = 1;
        write_sequnlock_irqrestore(&xtime_lock, flags);
        return 0;
 }
@@ -991,6 +1004,7 @@ static int timekeeping_resume(struct sys_device *dev)
 /* sysfs resume/suspend bits for timekeeping */
 static struct sysdev_class timekeeping_sysclass = {
        .resume         = timekeeping_resume,
+       .suspend        = timekeeping_suspend,
        set_kset_name("timekeeping"),
 };
 
@@ -1101,13 +1115,16 @@ static void update_wall_time(void)
 {
        cycle_t offset;
 
-       clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+       /* Make sure we're fully resumed: */
+       if (unlikely(timekeeping_suspended))
+               return;
 
 #ifdef CONFIG_GENERIC_TIME
        offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
 #else
        offset = clock->cycle_interval;
 #endif
+       clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
 
        /* normally this loop will run just once, however in the
         * case of lost or late ticks, it will accumulate correctly.
@@ -1671,7 +1688,7 @@ static void __devinit migrate_timers(int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static int __devinit timer_cpu_notify(struct notifier_block *self,
+static int __cpuinit timer_cpu_notify(struct notifier_block *self,
                                unsigned long action, void *hcpu)
 {
        long cpu = (long)hcpu;
@@ -1691,7 +1708,7 @@ static int __devinit timer_cpu_notify(struct notifier_block *self,
        return NOTIFY_OK;
 }
 
-static struct notifier_block __devinitdata timers_nb = {
+static struct notifier_block __cpuinitdata timers_nb = {
        .notifier_call  = timer_cpu_notify,
 };