Pull percpu-dtc into release branch
[pandora-kernel.git] / arch / ia64 / kernel / smpboot.c
index f7d7f56..ff7df43 100644 (file)
@@ -375,6 +375,7 @@ static void __devinit
 smp_callin (void)
 {
        int cpuid, phys_id, itc_master;
+       struct cpuinfo_ia64 *last_cpuinfo, *this_cpuinfo;
        extern void ia64_init_itm(void);
        extern volatile int time_keeper_id;
 
@@ -424,7 +425,21 @@ smp_callin (void)
         * Get our bogomips.
         */
        ia64_init_itm();
-       calibrate_delay();
+
+       /*
+        * Delay calibration can be skipped if new processor is identical to the
+        * previous processor.
+        */
+       last_cpuinfo = cpu_data(cpuid - 1);
+       this_cpuinfo = local_cpu_data;
+       if (last_cpuinfo->itc_freq != this_cpuinfo->itc_freq ||
+           last_cpuinfo->proc_freq != this_cpuinfo->proc_freq ||
+           last_cpuinfo->features != this_cpuinfo->features ||
+           last_cpuinfo->revision != this_cpuinfo->revision ||
+           last_cpuinfo->family != this_cpuinfo->family ||
+           last_cpuinfo->archrev != this_cpuinfo->archrev ||
+           last_cpuinfo->model != this_cpuinfo->model)
+               calibrate_delay();
        local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 
 #ifdef CONFIG_IA32_SUPPORT
@@ -463,15 +478,17 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
 }
 
 struct create_idle {
+       struct work_struct work;
        struct task_struct *idle;
        struct completion done;
        int cpu;
 };
 
 void
-do_fork_idle(void *_c_idle)
+do_fork_idle(struct work_struct *work)
 {
-       struct create_idle *c_idle = _c_idle;
+       struct create_idle *c_idle =
+               container_of(work, struct create_idle, work);
 
        c_idle->idle = fork_idle(c_idle->cpu);
        complete(&c_idle->done);
@@ -482,10 +499,10 @@ do_boot_cpu (int sapicid, int cpu)
 {
        int timeout;
        struct create_idle c_idle = {
+               .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
                .cpu    = cpu,
                .done   = COMPLETION_INITIALIZER(c_idle.done),
        };
-       DECLARE_WORK(work, do_fork_idle, &c_idle);
 
        c_idle.idle = get_idle_for_cpu(cpu);
        if (c_idle.idle) {
@@ -497,9 +514,9 @@ do_boot_cpu (int sapicid, int cpu)
         * We can't use kernel_thread since we must avoid to reschedule the child.
         */
        if (!keventd_up() || current_is_keventd())
-               work.func(work.data);
+               c_idle.work.func(&c_idle.work);
        else {
-               schedule_work(&work);
+               schedule_work(&c_idle.work);
                wait_for_completion(&c_idle.done);
        }