aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2012-05-14 09:14:36 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-14 17:05:07 -0400
commit4ba22b16bbf354822b7988ec5b4b35774dcd479f (patch)
tree3476a58b0d8788b89b575f4926e294f4b8bbdd43
parentc68e5d39a502d01421cbc70d25c377e9215facef (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.h13
-rw-r--r--arch/sparc/include/asm/smp_32.h45
-rw-r--r--arch/sparc/kernel/irq.h8
-rw-r--r--arch/sparc/kernel/leon_kernel.c19
-rw-r--r--arch/sparc/kernel/leon_smp.c27
-rw-r--r--arch/sparc/kernel/smp_32.c8
-rw-r--r--arch/sparc/kernel/sun4d_irq.c8
-rw-r--r--arch/sparc/kernel/sun4d_smp.c34
-rw-r--r--arch/sparc/kernel/sun4m_irq.c14
-rw-r--r--arch/sparc/kernel/sun4m_smp.c36
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
231static 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;
58void smp_bogo(struct seq_file *); 58void smp_bogo(struct seq_file *);
59void smp_info(struct seq_file *); 59void smp_info(struct seq_file *);
60 60
61BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) 61struct sparc32_ipi_ops {
62BTFIXUPDEF_CALL(void, smp_ipi_resched, int); 62 void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1,
63BTFIXUPDEF_CALL(void, smp_ipi_single, int); 63 unsigned long arg2, unsigned long arg3,
64BTFIXUPDEF_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};
69extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
70
71static inline void xc0(smpfunc_t func)
72{
73 sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
74}
67 75
68static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); }
69static inline void xc1(smpfunc_t func, unsigned long arg1) 76static 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}
71static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) 80static 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
73static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, 85static 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
76static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, 92static 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
80extern void arch_send_call_function_single_ipi(int cpu); 99extern void arch_send_call_function_single_ipi(int cpu);
81extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 100extern 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 102unsigned long leon_get_irqmask(unsigned int irq);
100BTFIXUPDEF_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
89static inline unsigned long get_irqmask(unsigned int irq) 89unsigned 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
501void 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
508void leon_clear_profile_irq(int cpu) 500void leon_clear_profile_irq(int cpu)
509{ 501{
510} 502}
@@ -512,7 +504,7 @@ void leon_clear_profile_irq(int cpu)
512void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) 504void 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
541void __init leon_init(void) 528void __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
349static 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
349static void leon_ipi_single(int cpu) 356static 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
360static void leon_ipi_mask_one(int cpu) 367static 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
371static void leon_ipi_resched(int cpu) 378static 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
382void leonsmp_ipi_interrupt(void) 389void 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
501static 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
494void __init leon_init_smp(void) 508void __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
41cpumask_t smp_commenced_mask = CPU_MASK_NONE; 41cpumask_t smp_commenced_mask = CPU_MASK_NONE;
42 42
43const 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
130void smp_send_stop(void) 132void smp_send_stop(void)
@@ -134,7 +136,7 @@ void smp_send_stop(void)
134void arch_send_call_function_single_ipi(int cpu) 136void 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
140void arch_send_call_function_ipi_mask(const struct cpumask *mask) 142void 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
149void smp_resched_interrupt(void) 151void 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
247static 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. */
253void __init sun4d_distribute_irqs(void) 248void __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
238static 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
246static 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
251static 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
249static void smp4d_ipi_mask_one(int cpu) 262static 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
260static void smp4d_ipi_resched(int cpu) 273static 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 {
282static DEFINE_SPINLOCK(cross_call_lock); 295static 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. */
285static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, 298static 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
407static 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
394void __init sun4d_init_smp(void) 414void __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
286static 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
292struct sun4m_timer_percpu { 282struct 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
37static void smp4m_ipi_init(void);
38
39void __cpuinit smp4m_callin(void) 37void __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 */
89void __init smp4m_boot_cpus(void) 87void __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 156static void sun4m_send_ipi(int cpu, int level)
160/* Initialize IPIs on the SUN4M SMP machine */
161static void __init smp4m_ipi_init(void)
162{ 157{
158 sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
163} 159}
164 160
165static void smp4m_ipi_resched(int cpu) 161static 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
170static void smp4m_ipi_single(int cpu) 166static 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
175static void smp4m_ipi_mask_one(int cpu) 171static 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
180static struct smp_funcall { 176static struct smp_funcall {
@@ -191,7 +187,7 @@ static struct smp_funcall {
191static DEFINE_SPINLOCK(cross_call_lock); 187static 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. */
194static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, 190static 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
280static 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
284void __init sun4m_init_smp(void) 287void __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}