powerpc: Implement smp_release_cpus() in C not asm
There's no reason for smp_release_cpus() to be asm, and most people can make
more sense of C code. Add an extern declaration to smp.h and remove the custom
one in machine_kexec.c
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index ba30e31..45d8197 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1914,24 +1914,6 @@
blr
#endif
-#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
-_GLOBAL(smp_release_cpus)
- /* All secondary cpus are spinning on a common
- * spinloop, release them all now so they can start
- * to spin on their individual paca spinloops.
- * For non SMP kernels, the secondary cpus never
- * get out of the common spinloop.
- * XXX This does nothing useful on iSeries, secondaries are
- * already waiting on their paca.
- */
- li r3,1
- LOADADDR(r5,__secondary_hold_spinloop)
- std r3,0(r5)
- sync
- blr
-#endif /* CONFIG_SMP */
-
-
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the bss, which is page-aligned.
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index d4a3c5d..275d86d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -103,8 +103,6 @@
extern void early_init_devtree(void *flat_dt);
extern void unflatten_device_tree(void);
-extern void smp_release_cpus(void);
-
int have_of = 1;
int boot_cpuid = 0;
int boot_cpuid_phys = 0;
@@ -400,6 +398,27 @@
}
+#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+void smp_release_cpus(void)
+{
+ extern unsigned long __secondary_hold_spinloop;
+
+ DBG(" -> smp_release_cpus()\n");
+
+ /* All secondary cpus are spinning on a common spinloop, release them
+ * all now so they can start to spin on their individual paca
+ * spinloops. For non SMP kernels, the secondary cpus never get out
+ * of the common spinloop.
+ * This is useless but harmless on iSeries, secondaries are already
+ * waiting on their paca spinloops. */
+
+ __secondary_hold_spinloop = 1;
+ mb();
+
+ DBG(" <- smp_release_cpus()\n");
+}
+#endif /* CONFIG_SMP || CONFIG_KEXEC */
+
/*
* Initialize some remaining members of the ppc64_caches and systemcfg structures
* (at least until we get rid of them completely). This is mostly some
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 0b65efe..db1cf39 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -1914,24 +1914,6 @@
blr
#endif
-#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
-_GLOBAL(smp_release_cpus)
- /* All secondary cpus are spinning on a common
- * spinloop, release them all now so they can start
- * to spin on their individual paca spinloops.
- * For non SMP kernels, the secondary cpus never
- * get out of the common spinloop.
- * XXX This does nothing useful on iSeries, secondaries are
- * already waiting on their paca.
- */
- li r3,1
- LOADADDR(r5,__secondary_hold_spinloop)
- std r3,0(r5)
- sync
- blr
-#endif /* CONFIG_SMP */
-
-
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the bss, which is page-aligned.
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
index bf7cc4f..ff8679f 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -244,7 +244,6 @@
static void kexec_prepare_cpus(void)
{
- extern void smp_release_cpus(void);
/*
* move the secondarys to us so that we can copy
* the new kernel 0-0x100 safely
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
index 46c0404..ba0f5c8 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -79,6 +79,7 @@
extern int smp_mpic_probe(void);
extern void smp_mpic_setup_cpu(int cpu);
extern void smp_generic_kick_cpu(int nr);
+extern void smp_release_cpus(void);
extern void smp_generic_give_timebase(void);
extern void smp_generic_take_timebase(void);