diff options
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 71 |
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 | ||
60 | int smp_hw_index[NR_CPUS]; | ||
61 | struct thread_info *secondary_ti; | 60 | struct thread_info *secondary_ti; |
62 | 61 | ||
63 | cpumask_t cpu_possible_map = CPU_MASK_NONE; | 62 | cpumask_t cpu_possible_map = CPU_MASK_NONE; |
@@ -123,6 +122,65 @@ void smp_message_recv(int msg) | |||
123 | } | 122 | } |
124 | } | 123 | } |
125 | 124 | ||
125 | static irqreturn_t call_function_action(int irq, void *data) | ||
126 | { | ||
127 | generic_smp_call_function_interrupt(); | ||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static 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 | |||
137 | static irqreturn_t call_function_single_action(int irq, void *data) | ||
138 | { | ||
139 | generic_smp_call_function_single_interrupt(); | ||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
143 | static irqreturn_t debug_ipi_action(int irq, void *data) | ||
144 | { | ||
145 | smp_message_recv(PPC_MSG_DEBUGGER_BREAK); | ||
146 | return IRQ_HANDLED; | ||
147 | } | ||
148 | |||
149 | static 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 | |||
156 | const 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 */ | ||
164 | int 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 | |||
126 | void smp_send_reschedule(int cpu) | 184 | void smp_send_reschedule(int cpu) |
127 | { | 185 | { |
128 | if (likely(smp_ops)) | 186 | if (likely(smp_ops)) |
@@ -408,8 +466,7 @@ out: | |||
408 | static struct device_node *cpu_to_l2cache(int cpu) | 466 | static 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. */ |