diff options
Diffstat (limited to 'arch/sparc/kernel/sun4m_smp.c')
-rw-r--r-- | arch/sparc/kernel/sun4m_smp.c | 51 |
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 | ||
20 | static inline unsigned long | 23 | static 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 | ||
32 | static void smp4m_ipi_init(void); | ||
29 | static void smp_setup_percpu_timer(void); | 33 | static void smp_setup_percpu_timer(void); |
30 | 34 | ||
31 | void __cpuinit smp4m_callin(void) | 35 | void __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" (¤t_set[cpuid]) | 68 | : : "r" (¤t_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 | */ |
84 | void __init smp4m_boot_cpus(void) | 86 | void __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. | 158 | static void __init smp4m_ipi_init(void) |
156 | * | 159 | { |
157 | * XXX See sparc64 irq.c. | 160 | } |
158 | */ | 161 | |
159 | void smp4m_irq_rotate(int cpu) | 162 | static void smp4m_ipi_resched(int cpu) |
163 | { | ||
164 | set_cpu_int(cpu, IRQ_IPI_RESCHED); | ||
165 | } | ||
166 | |||
167 | static 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) | 172 | static 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 | ||
167 | static struct smp_funcall { | 177 | static 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 | ||
283 | static void __init smp4m_blackbox_id(unsigned *addr) | 293 | static 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 | } |