diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2012-05-14 09:14:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-14 17:05:07 -0400 |
commit | 4ba22b16bbf354822b7988ec5b4b35774dcd479f (patch) | |
tree | 3476a58b0d8788b89b575f4926e294f4b8bbdd43 | |
parent | c68e5d39a502d01421cbc70d25c377e9215facef (diff) |
sparc32: move smp ipi to method ops
I ended up renaming set_cpu_int to send_ipi to
be consistent all way around.
send_ipi was moved to the *_smp.c files so
we could call the relevant method direct,
without any _ops indirection.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc/include/asm/obio.h | 13 | ||||
-rw-r--r-- | arch/sparc/include/asm/smp_32.h | 45 | ||||
-rw-r--r-- | arch/sparc/kernel/irq.h | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/leon_kernel.c | 19 | ||||
-rw-r--r-- | arch/sparc/kernel/leon_smp.c | 27 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_32.c | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_irq.c | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 34 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4m_irq.c | 14 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4m_smp.c | 36 |
10 files changed, 107 insertions, 105 deletions
diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h index 4ade0c8a2c79..910c1d9af1f8 100644 --- a/arch/sparc/include/asm/obio.h +++ b/arch/sparc/include/asm/obio.h | |||
@@ -220,19 +220,6 @@ static inline void cc_set_igen(unsigned gen) | |||
220 | "i" (ASI_M_MXCC)); | 220 | "i" (ASI_M_MXCC)); |
221 | } | 221 | } |
222 | 222 | ||
223 | /* +-------+-------------+-----------+------------------------------------+ | ||
224 | * | bcast | devid | sid | levels mask | | ||
225 | * +-------+-------------+-----------+------------------------------------+ | ||
226 | * 31 30 23 22 15 14 0 | ||
227 | */ | ||
228 | #define IGEN_MESSAGE(bcast, devid, sid, levels) \ | ||
229 | (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) | ||
230 | |||
231 | static inline void sun4d_send_ipi(int cpu, int level) | ||
232 | { | ||
233 | cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); | ||
234 | } | ||
235 | |||
236 | #endif /* !__ASSEMBLY__ */ | 223 | #endif /* !__ASSEMBLY__ */ |
237 | 224 | ||
238 | #endif /* !(_SPARC_OBIO_H) */ | 225 | #endif /* !(_SPARC_OBIO_H) */ |
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index f5b325e731dd..d596061939d1 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h | |||
@@ -58,24 +58,43 @@ struct seq_file; | |||
58 | void smp_bogo(struct seq_file *); | 58 | void smp_bogo(struct seq_file *); |
59 | void smp_info(struct seq_file *); | 59 | void smp_info(struct seq_file *); |
60 | 60 | ||
61 | BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) | 61 | struct sparc32_ipi_ops { |
62 | BTFIXUPDEF_CALL(void, smp_ipi_resched, int); | 62 | void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1, |
63 | BTFIXUPDEF_CALL(void, smp_ipi_single, int); | 63 | unsigned long arg2, unsigned long arg3, |
64 | BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int); | 64 | unsigned long arg4); |
65 | 65 | void (*resched)(int cpu); | |
66 | #define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4) | 66 | void (*single)(int cpu); |
67 | void (*mask_one)(int cpu); | ||
68 | }; | ||
69 | extern const struct sparc32_ipi_ops *sparc32_ipi_ops; | ||
70 | |||
71 | static inline void xc0(smpfunc_t func) | ||
72 | { | ||
73 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0); | ||
74 | } | ||
67 | 75 | ||
68 | static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); } | ||
69 | static inline void xc1(smpfunc_t func, unsigned long arg1) | 76 | static inline void xc1(smpfunc_t func, unsigned long arg1) |
70 | { smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); } | 77 | { |
78 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); | ||
79 | } | ||
71 | static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) | 80 | static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) |
72 | { smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); } | 81 | { |
82 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); | ||
83 | } | ||
84 | |||
73 | static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, | 85 | static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, |
74 | unsigned long arg3) | 86 | unsigned long arg3) |
75 | { smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); } | 87 | { |
88 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, | ||
89 | arg1, arg2, arg3, 0); | ||
90 | } | ||
91 | |||
76 | static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, | 92 | static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, |
77 | unsigned long arg3, unsigned long arg4) | 93 | unsigned long arg3, unsigned long arg4) |
78 | { smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); } | 94 | { |
95 | sparc32_ipi_ops->cross_call(func, *cpu_online_mask, | ||
96 | arg1, arg2, arg3, arg4); | ||
97 | } | ||
79 | 98 | ||
80 | extern void arch_send_call_function_single_ipi(int cpu); | 99 | extern void arch_send_call_function_single_ipi(int cpu); |
81 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); | 100 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index e2b5d5c9611e..e40ca6c0076a 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h | |||
@@ -10,6 +10,9 @@ struct irq_bucket { | |||
10 | unsigned int pil; | 10 | unsigned int pil; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | #define SUN4M_HARD_INT(x) (0x000000001 << (x)) | ||
14 | #define SUN4M_SOFT_INT(x) (0x000010000 << (x)) | ||
15 | |||
13 | #define SUN4D_MAX_BOARD 10 | 16 | #define SUN4D_MAX_BOARD 10 |
14 | #define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5) | 17 | #define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5) |
15 | 18 | ||
@@ -96,10 +99,9 @@ static inline void load_profile_irq(int cpu, int limit) | |||
96 | BTFIXUP_CALL(load_profile_irq)(cpu, limit); | 99 | BTFIXUP_CALL(load_profile_irq)(cpu, limit); |
97 | } | 100 | } |
98 | 101 | ||
99 | #ifdef CONFIG_SMP | 102 | unsigned long leon_get_irqmask(unsigned int irq); |
100 | BTFIXUPDEF_CALL(void, set_cpu_int, int, int) | ||
101 | 103 | ||
102 | #define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) | 104 | #ifdef CONFIG_SMP |
103 | 105 | ||
104 | /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ | 106 | /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ |
105 | #define SUN4D_IPI_IRQ 13 | 107 | #define SUN4D_IPI_IRQ 13 |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index aeb411cd3927..1770b3c1cc74 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -86,7 +86,7 @@ void leon_eirq_setup(unsigned int eirq) | |||
86 | sparc_leon_eirq = eirq; | 86 | sparc_leon_eirq = eirq; |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline unsigned long get_irqmask(unsigned int irq) | 89 | unsigned long leon_get_irqmask(unsigned int irq) |
90 | { | 90 | { |
91 | unsigned long mask; | 91 | unsigned long mask; |
92 | 92 | ||
@@ -212,7 +212,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq, | |||
212 | unsigned long mask; | 212 | unsigned long mask; |
213 | 213 | ||
214 | irq = 0; | 214 | irq = 0; |
215 | mask = get_irqmask(real_irq); | 215 | mask = leon_get_irqmask(real_irq); |
216 | if (mask == 0) | 216 | if (mask == 0) |
217 | goto out; | 217 | goto out; |
218 | 218 | ||
@@ -497,14 +497,6 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) | |||
497 | } | 497 | } |
498 | 498 | ||
499 | #ifdef CONFIG_SMP | 499 | #ifdef CONFIG_SMP |
500 | |||
501 | void leon_set_cpu_int(int cpu, int level) | ||
502 | { | ||
503 | unsigned long mask; | ||
504 | mask = get_irqmask(level); | ||
505 | LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); | ||
506 | } | ||
507 | |||
508 | void leon_clear_profile_irq(int cpu) | 500 | void leon_clear_profile_irq(int cpu) |
509 | { | 501 | { |
510 | } | 502 | } |
@@ -512,7 +504,7 @@ void leon_clear_profile_irq(int cpu) | |||
512 | void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) | 504 | void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) |
513 | { | 505 | { |
514 | unsigned long mask, flags, *addr; | 506 | unsigned long mask, flags, *addr; |
515 | mask = get_irqmask(irq_nr); | 507 | mask = leon_get_irqmask(irq_nr); |
516 | spin_lock_irqsave(&leon_irq_lock, flags); | 508 | spin_lock_irqsave(&leon_irq_lock, flags); |
517 | addr = (unsigned long *)LEON_IMASK(cpu); | 509 | addr = (unsigned long *)LEON_IMASK(cpu); |
518 | LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask)); | 510 | LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask)); |
@@ -531,11 +523,6 @@ void __init leon_init_IRQ(void) | |||
531 | BTFIXUPCALL_NORM); | 523 | BTFIXUPCALL_NORM); |
532 | BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, | 524 | BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, |
533 | BTFIXUPCALL_NOP); | 525 | BTFIXUPCALL_NOP); |
534 | |||
535 | #ifdef CONFIG_SMP | ||
536 | BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM); | ||
537 | #endif | ||
538 | |||
539 | } | 526 | } |
540 | 527 | ||
541 | void __init leon_init(void) | 528 | void __init leon_init(void) |
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index faff792d53c8..29325bacba6f 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c | |||
@@ -346,6 +346,13 @@ static void __init leon_ipi_init(void) | |||
346 | } | 346 | } |
347 | } | 347 | } |
348 | 348 | ||
349 | static void leon_send_ipi(int cpu, int level) | ||
350 | { | ||
351 | unsigned long mask; | ||
352 | mask = leon_get_irqmask(level); | ||
353 | LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask); | ||
354 | } | ||
355 | |||
349 | static void leon_ipi_single(int cpu) | 356 | static void leon_ipi_single(int cpu) |
350 | { | 357 | { |
351 | struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu); | 358 | struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu); |
@@ -354,7 +361,7 @@ static void leon_ipi_single(int cpu) | |||
354 | work->single = 1; | 361 | work->single = 1; |
355 | 362 | ||
356 | /* Generate IRQ on the CPU */ | 363 | /* Generate IRQ on the CPU */ |
357 | set_cpu_int(cpu, leon_ipi_irq); | 364 | leon_send_ipi(cpu, leon_ipi_irq); |
358 | } | 365 | } |
359 | 366 | ||
360 | static void leon_ipi_mask_one(int cpu) | 367 | static void leon_ipi_mask_one(int cpu) |
@@ -365,7 +372,7 @@ static void leon_ipi_mask_one(int cpu) | |||
365 | work->msk = 1; | 372 | work->msk = 1; |
366 | 373 | ||
367 | /* Generate IRQ on the CPU */ | 374 | /* Generate IRQ on the CPU */ |
368 | set_cpu_int(cpu, leon_ipi_irq); | 375 | leon_send_ipi(cpu, leon_ipi_irq); |
369 | } | 376 | } |
370 | 377 | ||
371 | static void leon_ipi_resched(int cpu) | 378 | static void leon_ipi_resched(int cpu) |
@@ -376,7 +383,7 @@ static void leon_ipi_resched(int cpu) | |||
376 | work->resched = 1; | 383 | work->resched = 1; |
377 | 384 | ||
378 | /* Generate IRQ on the CPU (any IRQ will cause resched) */ | 385 | /* Generate IRQ on the CPU (any IRQ will cause resched) */ |
379 | set_cpu_int(cpu, leon_ipi_irq); | 386 | leon_send_ipi(cpu, leon_ipi_irq); |
380 | } | 387 | } |
381 | 388 | ||
382 | void leonsmp_ipi_interrupt(void) | 389 | void leonsmp_ipi_interrupt(void) |
@@ -448,7 +455,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |||
448 | if (cpumask_test_cpu(i, &mask)) { | 455 | if (cpumask_test_cpu(i, &mask)) { |
449 | ccall_info.processors_in[i] = 0; | 456 | ccall_info.processors_in[i] = 0; |
450 | ccall_info.processors_out[i] = 0; | 457 | ccall_info.processors_out[i] = 0; |
451 | set_cpu_int(i, LEON3_IRQ_CROSS_CALL); | 458 | leon_send_ipi(i, LEON3_IRQ_CROSS_CALL); |
452 | 459 | ||
453 | } | 460 | } |
454 | } | 461 | } |
@@ -491,15 +498,19 @@ void leon_cross_call_irq(void) | |||
491 | ccall_info.processors_out[i] = 1; | 498 | ccall_info.processors_out[i] = 1; |
492 | } | 499 | } |
493 | 500 | ||
501 | static const struct sparc32_ipi_ops leon_ipi_ops = { | ||
502 | .cross_call = leon_cross_call, | ||
503 | .resched = leon_ipi_resched, | ||
504 | .single = leon_ipi_single, | ||
505 | .mask_one = leon_ipi_mask_one, | ||
506 | }; | ||
507 | |||
494 | void __init leon_init_smp(void) | 508 | void __init leon_init_smp(void) |
495 | { | 509 | { |
496 | /* Patch ipi15 trap table */ | 510 | /* Patch ipi15 trap table */ |
497 | t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); | 511 | t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); |
498 | 512 | ||
499 | BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); | 513 | sparc32_ipi_ops = &leon_ipi_ops; |
500 | BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM); | ||
501 | BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM); | ||
502 | BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM); | ||
503 | } | 514 | } |
504 | 515 | ||
505 | #endif /* CONFIG_SPARC_LEON */ | 516 | #endif /* CONFIG_SPARC_LEON */ |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 8cd5c79f6193..57713758079e 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -40,6 +40,8 @@ volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; | |||
40 | 40 | ||
41 | cpumask_t smp_commenced_mask = CPU_MASK_NONE; | 41 | cpumask_t smp_commenced_mask = CPU_MASK_NONE; |
42 | 42 | ||
43 | const struct sparc32_ipi_ops *sparc32_ipi_ops; | ||
44 | |||
43 | /* The only guaranteed locking primitive available on all Sparc | 45 | /* The only guaranteed locking primitive available on all Sparc |
44 | * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically | 46 | * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically |
45 | * places the current byte at the effective address into dest_reg and | 47 | * places the current byte at the effective address into dest_reg and |
@@ -124,7 +126,7 @@ void smp_send_reschedule(int cpu) | |||
124 | * a single CPU. The trap handler needs only to do trap entry/return | 126 | * a single CPU. The trap handler needs only to do trap entry/return |
125 | * to call schedule. | 127 | * to call schedule. |
126 | */ | 128 | */ |
127 | BTFIXUP_CALL(smp_ipi_resched)(cpu); | 129 | sparc32_ipi_ops->resched(cpu); |
128 | } | 130 | } |
129 | 131 | ||
130 | void smp_send_stop(void) | 132 | void smp_send_stop(void) |
@@ -134,7 +136,7 @@ void smp_send_stop(void) | |||
134 | void arch_send_call_function_single_ipi(int cpu) | 136 | void arch_send_call_function_single_ipi(int cpu) |
135 | { | 137 | { |
136 | /* trigger one IPI single call on one CPU */ | 138 | /* trigger one IPI single call on one CPU */ |
137 | BTFIXUP_CALL(smp_ipi_single)(cpu); | 139 | sparc32_ipi_ops->single(cpu); |
138 | } | 140 | } |
139 | 141 | ||
140 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) | 142 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
@@ -143,7 +145,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) | |||
143 | 145 | ||
144 | /* trigger IPI mask call on each CPU */ | 146 | /* trigger IPI mask call on each CPU */ |
145 | for_each_cpu(cpu, mask) | 147 | for_each_cpu(cpu, mask) |
146 | BTFIXUP_CALL(smp_ipi_mask_one)(cpu); | 148 | sparc32_ipi_ops->mask_one(cpu); |
147 | } | 149 | } |
148 | 150 | ||
149 | void smp_resched_interrupt(void) | 151 | void smp_resched_interrupt(void) |
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index b2fdb3d78c19..e8e4f1411585 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c | |||
@@ -244,11 +244,6 @@ struct irq_chip sun4d_irq = { | |||
244 | }; | 244 | }; |
245 | 245 | ||
246 | #ifdef CONFIG_SMP | 246 | #ifdef CONFIG_SMP |
247 | static void sun4d_set_cpu_int(int cpu, int level) | ||
248 | { | ||
249 | sun4d_send_ipi(cpu, level); | ||
250 | } | ||
251 | |||
252 | /* Setup IRQ distribution scheme. */ | 247 | /* Setup IRQ distribution scheme. */ |
253 | void __init sun4d_distribute_irqs(void) | 248 | void __init sun4d_distribute_irqs(void) |
254 | { | 249 | { |
@@ -518,8 +513,5 @@ void __init sun4d_init_IRQ(void) | |||
518 | sparc_config.build_device_irq = sun4d_build_device_irq; | 513 | sparc_config.build_device_irq = sun4d_build_device_irq; |
519 | sparc_config.clock_rate = SBUS_CLOCK_RATE; | 514 | sparc_config.clock_rate = SBUS_CLOCK_RATE; |
520 | 515 | ||
521 | #ifdef CONFIG_SMP | ||
522 | BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); | ||
523 | #endif | ||
524 | /* Cannot enable interrupts until OBP ticker is disabled. */ | 516 | /* Cannot enable interrupts until OBP ticker is disabled. */ |
525 | } | 517 | } |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 38ca0aac2ef2..f9a1a33cbb2c 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -235,7 +235,20 @@ void sun4d_ipi_interrupt(void) | |||
235 | } | 235 | } |
236 | } | 236 | } |
237 | 237 | ||
238 | static void smp4d_ipi_single(int cpu) | 238 | /* +-------+-------------+-----------+------------------------------------+ |
239 | * | bcast | devid | sid | levels mask | | ||
240 | * +-------+-------------+-----------+------------------------------------+ | ||
241 | * 31 30 23 22 15 14 0 | ||
242 | */ | ||
243 | #define IGEN_MESSAGE(bcast, devid, sid, levels) \ | ||
244 | (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) | ||
245 | |||
246 | static void sun4d_send_ipi(int cpu, int level) | ||
247 | { | ||
248 | cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); | ||
249 | } | ||
250 | |||
251 | static void sun4d_ipi_single(int cpu) | ||
239 | { | 252 | { |
240 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); | 253 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); |
241 | 254 | ||
@@ -246,7 +259,7 @@ static void smp4d_ipi_single(int cpu) | |||
246 | sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); | 259 | sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); |
247 | } | 260 | } |
248 | 261 | ||
249 | static void smp4d_ipi_mask_one(int cpu) | 262 | static void sun4d_ipi_mask_one(int cpu) |
250 | { | 263 | { |
251 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); | 264 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); |
252 | 265 | ||
@@ -257,7 +270,7 @@ static void smp4d_ipi_mask_one(int cpu) | |||
257 | sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); | 270 | sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); |
258 | } | 271 | } |
259 | 272 | ||
260 | static void smp4d_ipi_resched(int cpu) | 273 | static void sun4d_ipi_resched(int cpu) |
261 | { | 274 | { |
262 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); | 275 | struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); |
263 | 276 | ||
@@ -282,7 +295,7 @@ static struct smp_funcall { | |||
282 | static DEFINE_SPINLOCK(cross_call_lock); | 295 | static DEFINE_SPINLOCK(cross_call_lock); |
283 | 296 | ||
284 | /* Cross calls must be serialized, at least currently. */ | 297 | /* Cross calls must be serialized, at least currently. */ |
285 | static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | 298 | static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, |
286 | unsigned long arg2, unsigned long arg3, | 299 | unsigned long arg2, unsigned long arg3, |
287 | unsigned long arg4) | 300 | unsigned long arg4) |
288 | { | 301 | { |
@@ -391,6 +404,13 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) | |||
391 | set_irq_regs(old_regs); | 404 | set_irq_regs(old_regs); |
392 | } | 405 | } |
393 | 406 | ||
407 | static const struct sparc32_ipi_ops sun4d_ipi_ops = { | ||
408 | .cross_call = sun4d_cross_call, | ||
409 | .resched = sun4d_ipi_resched, | ||
410 | .single = sun4d_ipi_single, | ||
411 | .mask_one = sun4d_ipi_mask_one, | ||
412 | }; | ||
413 | |||
394 | void __init sun4d_init_smp(void) | 414 | void __init sun4d_init_smp(void) |
395 | { | 415 | { |
396 | int i; | 416 | int i; |
@@ -398,11 +418,7 @@ void __init sun4d_init_smp(void) | |||
398 | /* Patch ipi15 trap table */ | 418 | /* Patch ipi15 trap table */ |
399 | t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); | 419 | t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); |
400 | 420 | ||
401 | /* And set btfixup... */ | 421 | sparc32_ipi_ops = &sun4d_ipi_ops; |
402 | BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM); | ||
403 | BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM); | ||
404 | BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM); | ||
405 | BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM); | ||
406 | 422 | ||
407 | for (i = 0; i < NR_CPUS; i++) { | 423 | for (i = 0; i < NR_CPUS; i++) { |
408 | ccall_info.processors_in[i] = 1; | 424 | ccall_info.processors_in[i] = 1; |
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 32d3a5ce50f3..eb2c277aaf94 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c | |||
@@ -112,9 +112,6 @@ struct sun4m_handler_data { | |||
112 | #define SUN4M_INT_E14 0x00000080 | 112 | #define SUN4M_INT_E14 0x00000080 |
113 | #define SUN4M_INT_E10 0x00080000 | 113 | #define SUN4M_INT_E10 0x00080000 |
114 | 114 | ||
115 | #define SUN4M_HARD_INT(x) (0x000000001 << (x)) | ||
116 | #define SUN4M_SOFT_INT(x) (0x000010000 << (x)) | ||
117 | |||
118 | #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ | 115 | #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ |
119 | #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ | 116 | #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ |
120 | #define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ | 117 | #define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ |
@@ -282,13 +279,6 @@ out: | |||
282 | return irq; | 279 | return irq; |
283 | } | 280 | } |
284 | 281 | ||
285 | #ifdef CONFIG_SMP | ||
286 | static void sun4m_send_ipi(int cpu, int level) | ||
287 | { | ||
288 | sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); | ||
289 | } | ||
290 | #endif | ||
291 | |||
292 | struct sun4m_timer_percpu { | 282 | struct sun4m_timer_percpu { |
293 | u32 l14_limit; | 283 | u32 l14_limit; |
294 | u32 l14_count; | 284 | u32 l14_count; |
@@ -479,9 +469,5 @@ void __init sun4m_init_IRQ(void) | |||
479 | sparc_config.build_device_irq = sun4m_build_device_irq; | 469 | sparc_config.build_device_irq = sun4m_build_device_irq; |
480 | sparc_config.clock_rate = SBUS_CLOCK_RATE; | 470 | sparc_config.clock_rate = SBUS_CLOCK_RATE; |
481 | 471 | ||
482 | #ifdef CONFIG_SMP | ||
483 | BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM); | ||
484 | #endif | ||
485 | |||
486 | /* Cannot enable interrupts until OBP ticker is disabled. */ | 472 | /* Cannot enable interrupts until OBP ticker is disabled. */ |
487 | } | 473 | } |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index ff74d33e2709..ee21c4375a90 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -34,8 +34,6 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) | |||
34 | return val; | 34 | return val; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void smp4m_ipi_init(void); | ||
38 | |||
39 | void __cpuinit smp4m_callin(void) | 37 | void __cpuinit smp4m_callin(void) |
40 | { | 38 | { |
41 | int cpuid = hard_smp_processor_id(); | 39 | int cpuid = hard_smp_processor_id(); |
@@ -88,7 +86,6 @@ void __cpuinit smp4m_callin(void) | |||
88 | */ | 86 | */ |
89 | void __init smp4m_boot_cpus(void) | 87 | void __init smp4m_boot_cpus(void) |
90 | { | 88 | { |
91 | smp4m_ipi_init(); | ||
92 | sun4m_unmask_profile_irq(); | 89 | sun4m_unmask_profile_irq(); |
93 | local_ops->cache_all(); | 90 | local_ops->cache_all(); |
94 | } | 91 | } |
@@ -156,25 +153,24 @@ void __init smp4m_smp_done(void) | |||
156 | /* Ok, they are spinning and ready to go. */ | 153 | /* Ok, they are spinning and ready to go. */ |
157 | } | 154 | } |
158 | 155 | ||
159 | 156 | static void sun4m_send_ipi(int cpu, int level) | |
160 | /* Initialize IPIs on the SUN4M SMP machine */ | ||
161 | static void __init smp4m_ipi_init(void) | ||
162 | { | 157 | { |
158 | sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set); | ||
163 | } | 159 | } |
164 | 160 | ||
165 | static void smp4m_ipi_resched(int cpu) | 161 | static void sun4m_ipi_resched(int cpu) |
166 | { | 162 | { |
167 | set_cpu_int(cpu, IRQ_IPI_RESCHED); | 163 | sun4m_send_ipi(cpu, IRQ_IPI_RESCHED); |
168 | } | 164 | } |
169 | 165 | ||
170 | static void smp4m_ipi_single(int cpu) | 166 | static void sun4m_ipi_single(int cpu) |
171 | { | 167 | { |
172 | set_cpu_int(cpu, IRQ_IPI_SINGLE); | 168 | sun4m_send_ipi(cpu, IRQ_IPI_SINGLE); |
173 | } | 169 | } |
174 | 170 | ||
175 | static void smp4m_ipi_mask_one(int cpu) | 171 | static void sun4m_ipi_mask_one(int cpu) |
176 | { | 172 | { |
177 | set_cpu_int(cpu, IRQ_IPI_MASK); | 173 | sun4m_send_ipi(cpu, IRQ_IPI_MASK); |
178 | } | 174 | } |
179 | 175 | ||
180 | static struct smp_funcall { | 176 | static struct smp_funcall { |
@@ -191,7 +187,7 @@ static struct smp_funcall { | |||
191 | static DEFINE_SPINLOCK(cross_call_lock); | 187 | static DEFINE_SPINLOCK(cross_call_lock); |
192 | 188 | ||
193 | /* Cross calls must be serialized, at least currently. */ | 189 | /* Cross calls must be serialized, at least currently. */ |
194 | static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | 190 | static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, |
195 | unsigned long arg2, unsigned long arg3, | 191 | unsigned long arg2, unsigned long arg3, |
196 | unsigned long arg4) | 192 | unsigned long arg4) |
197 | { | 193 | { |
@@ -218,7 +214,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, | |||
218 | if (cpumask_test_cpu(i, &mask)) { | 214 | if (cpumask_test_cpu(i, &mask)) { |
219 | ccall_info.processors_in[i] = 0; | 215 | ccall_info.processors_in[i] = 0; |
220 | ccall_info.processors_out[i] = 0; | 216 | ccall_info.processors_out[i] = 0; |
221 | set_cpu_int(i, IRQ_CROSS_CALL); | 217 | sun4m_send_ipi(i, IRQ_CROSS_CALL); |
222 | } else { | 218 | } else { |
223 | ccall_info.processors_in[i] = 1; | 219 | ccall_info.processors_in[i] = 1; |
224 | ccall_info.processors_out[i] = 1; | 220 | ccall_info.processors_out[i] = 1; |
@@ -281,10 +277,14 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) | |||
281 | set_irq_regs(old_regs); | 277 | set_irq_regs(old_regs); |
282 | } | 278 | } |
283 | 279 | ||
280 | static const struct sparc32_ipi_ops sun4m_ipi_ops = { | ||
281 | .cross_call = sun4m_cross_call, | ||
282 | .resched = sun4m_ipi_resched, | ||
283 | .single = sun4m_ipi_single, | ||
284 | .mask_one = sun4m_ipi_mask_one, | ||
285 | }; | ||
286 | |||
284 | void __init sun4m_init_smp(void) | 287 | void __init sun4m_init_smp(void) |
285 | { | 288 | { |
286 | BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); | 289 | sparc32_ipi_ops = &sun4m_ipi_ops; |
287 | BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM); | ||
288 | BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM); | ||
289 | BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM); | ||
290 | } | 290 | } |