aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sun4m_smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/sun4m_smp.c')
-rw-r--r--arch/sparc/kernel/sun4m_smp.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 5cc7dc51de3d..594768686525 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -15,6 +15,9 @@
15#include "irq.h" 15#include "irq.h"
16#include "kernel.h" 16#include "kernel.h"
17 17
18#define IRQ_IPI_SINGLE 12
19#define IRQ_IPI_MASK 13
20#define IRQ_IPI_RESCHED 14
18#define IRQ_CROSS_CALL 15 21#define IRQ_CROSS_CALL 15
19 22
20static inline unsigned long 23static inline unsigned long
@@ -26,6 +29,7 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val)
26 return val; 29 return val;
27} 30}
28 31
32static void smp4m_ipi_init(void);
29static void smp_setup_percpu_timer(void); 33static void smp_setup_percpu_timer(void);
30 34
31void __cpuinit smp4m_callin(void) 35void __cpuinit smp4m_callin(void)
@@ -59,8 +63,6 @@ void __cpuinit smp4m_callin(void)
59 local_flush_cache_all(); 63 local_flush_cache_all();
60 local_flush_tlb_all(); 64 local_flush_tlb_all();
61 65
62 cpu_probe();
63
64 /* Fix idle thread fields. */ 66 /* Fix idle thread fields. */
65 __asm__ __volatile__("ld [%0], %%g6\n\t" 67 __asm__ __volatile__("ld [%0], %%g6\n\t"
66 : : "r" (&current_set[cpuid]) 68 : : "r" (&current_set[cpuid])
@@ -70,7 +72,7 @@ void __cpuinit smp4m_callin(void)
70 atomic_inc(&init_mm.mm_count); 72 atomic_inc(&init_mm.mm_count);
71 current->active_mm = &init_mm; 73 current->active_mm = &init_mm;
72 74
73 while (!cpu_isset(cpuid, smp_commenced_mask)) 75 while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
74 mb(); 76 mb();
75 77
76 local_irq_enable(); 78 local_irq_enable();
@@ -83,6 +85,7 @@ void __cpuinit smp4m_callin(void)
83 */ 85 */
84void __init smp4m_boot_cpus(void) 86void __init smp4m_boot_cpus(void)
85{ 87{
88 smp4m_ipi_init();
86 smp_setup_percpu_timer(); 89 smp_setup_percpu_timer();
87 local_flush_cache_all(); 90 local_flush_cache_all();
88} 91}
@@ -150,18 +153,25 @@ void __init smp4m_smp_done(void)
150 /* Ok, they are spinning and ready to go. */ 153 /* Ok, they are spinning and ready to go. */
151} 154}
152 155
153/* At each hardware IRQ, we get this called to forward IRQ reception 156
154 * to the next processor. The caller must disable the IRQ level being 157/* Initialize IPIs on the SUN4M SMP machine */
155 * serviced globally so that there are no double interrupts received. 158static void __init smp4m_ipi_init(void)
156 * 159{
157 * XXX See sparc64 irq.c. 160}
158 */ 161
159void smp4m_irq_rotate(int cpu) 162static void smp4m_ipi_resched(int cpu)
163{
164 set_cpu_int(cpu, IRQ_IPI_RESCHED);
165}
166
167static void smp4m_ipi_single(int cpu)
160{ 168{
161 int next = cpu_data(cpu).next; 169 set_cpu_int(cpu, IRQ_IPI_SINGLE);
170}
162 171
163 if (next != cpu) 172static void smp4m_ipi_mask_one(int cpu)
164 set_irq_udt(next); 173{
174 set_cpu_int(cpu, IRQ_IPI_MASK);
165} 175}
166 176
167static struct smp_funcall { 177static struct smp_funcall {
@@ -199,10 +209,10 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
199 { 209 {
200 register int i; 210 register int i;
201 211
202 cpu_clear(smp_processor_id(), mask); 212 cpumask_clear_cpu(smp_processor_id(), &mask);
203 cpus_and(mask, cpu_online_map, mask); 213 cpumask_and(&mask, cpu_online_mask, &mask);
204 for (i = 0; i < ncpus; i++) { 214 for (i = 0; i < ncpus; i++) {
205 if (cpu_isset(i, mask)) { 215 if (cpumask_test_cpu(i, &mask)) {
206 ccall_info.processors_in[i] = 0; 216 ccall_info.processors_in[i] = 0;
207 ccall_info.processors_out[i] = 0; 217 ccall_info.processors_out[i] = 0;
208 set_cpu_int(i, IRQ_CROSS_CALL); 218 set_cpu_int(i, IRQ_CROSS_CALL);
@@ -218,7 +228,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
218 228
219 i = 0; 229 i = 0;
220 do { 230 do {
221 if (!cpu_isset(i, mask)) 231 if (!cpumask_test_cpu(i, &mask))
222 continue; 232 continue;
223 while (!ccall_info.processors_in[i]) 233 while (!ccall_info.processors_in[i])
224 barrier(); 234 barrier();
@@ -226,7 +236,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
226 236
227 i = 0; 237 i = 0;
228 do { 238 do {
229 if (!cpu_isset(i, mask)) 239 if (!cpumask_test_cpu(i, &mask))
230 continue; 240 continue;
231 while (!ccall_info.processors_out[i]) 241 while (!ccall_info.processors_out[i])
232 barrier(); 242 barrier();
@@ -277,7 +287,7 @@ static void __cpuinit smp_setup_percpu_timer(void)
277 load_profile_irq(cpu, lvl14_resolution); 287 load_profile_irq(cpu, lvl14_resolution);
278 288
279 if (cpu == boot_cpu_id) 289 if (cpu == boot_cpu_id)
280 enable_pil_irq(14); 290 sun4m_unmask_profile_irq();
281} 291}
282 292
283static void __init smp4m_blackbox_id(unsigned *addr) 293static void __init smp4m_blackbox_id(unsigned *addr)
@@ -306,4 +316,7 @@ void __init sun4m_init_smp(void)
306 BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current); 316 BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current);
307 BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); 317 BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM);
308 BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM); 318 BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM);
319 BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM);
320 BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM);
321 BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM);
309} 322}