aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 19:54:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 19:54:33 -0500
commit3c92ec8ae91ecf59d88c798301833d7cf83f2179 (patch)
tree08a38cd3523c42bd49882f17cd501fd879e7ca1c /arch/powerpc/kernel/smp.c
parentc4c9f0183b7c4e97836e8fecbb67898b06c47e78 (diff)
parentca9153a3a2a7556d091dfe080e42b0e67881fff6 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits) powerpc/44x: Support 16K/64K base page sizes on 44x powerpc: Force memory size to be a multiple of PAGE_SIZE powerpc/32: Wire up the trampoline code for kdump powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M powerpc/32: Allow __ioremap on RAM addresses for kdump kernel powerpc/32: Setup OF properties for kdump powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs() powerpc: Prepare xmon_save_regs for use with kdump powerpc: Remove default kexec/crash_kernel ops assignments powerpc: Make default kexec/crash_kernel ops implicit powerpc: Setup OF properties for ppc32 kexec powerpc/pseries: Fix cpu hotplug powerpc: Fix KVM build on ppc440 powerpc/cell: add QPACE as a separate Cell platform powerpc/cell: fix build breakage with CONFIG_SPUFS disabled powerpc/mpc5200: fix error paths in PSC UART probe function powerpc/mpc5200: add rts/cts handling in PSC UART driver powerpc/mpc5200: Make PSC UART driver update serial errors counters powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver ... Fix trivial conflict in drivers/char/Makefile as per Paul's directions
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index ff9f7010097d..8ac3f721d235 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,7 +57,6 @@
57#define DBG(fmt...) 57#define DBG(fmt...)
58#endif 58#endif
59 59
60int smp_hw_index[NR_CPUS];
61struct thread_info *secondary_ti; 60struct thread_info *secondary_ti;
62 61
63cpumask_t cpu_possible_map = CPU_MASK_NONE; 62cpumask_t cpu_possible_map = CPU_MASK_NONE;
@@ -123,6 +122,65 @@ void smp_message_recv(int msg)
123 } 122 }
124} 123}
125 124
125static irqreturn_t call_function_action(int irq, void *data)
126{
127 generic_smp_call_function_interrupt();
128 return IRQ_HANDLED;
129}
130
131static irqreturn_t reschedule_action(int irq, void *data)
132{
133 /* we just need the return path side effect of checking need_resched */
134 return IRQ_HANDLED;
135}
136
137static irqreturn_t call_function_single_action(int irq, void *data)
138{
139 generic_smp_call_function_single_interrupt();
140 return IRQ_HANDLED;
141}
142
143static irqreturn_t debug_ipi_action(int irq, void *data)
144{
145 smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
146 return IRQ_HANDLED;
147}
148
149static irq_handler_t smp_ipi_action[] = {
150 [PPC_MSG_CALL_FUNCTION] = call_function_action,
151 [PPC_MSG_RESCHEDULE] = reschedule_action,
152 [PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action,
153 [PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action,
154};
155
156const char *smp_ipi_name[] = {
157 [PPC_MSG_CALL_FUNCTION] = "ipi call function",
158 [PPC_MSG_RESCHEDULE] = "ipi reschedule",
159 [PPC_MSG_CALL_FUNC_SINGLE] = "ipi call function single",
160 [PPC_MSG_DEBUGGER_BREAK] = "ipi debugger",
161};
162
163/* optional function to request ipi, for controllers with >= 4 ipis */
164int smp_request_message_ipi(int virq, int msg)
165{
166 int err;
167
168 if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) {
169 return -EINVAL;
170 }
171#if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC)
172 if (msg == PPC_MSG_DEBUGGER_BREAK) {
173 return 1;
174 }
175#endif
176 err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
177 smp_ipi_name[msg], 0);
178 WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
179 virq, smp_ipi_name[msg], err);
180
181 return err;
182}
183
126void smp_send_reschedule(int cpu) 184void smp_send_reschedule(int cpu)
127{ 185{
128 if (likely(smp_ops)) 186 if (likely(smp_ops))
@@ -408,8 +466,7 @@ out:
408static struct device_node *cpu_to_l2cache(int cpu) 466static struct device_node *cpu_to_l2cache(int cpu)
409{ 467{
410 struct device_node *np; 468 struct device_node *np;
411 const phandle *php; 469 struct device_node *cache;
412 phandle ph;
413 470
414 if (!cpu_present(cpu)) 471 if (!cpu_present(cpu))
415 return NULL; 472 return NULL;
@@ -418,13 +475,11 @@ static struct device_node *cpu_to_l2cache(int cpu)
418 if (np == NULL) 475 if (np == NULL)
419 return NULL; 476 return NULL;
420 477
421 php = of_get_property(np, "l2-cache", NULL); 478 cache = of_find_next_cache_node(np);
422 if (php == NULL) 479
423 return NULL;
424 ph = *php;
425 of_node_put(np); 480 of_node_put(np);
426 481
427 return of_find_node_by_phandle(ph); 482 return cache;
428} 483}
429 484
430/* Activate a secondary processor. */ 485/* Activate a secondary processor. */