aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/smp_32.c
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-05-01 20:08:51 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-16 16:07:43 -0400
commitd6d048192b1d22cb8f09da0cc936095ec2cb969c (patch)
tree1fcb2aac7a706074a59c329a2e25cac5cc171255 /arch/sparc/kernel/smp_32.c
parent2645e7219e88d1e2ab8b2939537bce36e6db9e8c (diff)
sparc32: implement SMP IPIs using the generic functions
The current sparc32 SMP IPI generation is implemented the cross call function. The cross call function uses IRQ15 the NMI, this is has the effect that IPIs will interrupt IRQ critical areas and hang the system. Typically on/after spin_lock_irqsave calls can be aborted. The cross call functionality must still exist to flush cache/TLBS. This patch provides CPU models a custom way to implement generation of IPIs on the generic code's request. The typical approach is to generate an IRQ for each IPI case. After this patch each sparc32 SMP CPU model needs to implement IPIs in order to function properly. Signed-off-by: Daniel Hellstrom <daniel@gaisler.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/smp_32.c')
-rw-r--r--arch/sparc/kernel/smp_32.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 4a1d5b7f20d..2710602281d 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -123,13 +123,58 @@ struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 };
123 123
124void smp_send_reschedule(int cpu) 124void smp_send_reschedule(int cpu)
125{ 125{
126 /* See sparc64 */ 126 /*
127 * CPU model dependent way of implementing IPI generation targeting
128 * a single CPU. The trap handler needs only to do trap entry/return
129 * to call schedule.
130 */
131 BTFIXUP_CALL(smp_ipi_resched)(cpu);
127} 132}
128 133
129void smp_send_stop(void) 134void smp_send_stop(void)
130{ 135{
131} 136}
132 137
138void arch_send_call_function_single_ipi(int cpu)
139{
140 /* trigger one IPI single call on one CPU */
141 BTFIXUP_CALL(smp_ipi_single)(cpu);
142}
143
144void arch_send_call_function_ipi_mask(const struct cpumask *mask)
145{
146 int cpu;
147
148 /* trigger IPI mask call on each CPU */
149 for_each_cpu(cpu, mask)
150 BTFIXUP_CALL(smp_ipi_mask_one)(cpu);
151}
152
153void smp_resched_interrupt(void)
154{
155 local_cpu_data().irq_resched_count++;
156 /*
157 * do nothing, since it all was about calling re-schedule
158 * routine called by interrupt return code.
159 */
160}
161
162void smp_call_function_single_interrupt(void)
163{
164 irq_enter();
165 generic_smp_call_function_single_interrupt();
166 local_cpu_data().irq_call_count++;
167 irq_exit();
168}
169
170void smp_call_function_interrupt(void)
171{
172 irq_enter();
173 generic_smp_call_function_interrupt();
174 local_cpu_data().irq_call_count++;
175 irq_exit();
176}
177
133void smp_flush_cache_all(void) 178void smp_flush_cache_all(void)
134{ 179{
135 xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); 180 xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all));