Commit 4ba22b16 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by David S. Miller

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: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c68e5d39
...@@ -220,19 +220,6 @@ static inline void cc_set_igen(unsigned gen) ...@@ -220,19 +220,6 @@ static inline void cc_set_igen(unsigned gen)
"i" (ASI_M_MXCC)); "i" (ASI_M_MXCC));
} }
/* +-------+-------------+-----------+------------------------------------+
* | bcast | devid | sid | levels mask |
* +-------+-------------+-----------+------------------------------------+
* 31 30 23 22 15 14 0
*/
#define IGEN_MESSAGE(bcast, devid, sid, levels) \
(((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
static inline void sun4d_send_ipi(int cpu, int level)
{
cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
}
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* !(_SPARC_OBIO_H) */ #endif /* !(_SPARC_OBIO_H) */
...@@ -58,24 +58,43 @@ struct seq_file; ...@@ -58,24 +58,43 @@ struct seq_file;
void smp_bogo(struct seq_file *); void smp_bogo(struct seq_file *);
void smp_info(struct seq_file *); void smp_info(struct seq_file *);
BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) struct sparc32_ipi_ops {
BTFIXUPDEF_CALL(void, smp_ipi_resched, int); void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1,
BTFIXUPDEF_CALL(void, smp_ipi_single, int); unsigned long arg2, unsigned long arg3,
BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int); unsigned long arg4);
void (*resched)(int cpu);
#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4) void (*single)(int cpu);
void (*mask_one)(int cpu);
};
extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
static inline void xc0(smpfunc_t func)
{
sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
}
static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); }
static inline void xc1(smpfunc_t func, unsigned long arg1) static inline void xc1(smpfunc_t func, unsigned long arg1)
{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); } {
sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0);
}
static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); } {
sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0);
}
static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3) unsigned long arg3)
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); } {
sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
arg1, arg2, arg3, 0);
}
static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4) unsigned long arg3, unsigned long arg4)
{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); } {
sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
arg1, arg2, arg3, arg4);
}
extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
......
...@@ -10,6 +10,9 @@ struct irq_bucket { ...@@ -10,6 +10,9 @@ struct irq_bucket {
unsigned int pil; unsigned int pil;
}; };
#define SUN4M_HARD_INT(x) (0x000000001 << (x))
#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
#define SUN4D_MAX_BOARD 10 #define SUN4D_MAX_BOARD 10
#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5) #define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
...@@ -96,10 +99,9 @@ static inline void load_profile_irq(int cpu, int limit) ...@@ -96,10 +99,9 @@ static inline void load_profile_irq(int cpu, int limit)
BTFIXUP_CALL(load_profile_irq)(cpu, limit); BTFIXUP_CALL(load_profile_irq)(cpu, limit);
} }
#ifdef CONFIG_SMP unsigned long leon_get_irqmask(unsigned int irq);
BTFIXUPDEF_CALL(void, set_cpu_int, int, int)
#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) #ifdef CONFIG_SMP
/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
#define SUN4D_IPI_IRQ 13 #define SUN4D_IPI_IRQ 13
......
...@@ -86,7 +86,7 @@ void leon_eirq_setup(unsigned int eirq) ...@@ -86,7 +86,7 @@ void leon_eirq_setup(unsigned int eirq)
sparc_leon_eirq = eirq; sparc_leon_eirq = eirq;
} }
static inline unsigned long get_irqmask(unsigned int irq) unsigned long leon_get_irqmask(unsigned int irq)
{ {
unsigned long mask; unsigned long mask;
...@@ -212,7 +212,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq, ...@@ -212,7 +212,7 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
unsigned long mask; unsigned long mask;
irq = 0; irq = 0;
mask = get_irqmask(real_irq); mask = leon_get_irqmask(real_irq);
if (mask == 0) if (mask == 0)
goto out; goto out;
...@@ -497,14 +497,6 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) ...@@ -497,14 +497,6 @@ void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void leon_set_cpu_int(int cpu, int level)
{
unsigned long mask;
mask = get_irqmask(level);
LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask);
}
void leon_clear_profile_irq(int cpu) void leon_clear_profile_irq(int cpu)
{ {
} }
...@@ -512,7 +504,7 @@ void leon_clear_profile_irq(int cpu) ...@@ -512,7 +504,7 @@ void leon_clear_profile_irq(int cpu)
void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)
{ {
unsigned long mask, flags, *addr; unsigned long mask, flags, *addr;
mask = get_irqmask(irq_nr); mask = leon_get_irqmask(irq_nr);
spin_lock_irqsave(&leon_irq_lock, flags); spin_lock_irqsave(&leon_irq_lock, flags);
addr = (unsigned long *)LEON_IMASK(cpu); addr = (unsigned long *)LEON_IMASK(cpu);
LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask)); LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask));
...@@ -531,11 +523,6 @@ void __init leon_init_IRQ(void) ...@@ -531,11 +523,6 @@ void __init leon_init_IRQ(void)
BTFIXUPCALL_NORM); BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq,
BTFIXUPCALL_NOP); BTFIXUPCALL_NOP);
#ifdef CONFIG_SMP
BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM);
#endif
} }
void __init leon_init(void) void __init leon_init(void)
......
...@@ -346,6 +346,13 @@ static void __init leon_ipi_init(void) ...@@ -346,6 +346,13 @@ static void __init leon_ipi_init(void)
} }
} }
static void leon_send_ipi(int cpu, int level)
{
unsigned long mask;
mask = leon_get_irqmask(level);
LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->force[cpu], mask);
}
static void leon_ipi_single(int cpu) static void leon_ipi_single(int cpu)
{ {
struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu); struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu);
...@@ -354,7 +361,7 @@ static void leon_ipi_single(int cpu) ...@@ -354,7 +361,7 @@ static void leon_ipi_single(int cpu)
work->single = 1; work->single = 1;
/* Generate IRQ on the CPU */ /* Generate IRQ on the CPU */
set_cpu_int(cpu, leon_ipi_irq); leon_send_ipi(cpu, leon_ipi_irq);
} }
static void leon_ipi_mask_one(int cpu) static void leon_ipi_mask_one(int cpu)
...@@ -365,7 +372,7 @@ static void leon_ipi_mask_one(int cpu) ...@@ -365,7 +372,7 @@ static void leon_ipi_mask_one(int cpu)
work->msk = 1; work->msk = 1;
/* Generate IRQ on the CPU */ /* Generate IRQ on the CPU */
set_cpu_int(cpu, leon_ipi_irq); leon_send_ipi(cpu, leon_ipi_irq);
} }
static void leon_ipi_resched(int cpu) static void leon_ipi_resched(int cpu)
...@@ -376,7 +383,7 @@ static void leon_ipi_resched(int cpu) ...@@ -376,7 +383,7 @@ static void leon_ipi_resched(int cpu)
work->resched = 1; work->resched = 1;
/* Generate IRQ on the CPU (any IRQ will cause resched) */ /* Generate IRQ on the CPU (any IRQ will cause resched) */
set_cpu_int(cpu, leon_ipi_irq); leon_send_ipi(cpu, leon_ipi_irq);
} }
void leonsmp_ipi_interrupt(void) void leonsmp_ipi_interrupt(void)
...@@ -448,7 +455,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, ...@@ -448,7 +455,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
if (cpumask_test_cpu(i, &mask)) { if (cpumask_test_cpu(i, &mask)) {
ccall_info.processors_in[i] = 0; ccall_info.processors_in[i] = 0;
ccall_info.processors_out[i] = 0; ccall_info.processors_out[i] = 0;
set_cpu_int(i, LEON3_IRQ_CROSS_CALL); leon_send_ipi(i, LEON3_IRQ_CROSS_CALL);
} }
} }
...@@ -491,15 +498,19 @@ void leon_cross_call_irq(void) ...@@ -491,15 +498,19 @@ void leon_cross_call_irq(void)
ccall_info.processors_out[i] = 1; ccall_info.processors_out[i] = 1;
} }
static const struct sparc32_ipi_ops leon_ipi_ops = {
.cross_call = leon_cross_call,
.resched = leon_ipi_resched,
.single = leon_ipi_single,
.mask_one = leon_ipi_mask_one,
};
void __init leon_init_smp(void) void __init leon_init_smp(void)
{ {
/* Patch ipi15 trap table */ /* Patch ipi15 trap table */
t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m); t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m);
BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); sparc32_ipi_ops = &leon_ipi_ops;
BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM);
} }
#endif /* CONFIG_SPARC_LEON */ #endif /* CONFIG_SPARC_LEON */
...@@ -40,6 +40,8 @@ volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; ...@@ -40,6 +40,8 @@ volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
cpumask_t smp_commenced_mask = CPU_MASK_NONE; cpumask_t smp_commenced_mask = CPU_MASK_NONE;
const struct sparc32_ipi_ops *sparc32_ipi_ops;
/* The only guaranteed locking primitive available on all Sparc /* The only guaranteed locking primitive available on all Sparc
* processors is 'ldstub [%reg + immediate], %dest_reg' which atomically * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically
* places the current byte at the effective address into dest_reg and * places the current byte at the effective address into dest_reg and
...@@ -124,7 +126,7 @@ void smp_send_reschedule(int cpu) ...@@ -124,7 +126,7 @@ void smp_send_reschedule(int cpu)
* a single CPU. The trap handler needs only to do trap entry/return * a single CPU. The trap handler needs only to do trap entry/return
* to call schedule. * to call schedule.
*/ */
BTFIXUP_CALL(smp_ipi_resched)(cpu); sparc32_ipi_ops->resched(cpu);
} }
void smp_send_stop(void) void smp_send_stop(void)
...@@ -134,7 +136,7 @@ void smp_send_stop(void) ...@@ -134,7 +136,7 @@ void smp_send_stop(void)
void arch_send_call_function_single_ipi(int cpu) void arch_send_call_function_single_ipi(int cpu)
{ {
/* trigger one IPI single call on one CPU */ /* trigger one IPI single call on one CPU */
BTFIXUP_CALL(smp_ipi_single)(cpu); sparc32_ipi_ops->single(cpu);
} }
void arch_send_call_function_ipi_mask(const struct cpumask *mask) 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,7 +145,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
/* trigger IPI mask call on each CPU */ /* trigger IPI mask call on each CPU */
for_each_cpu(cpu, mask) for_each_cpu(cpu, mask)
BTFIXUP_CALL(smp_ipi_mask_one)(cpu); sparc32_ipi_ops->mask_one(cpu);
} }
void smp_resched_interrupt(void) void smp_resched_interrupt(void)
......
...@@ -244,11 +244,6 @@ struct irq_chip sun4d_irq = { ...@@ -244,11 +244,6 @@ struct irq_chip sun4d_irq = {
}; };
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void sun4d_set_cpu_int(int cpu, int level)
{
sun4d_send_ipi(cpu, level);
}
/* Setup IRQ distribution scheme. */ /* Setup IRQ distribution scheme. */
void __init sun4d_distribute_irqs(void) void __init sun4d_distribute_irqs(void)
{ {
...@@ -518,8 +513,5 @@ void __init sun4d_init_IRQ(void) ...@@ -518,8 +513,5 @@ void __init sun4d_init_IRQ(void)
sparc_config.build_device_irq = sun4d_build_device_irq; sparc_config.build_device_irq = sun4d_build_device_irq;
sparc_config.clock_rate = SBUS_CLOCK_RATE; sparc_config.clock_rate = SBUS_CLOCK_RATE;
#ifdef CONFIG_SMP
BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM);
#endif
/* Cannot enable interrupts until OBP ticker is disabled. */ /* Cannot enable interrupts until OBP ticker is disabled. */
} }
...@@ -235,7 +235,20 @@ void sun4d_ipi_interrupt(void) ...@@ -235,7 +235,20 @@ void sun4d_ipi_interrupt(void)
} }
} }
static void smp4d_ipi_single(int cpu) /* +-------+-------------+-----------+------------------------------------+
* | bcast | devid | sid | levels mask |
* +-------+-------------+-----------+------------------------------------+
* 31 30 23 22 15 14 0
*/
#define IGEN_MESSAGE(bcast, devid, sid, levels) \
(((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
static void sun4d_send_ipi(int cpu, int level)
{
cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
}
static void sun4d_ipi_single(int cpu)
{ {
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
...@@ -246,7 +259,7 @@ static void smp4d_ipi_single(int cpu) ...@@ -246,7 +259,7 @@ static void smp4d_ipi_single(int cpu)
sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
} }
static void smp4d_ipi_mask_one(int cpu) static void sun4d_ipi_mask_one(int cpu)
{ {
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
...@@ -257,7 +270,7 @@ static void smp4d_ipi_mask_one(int cpu) ...@@ -257,7 +270,7 @@ static void smp4d_ipi_mask_one(int cpu)
sun4d_send_ipi(cpu, SUN4D_IPI_IRQ); sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
} }
static void smp4d_ipi_resched(int cpu) static void sun4d_ipi_resched(int cpu)
{ {
struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu); struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
...@@ -282,7 +295,7 @@ static struct smp_funcall { ...@@ -282,7 +295,7 @@ static struct smp_funcall {
static DEFINE_SPINLOCK(cross_call_lock); static DEFINE_SPINLOCK(cross_call_lock);
/* Cross calls must be serialized, at least currently. */ /* Cross calls must be serialized, at least currently. */
static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
unsigned long arg2, unsigned long arg3, unsigned long arg2, unsigned long arg3,
unsigned long arg4) unsigned long arg4)
{ {
...@@ -391,6 +404,13 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) ...@@ -391,6 +404,13 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
set_irq_regs(old_regs); set_irq_regs(old_regs);
} }
static const struct sparc32_ipi_ops sun4d_ipi_ops = {
.cross_call = sun4d_cross_call,
.resched = sun4d_ipi_resched,
.single = sun4d_ipi_single,
.mask_one = sun4d_ipi_mask_one,
};
void __init sun4d_init_smp(void) void __init sun4d_init_smp(void)
{ {
int i; int i;
...@@ -398,11 +418,7 @@ void __init sun4d_init_smp(void) ...@@ -398,11 +418,7 @@ void __init sun4d_init_smp(void)
/* Patch ipi15 trap table */ /* Patch ipi15 trap table */
t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m);
/* And set btfixup... */ sparc32_ipi_ops = &sun4d_ipi_ops;
BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM);
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
ccall_info.processors_in[i] = 1; ccall_info.processors_in[i] = 1;
......
...@@ -112,9 +112,6 @@ struct sun4m_handler_data { ...@@ -112,9 +112,6 @@ struct sun4m_handler_data {
#define SUN4M_INT_E14 0x00000080 #define SUN4M_INT_E14 0x00000080
#define SUN4M_INT_E10 0x00080000 #define SUN4M_INT_E10 0x00080000
#define SUN4M_HARD_INT(x) (0x000000001 << (x))
#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
#define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */ #define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */
...@@ -282,13 +279,6 @@ static unsigned int sun4m_build_device_irq(struct platform_device *op, ...@@ -282,13 +279,6 @@ static unsigned int sun4m_build_device_irq(struct platform_device *op,
return irq; return irq;
} }
#ifdef CONFIG_SMP
static void sun4m_send_ipi(int cpu, int level)
{
sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
}
#endif
struct sun4m_timer_percpu { struct sun4m_timer_percpu {
u32 l14_limit; u32 l14_limit;
u32 l14_count; u32 l14_count;
...@@ -479,9 +469,5 @@ void __init sun4m_init_IRQ(void) ...@@ -479,9 +469,5 @@ void __init sun4m_init_IRQ(void)
sparc_config.build_device_irq = sun4m_build_device_irq; sparc_config.build_device_irq = sun4m_build_device_irq;
sparc_config.clock_rate = SBUS_CLOCK_RATE; sparc_config.clock_rate = SBUS_CLOCK_RATE;
#ifdef CONFIG_SMP
BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
#endif
/* Cannot enable interrupts until OBP ticker is disabled. */ /* Cannot enable interrupts until OBP ticker is disabled. */
} }
...@@ -34,8 +34,6 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) ...@@ -34,8 +34,6 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val)
return val; return val;
} }
static void smp4m_ipi_init(void);
void __cpuinit smp4m_callin(void) void __cpuinit smp4m_callin(void)
{ {
int cpuid = hard_smp_processor_id(); int cpuid = hard_smp_processor_id();
...@@ -88,7 +86,6 @@ void __cpuinit smp4m_callin(void) ...@@ -88,7 +86,6 @@ void __cpuinit smp4m_callin(void)
*/ */
void __init smp4m_boot_cpus(void) void __init smp4m_boot_cpus(void)
{ {
smp4m_ipi_init();
sun4m_unmask_profile_irq(); sun4m_unmask_profile_irq();
local_ops->cache_all(); local_ops->cache_all();
} }
...@@ -156,25 +153,24 @@ void __init smp4m_smp_done(void) ...@@ -156,25 +153,24 @@ void __init smp4m_smp_done(void)
/* Ok, they are spinning and ready to go. */ /* Ok, they are spinning and ready to go. */
} }
static void sun4m_send_ipi(int cpu, int level)
/* Initialize IPIs on the SUN4M SMP machine */
static void __init smp4m_ipi_init(void)
{ {
sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
} }
static void smp4m_ipi_resched(int cpu) static void sun4m_ipi_resched(int cpu)
{ {
set_cpu_int(cpu, IRQ_IPI_RESCHED); sun4m_send_ipi(cpu, IRQ_IPI_RESCHED);
} }
static void smp4m_ipi_single(int cpu) static void sun4m_ipi_single(int cpu)
{ {
set_cpu_int(cpu, IRQ_IPI_SINGLE); sun4m_send_ipi(cpu, IRQ_IPI_SINGLE);
} }
static void smp4m_ipi_mask_one(int cpu) static void sun4m_ipi_mask_one(int cpu)
{ {
set_cpu_int(cpu, IRQ_IPI_MASK); sun4m_send_ipi(cpu, IRQ_IPI_MASK);
} }
static struct smp_funcall { static struct smp_funcall {
...@@ -191,7 +187,7 @@ static struct smp_funcall { ...@@ -191,7 +187,7 @@ static struct smp_funcall {
static DEFINE_SPINLOCK(cross_call_lock); static DEFINE_SPINLOCK(cross_call_lock);
/* Cross calls must be serialized, at least currently. */ /* Cross calls must be serialized, at least currently. */
static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
unsigned long arg2, unsigned long arg3, unsigned long arg2, unsigned long arg3,
unsigned long arg4) unsigned long arg4)
{ {
...@@ -218,7 +214,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, ...@@ -218,7 +214,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
if (cpumask_test_cpu(i, &mask)) { if (cpumask_test_cpu(i, &mask)) {
ccall_info.processors_in[i] = 0; ccall_info.processors_in[i] = 0;
ccall_info.processors_out[i] = 0; ccall_info.processors_out[i] = 0;
set_cpu_int(i, IRQ_CROSS_CALL); sun4m_send_ipi(i, IRQ_CROSS_CALL);
} else { } else {
ccall_info.processors_in[i] = 1; ccall_info.processors_in[i] = 1;
ccall_info.processors_out[i] = 1; ccall_info.processors_out[i] = 1;
...@@ -281,10 +277,14 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) ...@@ -281,10 +277,14 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
set_irq_regs(old_regs); set_irq_regs(old_regs);
} }
static const struct sparc32_ipi_ops sun4m_ipi_ops = {
.cross_call = sun4m_cross_call,
.resched = sun4m_ipi_resched,
.single = sun4m_ipi_single,
.mask_one = sun4m_ipi_mask_one,
};
void __init sun4m_init_smp(void) void __init sun4m_init_smp(void)
{ {
BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); sparc32_ipi_ops = &sun4m_ipi_ops;
BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment