Merge branch 'drm-forlinus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / arch / powerpc / kernel / smp.c
index 5c330c3..c8458c5 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
+#include <linux/topology.h>
 
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
 #include <asm/cputable.h>
 #include <asm/system.h>
 #include <asm/mpic.h>
+#include <asm/vdso_datapage.h>
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #endif
 
-int smp_hw_index[NR_CPUS];
-struct thread_info *secondary_ti;
-
 #ifdef DEBUG
+#include <asm/udbg.h>
 #define DBG(fmt...) udbg_printf(fmt)
 #else
 #define DBG(fmt...)
 #endif
 
+int smp_hw_index[NR_CPUS];
+struct thread_info *secondary_ti;
+
 cpumask_t cpu_possible_map = CPU_MASK_NONE;
 cpumask_t cpu_online_map = CPU_MASK_NONE;
 cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
@@ -73,6 +76,8 @@ void smp_call_function_interrupt(void);
 
 int smt_enabled_at_boot = 1;
 
+static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
+
 #ifdef CONFIG_MPIC
 int __init smp_mpic_probe(void)
 {
@@ -121,11 +126,16 @@ void smp_message_recv(int msg, struct pt_regs *regs)
                /* XXX Do we have to do this? */
                set_need_resched();
                break;
-#ifdef CONFIG_DEBUGGER
        case PPC_MSG_DEBUGGER_BREAK:
+               if (crash_ipi_function_ptr) {
+                       crash_ipi_function_ptr(regs);
+                       break;
+               }
+#ifdef CONFIG_DEBUGGER
                debugger_ipi(regs);
                break;
-#endif
+#endif /* CONFIG_DEBUGGER */
+               /* FALLTHROUGH */
        default:
                printk("SMP %d: smp_message_recv(): unknown msg %d\n",
                       smp_processor_id(), msg);
@@ -145,6 +155,17 @@ void smp_send_debugger_break(int cpu)
 }
 #endif
 
+#ifdef CONFIG_KEXEC
+void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
+{
+       crash_ipi_function_ptr = crash_ipi_callback;
+       if (crash_ipi_callback) {
+               mb();
+               smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
+       }
+}
+#endif
+
 static void stop_this_cpu(void *dummy)
 {
        local_irq_disable();
@@ -317,8 +338,8 @@ static void __init smp_create_idle(unsigned int cpu)
 #ifdef CONFIG_PPC64
        paca[cpu].__current = p;
 #endif
-       current_set[cpu] = p->thread_info;
-       p->thread_info->cpu = cpu;
+       current_set[cpu] = task_thread_info(p);
+       task_thread_info(p)->cpu = cpu;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -354,7 +375,7 @@ void __devinit smp_prepare_boot_cpu(void)
 #ifdef CONFIG_PPC64
        paca[boot_cpuid].__current = current;
 #endif
-       current_set[boot_cpuid] = current->thread_info;
+       current_set[boot_cpuid] = task_thread_info(current);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -368,9 +389,11 @@ int generic_cpu_disable(void)
        if (cpu == boot_cpuid)
                return -EBUSY;
 
-       systemcfg->processorCount--;
        cpu_clear(cpu, cpu_online_map);
+#ifdef CONFIG_PPC64
+       vdso_data->processorCount--;
        fixup_irqs(cpu_online_map);
+#endif
        return 0;
 }
 
@@ -388,9 +411,11 @@ int generic_cpu_enable(unsigned int cpu)
        while (!cpu_online(cpu))
                cpu_relax();
 
+#ifdef CONFIG_PPC64
        fixup_irqs(cpu_online_map);
        /* counter the irq disable in fixup_irqs */
        local_irq_enable();
+#endif
        return 0;
 }
 
@@ -419,7 +444,9 @@ void generic_mach_cpu_die(void)
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
                cpu_relax();
 
+#ifdef CONFIG_PPC64
        flush_tlb_pending();
+#endif
        cpu_set(cpu, cpu_online_map);
        local_irq_enable();
 }
@@ -444,10 +471,6 @@ int __devinit __cpu_up(unsigned int cpu)
        if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
                return -EINVAL;
 
-#ifdef CONFIG_PPC64
-       paca[cpu].default_decr = tb_ticks_per_jiffy;
-#endif
-
        /* Make sure callin-map entry is 0 (can be leftover a CPU
         * hotplug
         */
@@ -510,6 +533,7 @@ int __devinit start_secondary(void *unused)
 
        smp_store_cpu_info(cpu);
        set_dec(tb_ticks_per_jiffy);
+       preempt_disable();
        cpu_callin_map[cpu] = 1;
 
        smp_ops->setup_cpu(cpu);
@@ -545,6 +569,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
        smp_ops->setup_cpu(boot_cpuid);
 
        set_cpus_allowed(current, old_mask);
+
+       dump_numa_cpu_topology();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU