diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2008-04-28 12:14:26 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-04-28 12:14:26 -0400 |
commit | 39b8d5254246ac56342b72f812255c8f7a74dca9 (patch) | |
tree | a9ec6bfb5d09a8367c34cc2067328d1b49bb46c1 /arch/mips/kernel/smp-mt.c | |
parent | 308402445e005a039a72b315cd9b5ceeaea0063c (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.c | 96 |
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 | 39 | static void __init smvp_copy_vpe_config(void) |
40 | #define MIPS_CPU_IPI_CALL_IRQ 1 | ||
41 | |||
42 | static int cpu_ipi_resched_irq, cpu_ipi_call_irq; | ||
43 | |||
44 | #if 0 | ||
45 | static 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 | |||
61 | static void ipi_resched_dispatch(void) | ||
62 | { | ||
63 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); | ||
64 | } | ||
65 | |||
66 | static void ipi_call_dispatch(void) | ||
67 | { | ||
68 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | ||
69 | } | ||
70 | |||
71 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
72 | { | ||
73 | return IRQ_HANDLED; | ||
74 | } | ||
75 | |||
76 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
77 | { | ||
78 | smp_call_function_interrupt(); | ||
79 | |||
80 | return IRQ_HANDLED; | ||
81 | } | ||
82 | |||
83 | static struct irqaction irq_resched = { | ||
84 | .handler = ipi_resched_interrupt, | ||
85 | .flags = IRQF_DISABLED|IRQF_PERCPU, | ||
86 | .name = "IPI_resched" | ||
87 | }; | ||
88 | |||
89 | static struct irqaction irq_call = { | ||
90 | .handler = ipi_call_interrupt, | ||
91 | .flags = IRQF_DISABLED|IRQF_PERCPU, | ||
92 | .name = "IPI_call" | ||
93 | }; | ||
94 | |||
95 | static 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 | ||
112 | static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, | 56 | static 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 | ||
143 | static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) | 87 | static 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 | ||
208 | static void __cpuinit vsmp_init_secondary(void) | 152 | static 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 | ||
217 | static void __cpuinit vsmp_smp_finish(void) | 165 | static 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 | */ |
281 | static void __init vsmp_smp_setup(void) | 230 | static 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) | |||
324 | static void __init vsmp_prepare_cpus(unsigned int max_cpus) | 273 | static 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 | ||
344 | struct plat_smp_ops vsmp_smp_ops = { | 278 | struct plat_smp_ops vsmp_smp_ops = { |