[MIPS] SMP: Call platform methods via ops structure.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index 3d6b1ec..640fb0c 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -17,7 +17,6 @@
 #include <asm/system.h>
 #include <asm/hardirq.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #include <asm/mipsmtregs.h>
 #include <asm/r4kcache.h>
 #include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 7b4418d..269c252 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -29,6 +29,7 @@
 #include <asm/cpu.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
+#include <asm/smp-ops.h>
 #include <asm/system.h>
 
 struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
@@ -575,9 +576,7 @@
 	arch_mem_init(cmdline_p);
 
 	resource_init();
-#ifdef CONFIG_SMP
 	plat_smp_setup();
-#endif
 }
 
 static int __init fpu_disable(char *s)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 2ab0b7e..89e6f6a 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -215,12 +215,117 @@
 	write_tc_c0_tchalt(TCHALT_H);
 }
 
+static void vsmp_send_ipi_single(int cpu, unsigned int action)
+{
+	int i;
+	unsigned long flags;
+	int vpflags;
+
+	local_irq_save(flags);
+
+	vpflags = dvpe();	/* cant access the other CPU's registers whilst MVPE enabled */
+
+	switch (action) {
+	case SMP_CALL_FUNCTION:
+		i = C_SW1;
+		break;
+
+	case SMP_RESCHEDULE_YOURSELF:
+	default:
+		i = C_SW0;
+		break;
+	}
+
+	/* 1:1 mapping of vpe and tc... */
+	settc(cpu);
+	write_vpe_c0_cause(read_vpe_c0_cause() | i);
+	evpe(vpflags);
+
+	local_irq_restore(flags);
+}
+
+static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
+{
+	unsigned int i;
+
+	for_each_cpu_mask(i, mask)
+		vsmp_send_ipi_single(i, action);
+}
+
+static void __cpuinit vsmp_init_secondary(void)
+{
+	/* Enable per-cpu interrupts */
+
+	/* This is Malta specific: IPI,performance and timer inetrrupts */
+	write_c0_status((read_c0_status() & ~ST0_IM ) |
+	                (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
+}
+
+static void __cpuinit vsmp_smp_finish(void)
+{
+	write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+	/* If we have an FPU, enroll ourselves in the FPU-full mask */
+	if (cpu_has_fpu)
+		cpu_set(smp_processor_id(), mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+	local_irq_enable();
+}
+
+static void vsmp_cpus_done(void)
+{
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ * assumes a 1:1 mapping of TC => VPE
+ */
+static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
+{
+	struct thread_info *gp = task_thread_info(idle);
+	dvpe();
+	set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+	settc(cpu);
+
+	/* restart */
+	write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+	/* enable the tc this vpe/cpu will be running */
+	write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
+
+	write_tc_c0_tchalt(0);
+
+	/* enable the VPE */
+	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+	/* stack pointer */
+	write_tc_gpr_sp( __KSTK_TOS(idle));
+
+	/* global pointer */
+	write_tc_gpr_gp((unsigned long)gp);
+
+	flush_icache_range((unsigned long)gp,
+	                   (unsigned long)(gp + sizeof(struct thread_info)));
+
+	/* finally out of configuration and into chaos */
+	clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+	evpe(EVPE_ENABLE);
+}
+
 /*
  * Common setup before any secondaries are started
  * Make sure all CPU's are in a sensible state before we boot any of the
  * secondarys
  */
-void __init plat_smp_setup(void)
+static void __init vsmp_smp_setup(void)
 {
 	unsigned int mvpconf0, ntc, tc, ncpu = 0;
 	unsigned int nvpe;
@@ -263,7 +368,7 @@
 	printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
 }
 
-void __init plat_prepare_cpus(unsigned int max_cpus)
+static void __init vsmp_prepare_cpus(unsigned int max_cpus)
 {
 	mips_mt_set_cpuoptions();
 
@@ -283,99 +388,13 @@
 	set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
 }
 
-/*
- * Setup the PC, SP, and GP of a secondary processor and start it
- * running!
- * smp_bootstrap is the place to resume from
- * __KSTK_TOS(idle) is apparently the stack pointer
- * (unsigned long)idle->thread_info the gp
- * assumes a 1:1 mapping of TC => VPE
- */
-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
-{
-	struct thread_info *gp = task_thread_info(idle);
-	dvpe();
-	set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-	settc(cpu);
-
-	/* restart */
-	write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
-
-	/* enable the tc this vpe/cpu will be running */
-	write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
-
-	write_tc_c0_tchalt(0);
-
-	/* enable the VPE */
-	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
-
-	/* stack pointer */
-	write_tc_gpr_sp( __KSTK_TOS(idle));
-
-	/* global pointer */
-	write_tc_gpr_gp((unsigned long)gp);
-
-	flush_icache_range((unsigned long)gp,
-	                   (unsigned long)(gp + sizeof(struct thread_info)));
-
-	/* finally out of configuration and into chaos */
-	clear_c0_mvpcontrol(MVPCONTROL_VPC);
-
-	evpe(EVPE_ENABLE);
-}
-
-void __cpuinit prom_init_secondary(void)
-{
-	/* Enable per-cpu interrupts */
-
-	/* This is Malta specific: IPI,performance and timer inetrrupts */
-	write_c0_status((read_c0_status() & ~ST0_IM ) |
-	                (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
-}
-
-void __cpuinit prom_smp_finish(void)
-{
-	write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
-
-#ifdef CONFIG_MIPS_MT_FPAFF
-	/* If we have an FPU, enroll ourselves in the FPU-full mask */
-	if (cpu_has_fpu)
-		cpu_set(smp_processor_id(), mt_fpu_cpumask);
-#endif /* CONFIG_MIPS_MT_FPAFF */
-
-	local_irq_enable();
-}
-
-void prom_cpus_done(void)
-{
-}
-
-void core_send_ipi(int cpu, unsigned int action)
-{
-	int i;
-	unsigned long flags;
-	int vpflags;
-
-	local_irq_save(flags);
-
-	vpflags = dvpe();	/* cant access the other CPU's registers whilst MVPE enabled */
-
-	switch (action) {
-	case SMP_CALL_FUNCTION:
-		i = C_SW1;
-		break;
-
-	case SMP_RESCHEDULE_YOURSELF:
-	default:
-		i = C_SW0;
-		break;
-	}
-
-	/* 1:1 mapping of vpe and tc... */
-	settc(cpu);
-	write_vpe_c0_cause(read_vpe_c0_cause() | i);
-	evpe(vpflags);
-
-	local_irq_restore(flags);
-}
+struct plat_smp_ops vsmp_smp_ops = {
+	.send_ipi_single	= vsmp_send_ipi_single,
+	.send_ipi_mask		= vsmp_send_ipi_mask,
+	.init_secondary		= vsmp_init_secondary,
+	.smp_finish		= vsmp_smp_finish,
+	.cpus_done		= vsmp_cpus_done,
+	.boot_secondary		= vsmp_boot_secondary,
+	.smp_setup		= vsmp_smp_setup,
+	.prepare_cpus		= vsmp_prepare_cpus,
+};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 335be9b..1e5dfc2 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -37,7 +37,6 @@
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #include <asm/time.h>
 
 #ifdef CONFIG_MIPS_MT_SMTC
@@ -84,6 +83,16 @@
 		cpu_set(cpu, cpu_sibling_map[cpu]);
 }
 
+struct plat_smp_ops *mp_ops;
+
+__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
+{
+	if (ops)
+		printk(KERN_WARNING "Overriding previous set SMP ops\n");
+
+	mp_ops = ops;
+}
+
 /*
  * First C code run on the secondary CPUs after being started up by
  * the master.
@@ -100,7 +109,7 @@
 	cpu_report();
 	per_cpu_trap_init();
 	mips_clockevent_init();
-	prom_init_secondary();
+	mp_ops->init_secondary();
 
 	/*
 	 * XXX parity protection should be folded in here when it's converted
@@ -112,7 +121,7 @@
 	cpu = smp_processor_id();
 	cpu_data[cpu].udelay_val = loops_per_jiffy;
 
-	prom_smp_finish();
+	mp_ops->smp_finish();
 	set_cpu_sibling_map(cpu);
 
 	cpu_set(cpu, cpu_callin_map);
@@ -184,7 +193,7 @@
 	smp_mb();
 
 	/* Send a message to all other CPUs and wait for them to respond */
-	core_send_ipi_mask(mask, SMP_CALL_FUNCTION);
+	mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
 
 	/* Wait for response */
 	/* FIXME: lock-up detection, backtrace on lock-up */
@@ -278,7 +287,7 @@
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
-	prom_cpus_done();
+	mp_ops->cpus_done();
 }
 
 /* called from main before smp_init() */
@@ -286,7 +295,7 @@
 {
 	init_new_context(current, &init_mm);
 	current_thread_info()->cpu = 0;
-	plat_prepare_cpus(max_cpus);
+	mp_ops->prepare_cpus(max_cpus);
 	set_cpu_sibling_map(0);
 #ifndef CONFIG_HOTPLUG_CPU
 	cpu_present_map = cpu_possible_map;
@@ -325,7 +334,7 @@
 	if (IS_ERR(idle))
 		panic(KERN_ERR "Fork failed for CPU %d", cpu);
 
-	prom_boot_secondary(cpu, idle);
+	mp_ops->boot_secondary(cpu, idle);
 
 	/*
 	 * Trust is futile.  We should really have timeouts ...
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
index 6f37099..fe25655 100644
--- a/arch/mips/kernel/smtc-proc.c
+++ b/arch/mips/kernel/smtc-proc.c
@@ -14,7 +14,6 @@
 #include <asm/system.h>
 #include <asm/hardirq.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
 #include <linux/proc_fs.h>
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 9c92d42..85f700e 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -16,7 +16,6 @@
 #include <asm/hazards.h>
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
-#include <asm/smp.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
 #include <asm/time.h>