aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smp-mt.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2008-04-28 12:14:26 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-04-28 12:14:26 -0400
commit39b8d5254246ac56342b72f812255c8f7a74dca9 (patch)
treea9ec6bfb5d09a8367c34cc2067328d1b49bb46c1 /arch/mips/kernel/smp-mt.c
parent308402445e005a039a72b315cd9b5ceeaea0063c (diff)
[MIPS] Add support for MIPS CMP platform.
Signed-off-by: Chris Dearman <chris@mips.com> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/smp-mt.c')
-rw-r--r--arch/mips/kernel/smp-mt.c96
1 files changed, 15 insertions, 81 deletions
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index e9c393a41775..87a1816c1f45 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -36,63 +36,7 @@
36#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
37#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
38 38
39#define MIPS_CPU_IPI_RESCHED_IRQ 0 39static void __init smvp_copy_vpe_config(void)
40#define MIPS_CPU_IPI_CALL_IRQ 1
41
42static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
43
44#if 0
45static void dump_mtregisters(int vpe, int tc)
46{
47 printk("vpe %d tc %d\n", vpe, tc);
48
49 settc(tc);
50
51 printk(" c0 status 0x%lx\n", read_vpe_c0_status());
52 printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
53 printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
54 printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
55 printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
56 printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
57 printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
58}
59#endif
60
61static void ipi_resched_dispatch(void)
62{
63 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
64}
65
66static void ipi_call_dispatch(void)
67{
68 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
69}
70
71static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
72{
73 return IRQ_HANDLED;
74}
75
76static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
77{
78 smp_call_function_interrupt();
79
80 return IRQ_HANDLED;
81}
82
83static struct irqaction irq_resched = {
84 .handler = ipi_resched_interrupt,
85 .flags = IRQF_DISABLED|IRQF_PERCPU,
86 .name = "IPI_resched"
87};
88
89static struct irqaction irq_call = {
90 .handler = ipi_call_interrupt,
91 .flags = IRQF_DISABLED|IRQF_PERCPU,
92 .name = "IPI_call"
93};
94
95static void __init smp_copy_vpe_config(void)
96{ 40{
97 write_vpe_c0_status( 41 write_vpe_c0_status(
98 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 42 (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
@@ -109,7 +53,7 @@ static void __init smp_copy_vpe_config(void)
109 write_vpe_c0_count(read_c0_count()); 53 write_vpe_c0_count(read_c0_count());
110} 54}
111 55
112static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, 56static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
113 unsigned int ncpu) 57 unsigned int ncpu)
114{ 58{
115 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) 59 if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
@@ -135,12 +79,12 @@ static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
135 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); 79 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
136 80
137 if (tc != 0) 81 if (tc != 0)
138 smp_copy_vpe_config(); 82 smvp_copy_vpe_config();
139 83
140 return ncpu; 84 return ncpu;
141} 85}
142 86
143static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) 87static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
144{ 88{
145 unsigned long tmp; 89 unsigned long tmp;
146 90
@@ -207,15 +151,20 @@ static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
207 151
208static void __cpuinit vsmp_init_secondary(void) 152static void __cpuinit vsmp_init_secondary(void)
209{ 153{
210 /* Enable per-cpu interrupts */ 154 extern int gic_present;
211 155
212 /* This is Malta specific: IPI,performance and timer inetrrupts */ 156 /* This is Malta specific: IPI,performance and timer inetrrupts */
213 write_c0_status((read_c0_status() & ~ST0_IM ) | 157 if (gic_present)
214 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); 158 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
159 STATUSF_IP6 | STATUSF_IP7);
160 else
161 change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
162 STATUSF_IP6 | STATUSF_IP7);
215} 163}
216 164
217static void __cpuinit vsmp_smp_finish(void) 165static void __cpuinit vsmp_smp_finish(void)
218{ 166{
167 /* CDFIXME: remove this? */
219 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 168 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
220 169
221#ifdef CONFIG_MIPS_MT_FPAFF 170#ifdef CONFIG_MIPS_MT_FPAFF
@@ -276,7 +225,7 @@ static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
276/* 225/*
277 * Common setup before any secondaries are started 226 * Common setup before any secondaries are started
278 * Make sure all CPU's are in a sensible state before we boot any of the 227 * Make sure all CPU's are in a sensible state before we boot any of the
279 * secondarys 228 * secondaries
280 */ 229 */
281static void __init vsmp_smp_setup(void) 230static void __init vsmp_smp_setup(void)
282{ 231{
@@ -309,8 +258,8 @@ static void __init vsmp_smp_setup(void)
309 for (tc = 0; tc <= ntc; tc++) { 258 for (tc = 0; tc <= ntc; tc++) {
310 settc(tc); 259 settc(tc);
311 260
312 smp_tc_init(tc, mvpconf0); 261 smvp_tc_init(tc, mvpconf0);
313 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); 262 ncpu = smvp_vpe_init(tc, mvpconf0, ncpu);
314 } 263 }
315 264
316 /* Release config state */ 265 /* Release config state */
@@ -324,21 +273,6 @@ static void __init vsmp_smp_setup(void)
324static void __init vsmp_prepare_cpus(unsigned int max_cpus) 273static void __init vsmp_prepare_cpus(unsigned int max_cpus)
325{ 274{
326 mips_mt_set_cpuoptions(); 275 mips_mt_set_cpuoptions();
327
328 /* set up ipi interrupts */
329 if (cpu_has_vint) {
330 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
331 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
332 }
333
334 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
335 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
336
337 setup_irq(cpu_ipi_resched_irq, &irq_resched);
338 setup_irq(cpu_ipi_call_irq, &irq_call);
339
340 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
341 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
342} 276}
343 277
344struct plat_smp_ops vsmp_smp_ops = { 278struct plat_smp_ops vsmp_smp_ops = {