diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-11-19 12:23:51 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-01-29 10:14:57 +0000 |
commit | 87353d8ac39c52784da605ecbe965ecdfad609ad (patch) | |
tree | c95ce7cbe9b099c21cab71a195621801b04bc05a | |
parent | 19388fb092d89e179575bd0b44f51b57e175edf5 (diff) |
[MIPS] SMP: Call platform methods via ops structure.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
27 files changed, 681 insertions, 485 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8cbdfd25567..b211e7961f2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1441,6 +1441,7 @@ config MIPS_MT_SMP select SMP select SYS_SUPPORTS_SCHED_SMT if SMP select SYS_SUPPORTS_SMP + select SMP_UP help This is a kernel model which is also known a VSMP or lately has been marketesed into SMVP. @@ -1457,6 +1458,7 @@ config MIPS_MT_SMTC select NR_CPUS_DEFAULT_8 select SMP select SYS_SUPPORTS_SMP + select SMP_UP help This is a kernel model which is known a SMTC or lately has been marketesed into SMVP. @@ -1735,6 +1737,9 @@ config SMP If you don't know what to do here, say N. +config SMP_UP + bool + config SYS_SUPPORTS_SMP bool diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c index e2f75b13312..3ad8788b6ea 100644 --- a/arch/mips/fw/arc/init.c +++ b/arch/mips/fw/arc/init.c @@ -12,6 +12,7 @@ #include <asm/bootinfo.h> #include <asm/sgialib.h> +#include <asm/smp-ops.h> #undef DEBUG_PROM_INIT @@ -48,4 +49,11 @@ void __init prom_init(void) ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); #endif +#ifdef CONFIG_SGI_IP27 + { + extern struct plat_smp_ops ip27_smp_ops; + + register_smp_ops(&ip27_smp_ops); + } +#endif } diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index 3d6b1ec1f32..640fb0cc6e3 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 7b4418dd585..269c252d956 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 @@ void __init setup_arch(char **cmdline_p) 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 2ab0b7eeaa7..89e6f6aa516 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -215,72 +215,67 @@ static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) write_tc_c0_tchalt(TCHALT_H); } -/* - * 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 vsmp_send_ipi_single(int cpu, unsigned int action) { - unsigned int mvpconf0, ntc, tc, ncpu = 0; - unsigned int nvpe; + int i; + unsigned long flags; + int vpflags; -#ifdef CONFIG_MIPS_MT_FPAFF - /* If we have an FPU, enroll ourselves in the FPU-full mask */ - if (cpu_has_fpu) - cpu_set(0, mt_fpu_cpumask); -#endif /* CONFIG_MIPS_MT_FPAFF */ - if (!cpu_has_mipsmt) - return; + local_irq_save(flags); - /* disable MT so we can configure */ - dvpe(); - dmt(); + vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ - /* Put MVPE's into 'configuration state' */ - set_c0_mvpcontrol(MVPCONTROL_VPC); + switch (action) { + case SMP_CALL_FUNCTION: + i = C_SW1; + break; - mvpconf0 = read_c0_mvpconf0(); - ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; + case SMP_RESCHEDULE_YOURSELF: + default: + i = C_SW0; + break; + } - nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; - smp_num_siblings = nvpe; + /* 1:1 mapping of vpe and tc... */ + settc(cpu); + write_vpe_c0_cause(read_vpe_c0_cause() | i); + evpe(vpflags); - /* we'll always have more TC's than VPE's, so loop setting everything - to a sensible state */ - for (tc = 0; tc <= ntc; tc++) { - settc(tc); + local_irq_restore(flags); +} - smp_tc_init(tc, mvpconf0); - ncpu = smp_vpe_init(tc, mvpconf0, ncpu); - } +static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action) +{ + unsigned int i; - /* Release config state */ - clear_c0_mvpcontrol(MVPCONTROL_VPC); + for_each_cpu_mask(i, mask) + vsmp_send_ipi_single(i, action); +} - /* We'll wait until starting the secondaries before starting MVPE */ +static void __cpuinit vsmp_init_secondary(void) +{ + /* Enable per-cpu interrupts */ - printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); + /* 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 __init plat_prepare_cpus(unsigned int max_cpus) +static void __cpuinit vsmp_smp_finish(void) { - mips_mt_set_cpuoptions(); - - /* set up ipi interrupts */ - if (cpu_has_vint) { - set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); - set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); - } + write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); - cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; - cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; +#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 */ - setup_irq(cpu_ipi_resched_irq, &irq_resched); - setup_irq(cpu_ipi_call_irq, &irq_call); + local_irq_enable(); +} - set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); - set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); +static void vsmp_cpus_done(void) +{ } /* @@ -291,7 +286,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) * (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) +static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); dvpe(); @@ -325,57 +320,81 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) 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) +/* + * Common setup before any secondaries are started + * Make sure all CPU's are in a sensible state before we boot any of the + * secondarys + */ +static void __init vsmp_smp_setup(void) { - write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); + unsigned int mvpconf0, ntc, tc, ncpu = 0; + unsigned int nvpe; #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); + cpu_set(0, mt_fpu_cpumask); #endif /* CONFIG_MIPS_MT_FPAFF */ + if (!cpu_has_mipsmt) + return; - local_irq_enable(); -} + /* disable MT so we can configure */ + dvpe(); + dmt(); -void prom_cpus_done(void) -{ -} + /* Put MVPE's into 'configuration state' */ + set_c0_mvpcontrol(MVPCONTROL_VPC); -void core_send_ipi(int cpu, unsigned int action) -{ - int i; - unsigned long flags; - int vpflags; + mvpconf0 = read_c0_mvpconf0(); + ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; - local_irq_save(flags); + nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; + smp_num_siblings = nvpe; - vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ + /* we'll always have more TC's than VPE's, so loop setting everything + to a sensible state */ + for (tc = 0; tc <= ntc; tc++) { + settc(tc); - switch (action) { - case SMP_CALL_FUNCTION: - i = C_SW1; - break; + smp_tc_init(tc, mvpconf0); + ncpu = smp_vpe_init(tc, mvpconf0, ncpu); + } - case SMP_RESCHEDULE_YOURSELF: - default: - i = C_SW0; - break; + /* Release config state */ + clear_c0_mvpcontrol(MVPCONTROL_VPC); + + /* We'll wait until starting the secondaries before starting MVPE */ + + printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); +} + +static void __init vsmp_prepare_cpus(unsigned int max_cpus) +{ + mips_mt_set_cpuoptions(); + + /* set up ipi interrupts */ + if (cpu_has_vint) { + set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); + set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); } - /* 1:1 mapping of vpe and tc... */ - settc(cpu); - write_vpe_c0_cause(read_vpe_c0_cause() | i); - evpe(vpflags); + cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; + cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; - local_irq_restore(flags); + setup_irq(cpu_ipi_resched_irq, &irq_resched); + setup_irq(cpu_ipi_call_irq, &irq_call); + + set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); + set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } + +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 335be9bcf0d..1e5dfc28294 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 @@ static inline void set_cpu_sibling_map(int cpu) 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 @@ asmlinkage __cpuinit void start_secondary(void) 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 @@ asmlinkage __cpuinit void start_secondary(void) 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 @@ int smp_call_function_mask(cpumask_t mask, void (*func) (void *info), 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 smp_send_stop(void) 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 @@ void __init smp_prepare_cpus(unsigned int max_cpus) { 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 @@ int __cpuinit __cpu_up(unsigned int cpu) 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 6f370999617..fe256559c99 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 9c92d42996c..85f700e5813 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> diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index 30f1f54cb68..1695dca5506 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c @@ -250,6 +250,8 @@ void __init mips_ejtag_setup(void) flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } +extern struct plat_smp_ops msmtc_smp_ops; + void __init prom_init(void) { prom_argc = fw_arg0; @@ -416,4 +418,10 @@ void __init prom_init(void) #ifdef CONFIG_SERIAL_8250_CONSOLE console_config(); #endif +#ifdef CONFIG_MIPS_MT_SMP + register_smp_ops(&vsmp_smp_ops); +#endif +#ifdef CONFIG_MIPS_MT_SMTC + register_smp_ops(&msmtc_smp_ops); +#endif } diff --git a/arch/mips/mips-boards/malta/malta_smtc.c b/arch/mips/mips-boards/malta/malta_smtc.c index 5c980f4a48f..6f051ca243f 100644 --- a/arch/mips/mips-boards/malta/malta_smtc.c +++ b/arch/mips/mips-boards/malta/malta_smtc.c @@ -15,26 +15,24 @@ * Cause the specified action to be performed on a targeted "CPU" */ -void core_send_ipi(int cpu, unsigned int action) +static void msmtc_send_ipi_single(int cpu, unsigned int action) { /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ smtc_send_ipi(cpu, LINUX_SMP_IPI, action); } -/* - * Platform "CPU" startup hook - */ - -void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) +static void msmtc_send_ipi_mask(cpumask_t mask, unsigned int action) { - smtc_boot_secondary(cpu, idle); + unsigned int i; + + for_each_cpu_mask(i, mask) + msmtc_send_ipi_single(i, action); } /* * Post-config but pre-boot cleanup entry point */ - -void __cpuinit prom_init_secondary(void) +static void __cpuinit msmtc_init_secondary(void) { void smtc_init_secondary(void); int myvpe; @@ -50,45 +48,61 @@ void __cpuinit prom_init_secondary(void) set_c0_status(0x100 << cp0_perfcount_irq); } - smtc_init_secondary(); + smtc_init_secondary(); } /* - * Platform SMP pre-initialization - * - * As noted above, we can assume a single CPU for now - * but it may be multithreaded. + * Platform "CPU" startup hook */ - -void __cpuinit plat_smp_setup(void) +static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle) { - if (read_c0_config3() & (1<<2)) - mipsmt_build_cpu_map(0); + smtc_boot_secondary(cpu, idle); } -void __init plat_prepare_cpus(unsigned int max_cpus) +/* + * SMP initialization finalization entry point + */ +static void __cpuinit msmtc_smp_finish(void) { - if (read_c0_config3() & (1<<2)) - mipsmt_prepare_cpus(); + smtc_smp_finish(); } /* - * SMP initialization finalization entry point + * Hook for after all CPUs are online */ -void __cpuinit prom_smp_finish(void) +static void msmtc_cpus_done(void) { - smtc_smp_finish(); } /* - * Hook for after all CPUs are online + * Platform SMP pre-initialization + * + * As noted above, we can assume a single CPU for now + * but it may be multithreaded. */ -void prom_cpus_done(void) +static void __init msmtc_smp_setup(void) { + mipsmt_build_cpu_map(0); } +static void __init msmtc_prepare_cpus(unsigned int max_cpus) +{ + mipsmt_prepare_cpus(); +} + +struct plat_smp_ops msmtc_smp_ops = { + .send_ipi_single = msmtc_send_ipi_single, + .send_ipi_mask = msmtc_send_ipi_mask, + .init_secondary = msmtc_init_secondary, + .smp_finish = msmtc_smp_finish, + .cpus_done = msmtc_cpus_done, + .boot_secondary = msmtc_boot_secondary, + .smp_setup = msmtc_smp_setup, + .prepare_cpus = msmtc_prepare_cpus, +}; + #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF /* * IRQ affinity hook diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile index 75568b584df..57f43c1c788 100644 --- a/arch/mips/mipssim/Makefile +++ b/arch/mips/mipssim/Makefile @@ -21,6 +21,6 @@ obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \ sim_cmdline.o obj-$(CONFIG_EARLY_PRINTK) += sim_console.o -obj-$(CONFIG_SMP) += sim_smp.o +obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c index 452c129d02c..d49fe73426b 100644 --- a/arch/mips/mipssim/sim_setup.c +++ b/arch/mips/mipssim/sim_setup.c @@ -60,6 +60,8 @@ void __init plat_mem_setup(void) #endif } +extern struct plat_smp_ops ssmtc_smp_ops; + void __init prom_init(void) { set_io_port_base(0xbfd00000); @@ -67,8 +69,20 @@ void __init prom_init(void) pr_info("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); -} +#ifdef CONFIG_MIPS_MT_SMP + if (cpu_has_mipsmt) + register_smp_ops(&vsmp_smp_ops); + else + register_smp_ops(&up_smp_ops); +#endif +#ifdef CONFIG_MIPS_MT_SMTC + if (cpu_has_mipsmt) + register_smp_ops(&ssmtc_smp_ops); + else + register_smp_ops(&up_smp_ops); +#endif +} static void __init serial_init(void) { diff --git a/arch/mips/mipssim/sim_smp.c b/arch/mips/mipssim/sim_smtc.c index ccbbccac23e..d6e4f656ad1 100644 --- a/arch/mips/mipssim/sim_smp.c +++ b/arch/mips/mipssim/sim_smtc.c @@ -16,7 +16,7 @@ * */ /* - * Simulator Platform-specific hooks for SMP operation + * Simulator Platform-specific hooks for SMTC operation */ #include <linux/kernel.h> #include <linux/sched.h> @@ -29,65 +29,72 @@ #include <asm/processor.h> #include <asm/system.h> #include <asm/mmu_context.h> -#ifdef CONFIG_MIPS_MT_SMTC #include <asm/smtc_ipi.h> -#endif /* CONFIG_MIPS_MT_SMTC */ /* VPE/SMP Prototype implements platform interfaces directly */ -#if !defined(CONFIG_MIPS_MT_SMP) /* * Cause the specified action to be performed on a targeted "CPU" */ -void core_send_ipi(int cpu, unsigned int action) +static void ssmtc_send_ipi_single(int cpu, unsigned int action) { -#ifdef CONFIG_MIPS_MT_SMTC smtc_send_ipi(cpu, LINUX_SMP_IPI, action); -#endif /* CONFIG_MIPS_MT_SMTC */ -/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ + /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ +} + +static inline void ssmtc_send_ipi_mask(cpumask_t mask, unsigned int action) +{ + unsigned int i; + for_each_cpu_mask(i, mask) + ssmtc_send_ipi_single(i, action); } /* - * Platform "CPU" startup hook + * Post-config but pre-boot cleanup entry point */ - -void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) +static void __cpuinit ssmtc_init_secondary(void) { -#ifdef CONFIG_MIPS_MT_SMTC - smtc_boot_secondary(cpu, idle); -#endif /* CONFIG_MIPS_MT_SMTC */ + void smtc_init_secondary(void); + + smtc_init_secondary(); } /* - * Post-config but pre-boot cleanup entry point + * SMP initialization finalization entry point */ +static void __cpuinit ssmtc_smp_finish(void) +{ + smtc_smp_finish(); +} -void __cpuinit prom_init_secondary(void) +/* + * Hook for after all CPUs are online + */ +static void ssmtc_cpus_done(void) { -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_init_secondary(void); +} - smtc_init_secondary(); -#endif /* CONFIG_MIPS_MT_SMTC */ +/* + * Platform "CPU" startup hook + */ +static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle) +{ + smtc_boot_secondary(cpu, idle); } -void plat_smp_setup(void) +static void __init ssmtc_smp_setup(void) { -#ifdef CONFIG_MIPS_MT_SMTC if (read_c0_config3() & (1 << 2)) mipsmt_build_cpu_map(0); -#endif /* CONFIG_MIPS_MT_SMTC */ } /* * Platform SMP pre-initialization */ - -void plat_prepare_cpus(unsigned int max_cpus) +static void ssmtc_prepare_cpus(unsigned int max_cpus) { -#ifdef CONFIG_MIPS_MT_SMTC /* * As noted above, we can assume a single CPU for now * but it may be multithreaded. @@ -96,28 +103,15 @@ void plat_prepare_cpus(unsigned int max_cpus) if (read_c0_config3() & (1 << 2)) { mipsmt_prepare_cpus(); } -#endif /* CONFIG_MIPS_MT_SMTC */ } -/* - * SMP initialization finalization entry point - */ - -void __cpuinit prom_smp_finish(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - smtc_smp_finish(); -#endif /* CONFIG_MIPS_MT_SMTC */ -} - -/* - * Hook for after all CPUs are online - */ - -void prom_cpus_done(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - -#endif /* CONFIG_MIPS_MT_SMTC */ -} -#endif /* CONFIG_MIPS32R2_MT_SMP */ +struct plat_smp_ops ssmtc_smp_ops = { + .send_ipi_single = ssmtc_send_ipi_single, + .send_ipi_mask = ssmtc_send_ipi_mask, + .init_secondary = ssmtc_init_secondary, + .smp_finish = ssmtc_smp_finish, + .cpus_done = ssmtc_cpus_done, + .boot_secondary = ssmtc_boot_secondary, + .smp_setup = ssmtc_smp_setup, + .prepare_cpus = ssmtc_prepare_cpus, +}; diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index 96d3ff051d3..35dc435846a 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c @@ -19,6 +19,7 @@ #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/reboot.h> +#include <asm/smp-ops.h> #include <asm/system.h> #include <asm/bootinfo.h> #include <asm/pmon.h> @@ -78,6 +79,8 @@ static void prom_halt(void) __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); } +extern struct plat_smp_ops yos_smp_ops; + /* * Init routine which accepts the variables from PMON */ @@ -127,6 +130,8 @@ void __init prom_init(void) } prom_grab_secondary(); + + register_smp_ops(&yos_smp_ops); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index b0f12cd2968..653f3ec61ca 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -42,70 +42,6 @@ void __init prom_grab_secondary(void) launchstack + LAUNCHSTACK_SIZE, 0); } -/* - * Detect available CPUs, populate phys_cpu_present_map before smp_init - * - * We don't want to start the secondary CPU yet nor do we have a nice probing - * feature in PMON so we just assume presence of the secondary core. - */ -void __init plat_smp_setup(void) -{ - int i; - - cpus_clear(phys_cpu_present_map); - - for (i = 0; i < 2; i++) { - cpu_set(i, phys_cpu_present_map); - __cpu_number_map[i] = i; - __cpu_logical_map[i] = i; - } -} - -void __init plat_prepare_cpus(unsigned int max_cpus) -{ - /* - * Be paranoid. Enable the IPI only if we're really about to go SMP. - */ - if (cpus_weight(cpu_possible_map)) - set_c0_status(STATUSF_IP5); -} - -/* - * Firmware CPU startup hook - * Complicated by PMON's weird interface which tries to minimic the UNIX fork. - * It launches the next * available CPU and copies some information on the - * stack so the first thing we do is throw away that stuff and load useful - * values into the registers ... - */ -void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) -{ - unsigned long gp = (unsigned long) task_thread_info(idle); - unsigned long sp = __KSTK_TOS(idle); - - secondary_sp = sp; - secondary_gp = gp; - - spin_unlock(&launch_lock); -} - -/* Hook for after all CPUs are online */ -void prom_cpus_done(void) -{ -} - -/* - * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed - */ -void __cpuinit prom_init_secondary(void) -{ - set_c0_status(ST0_CO | ST0_IE | ST0_IM); -} - -void __cpuinit prom_smp_finish(void) -{ -} - void titan_mailbox_irq(void) { int cpu = smp_processor_id(); @@ -133,7 +69,7 @@ void titan_mailbox_irq(void) /* * Send inter-processor interrupt */ -void core_send_ipi(int cpu, unsigned int action) +static void yos_send_ipi_single(int cpu, unsigned int action) { /* * Generate an INTMSG so that it can be sent over to the @@ -159,3 +95,86 @@ void core_send_ipi(int cpu, unsigned int action) break; } } + +static void yos_send_ipi_mask(cpumask_t mask, unsigned int action) +{ + unsigned int i; + + for_each_cpu_mask(i, mask) + yos_send_ipi_single(i, action); +} + +/* + * After we've done initial boot, this function is called to allow the + * board code to clean up state, if needed + */ +static void __cpuinit yos_init_secondary(void) +{ + set_c0_status(ST0_CO | ST0_IE | ST0_IM); +} + +static void __cpuinit yos_smp_finish(void) +{ +} + +/* Hook for after all CPUs are online */ +static void yos_cpus_done(void) +{ +} + +/* + * Firmware CPU startup hook + * Complicated by PMON's weird interface which tries to min |