Merge branch 'linus' into cpus4096
[pandora-kernel.git] / arch / sparc64 / kernel / smp.c
index 3aba476..c099d96 100644 (file)
@@ -807,7 +807,6 @@ extern unsigned long xcall_call_function;
  * smp_call_function(): Run a function on all other CPUs.
  * @func: The function to run. This must be fast and non-blocking.
  * @info: An arbitrary pointer to pass to the function.
- * @nonatomic: currently unused.
  * @wait: If true, wait (atomically) until function has completed on other CPUs.
  *
  * Returns 0 on success, else a negative status code. Does not return until
@@ -816,8 +815,8 @@ extern unsigned long xcall_call_function;
  * You must not call this function with disabled interrupts or from a
  * hardware interrupt handler or from a bottom half handler.
  */
-static int smp_call_function_mask(void (*func)(void *info), void *info,
-                                 int nonatomic, int wait, cpumask_t mask)
+static int sparc64_smp_call_function_mask(void (*func)(void *info), void *info,
+                                         int wait, cpumask_t mask)
 {
        struct call_data_struct data;
        int cpus;
@@ -852,11 +851,9 @@ out_unlock:
        return 0;
 }
 
-int smp_call_function(void (*func)(void *info), void *info,
-                     int nonatomic, int wait)
+int smp_call_function(void (*func)(void *info), void *info, int wait)
 {
-       return smp_call_function_mask(func, info, nonatomic, wait,
-                                     cpu_online_map);
+       return sparc64_smp_call_function_mask(func, info, wait, cpu_online_map);
 }
 
 void smp_call_function_client(int irq, struct pt_regs *regs)
@@ -865,21 +862,14 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
        void *info = call_data->info;
 
        clear_softint(1 << irq);
-
-       irq_enter();
-
-       if (!call_data->wait) {
-               /* let initiator proceed after getting data */
-               atomic_inc(&call_data->finished);
-       }
-
-       func(info);
-
-       irq_exit();
-
        if (call_data->wait) {
                /* let initiator proceed only after completion */
+               func(info);
+               atomic_inc(&call_data->finished);
+       } else {
+               /* let initiator proceed after getting data */
                atomic_inc(&call_data->finished);
+               func(info);
        }
 }
 
@@ -900,13 +890,16 @@ static void tsb_sync(void *info)
 
 void smp_tsb_sync(struct mm_struct *mm)
 {
-       smp_call_function_mask(tsb_sync, mm, 0, 1, mm->cpu_vm_mask);
+       sparc64_smp_call_function_mask(tsb_sync, mm, 1, mm->cpu_vm_mask);
 }
 
 extern unsigned long xcall_flush_tlb_mm;
 extern unsigned long xcall_flush_tlb_pending;
 extern unsigned long xcall_flush_tlb_kernel_range;
 extern unsigned long xcall_report_regs;
+#ifdef CONFIG_MAGIC_SYSRQ
+extern unsigned long xcall_fetch_glob_regs;
+#endif
 extern unsigned long xcall_receive_signal;
 extern unsigned long xcall_new_mmu_context_version;
 #ifdef CONFIG_KGDB
@@ -1041,9 +1034,7 @@ void smp_receive_signal(int cpu)
 
 void smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
-       irq_enter();
        clear_softint(1 << irq);
-       irq_exit();
 }
 
 void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
@@ -1051,8 +1042,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
        struct mm_struct *mm;
        unsigned long flags;
 
-       irq_enter();
-
        clear_softint(1 << irq);
 
        /* See if we need to allocate a new TLB context because
@@ -1072,8 +1061,6 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
        load_secondary_context(mm);
        __flush_tlb_mm(CTX_HWBITS(mm->context),
                       SECONDARY_CONTEXT);
-
-       irq_exit();
 }
 
 void smp_new_mmu_context_version(void)
@@ -1093,6 +1080,13 @@ void smp_report_regs(void)
        smp_cross_call(&xcall_report_regs, 0, 0, 0);
 }
 
+#ifdef CONFIG_MAGIC_SYSRQ
+void smp_fetch_global_regs(void)
+{
+       smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0);
+}
+#endif
+
 /* We know that the window frames of the user have been flushed
  * to the stack before we get here because all callers of us
  * are flush_tlb_*() routines, and these run after flush_cache_*()
@@ -1239,8 +1233,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 
-       irq_enter();
-
        preempt_disable();
 
        __asm__ __volatile__("flushw");
@@ -1253,8 +1245,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
        prom_world(0);
 
        preempt_enable();
-
-       irq_exit();
 }
 
 /* /proc/profile writes can call this, don't __init it please. */