[S390] Convert to smp_call_function_single.
[linux-2.6.git] / arch / s390 / kernel / smp.c
index 3754e20..aff9f85 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/cache.h>
 #include <linux/interrupt.h>
@@ -171,30 +170,28 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
 EXPORT_SYMBOL(smp_call_function);
 
 /*
- * smp_call_function_on:
+ * smp_call_function_single:
+ * @cpu: the CPU where func should run
  * @func: the function to run; this must be fast and non-blocking
  * @info: an arbitrary pointer to pass to the function
  * @nonatomic: unused
  * @wait: if true, wait (atomically) until function has completed on other CPUs
- * @cpu: the CPU where func should run
  *
  * Run a function on one processor.
  *
  * You must not call this function with disabled interrupts, from a
  * hardware interrupt handler or from a bottom half.
  */
-int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic,
-                        int wait, int cpu)
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
+                            int nonatomic, int wait)
 {
-       cpumask_t map = CPU_MASK_NONE;
-
        preempt_disable();
-       cpu_set(cpu, map);
-       __smp_call_function_map(func, info, nonatomic, wait, map);
+       __smp_call_function_map(func, info, nonatomic, wait,
+                               cpumask_of_cpu(cpu));
        preempt_enable();
        return 0;
 }
-EXPORT_SYMBOL(smp_call_function_on);
+EXPORT_SYMBOL(smp_call_function_single);
 
 static void do_send_stop(void)
 {
@@ -411,58 +408,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
 unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
        __attribute__((__section__(".data")));
 
-static void __init smp_get_save_areas(void)
+static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
 {
-       unsigned int cpu, cpu_num, rc;
-       __u16 boot_cpu_addr;
-
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return;
-       boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-       cpu_num = 1;
-       for (cpu = 0; cpu <= 65535; cpu++) {
-               if ((u16) cpu == boot_cpu_addr)
-                       continue;
-               __cpu_logical_map[1] = (__u16) cpu;
-               if (signal_processor(1, sigp_sense) == sigp_not_operational)
-                       continue;
-               if (cpu_num >= NR_CPUS) {
-                       printk("WARNING: Registers for cpu %i are not "
-                              "saved, since dump kernel was compiled with"
-                              "NR_CPUS=%i!\n", cpu_num, NR_CPUS);
-                       continue;
-               }
-               zfcpdump_save_areas[cpu_num] =
-                       alloc_bootmem(sizeof(union save_area));
-               while (1) {
-                       rc = signal_processor(1, sigp_stop_and_store_status);
-                       if (rc != sigp_busy)
-                               break;
-                       cpu_relax();
-               }
-               memcpy(zfcpdump_save_areas[cpu_num],
-                      (void *)(unsigned long) store_prefix() +
-                      SAVE_AREA_BASE, SAVE_AREA_SIZE);
-#ifdef __s390x__
-               /* copy original prefix register */
-               zfcpdump_save_areas[cpu_num]->s390x.pref_reg =
-                       zfcpdump_prefix_array[cpu_num];
-#endif
-               cpu_num++;
+       if (cpu >= NR_CPUS) {
+               printk(KERN_WARNING "Registers for cpu %i not saved since dump "
+                      "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
+               return;
        }
+       zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
+       __cpu_logical_map[1] = (__u16) phy_cpu;
+       while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
+               cpu_relax();
+       memcpy(zfcpdump_save_areas[cpu],
+              (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+              SAVE_AREA_SIZE);
+#ifdef CONFIG_64BIT
+       /* copy original prefix register */
+       zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
+#endif
 }
 
 union save_area *zfcpdump_save_areas[NR_CPUS + 1];
 EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
 
 #else
-#define smp_get_save_areas() do { } while (0)
-#endif
+
+static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
+
+#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
 
 /*
  * Lets check how many CPUs we have.
  */
-
 static unsigned int __init smp_count_cpus(void)
 {
        unsigned int cpu, num_cpus;
@@ -471,7 +450,6 @@ static unsigned int __init smp_count_cpus(void)
        /*
         * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
         */
-
        boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
        current_thread_info()->cpu = 0;
        num_cpus = 1;
@@ -481,19 +459,18 @@ static unsigned int __init smp_count_cpus(void)
                __cpu_logical_map[1] = (__u16) cpu;
                if (signal_processor(1, sigp_sense) == sigp_not_operational)
                        continue;
+               smp_get_save_area(num_cpus, cpu);
                num_cpus++;
        }
-
        printk("Detected %d CPU's\n", (int) num_cpus);
        printk("Boot cpu address %2X\n", boot_cpu_addr);
-
        return num_cpus;
 }
 
 /*
  *     Activate a secondary processor.
  */
-int __devinit start_secondary(void *cpuvoid)
+int __cpuinit start_secondary(void *cpuvoid)
 {
        /* Setup the cpu */
        cpu_init();
@@ -607,7 +584,6 @@ void __init smp_setup_cpu_possible_map(void)
 {
        unsigned int phy_cpus, pos_cpus, cpu;
 
-       smp_get_save_areas();
        phy_cpus = smp_count_cpus();
        pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
 
@@ -742,7 +718,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                        smp_create_idle(cpu);
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void __init smp_prepare_boot_cpu(void)
 {
        BUG_ON(smp_processor_id() != 0);
 
@@ -751,7 +727,7 @@ void __devinit smp_prepare_boot_cpu(void)
        current_set[0] = current;
 }
 
-void smp_cpus_done(unsigned int max_cpus)
+void __init smp_cpus_done(unsigned int max_cpus)
 {
        cpu_present_map = cpu_possible_map;
 }
@@ -790,10 +766,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
 
        switch (action) {
        case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
                if (sysdev_create_file(s, &attr_capability))
                        return NOTIFY_BAD;
                break;
        case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
                sysdev_remove_file(s, &attr_capability);
                break;
        }