diff options
Diffstat (limited to 'arch/mips/sgi-ip27/ip27-smp.c')
-rw-r--r-- | arch/mips/sgi-ip27/ip27-smp.c | 109 |
1 files changed, 64 insertions, 45 deletions
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index a70656d42191..f15fc93d6b35 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c | |||
@@ -140,30 +140,51 @@ static __init void intr_clear_all(nasid_t nasid) | |||
140 | REMOTE_HUB_CLR_INTR(nasid, i); | 140 | REMOTE_HUB_CLR_INTR(nasid, i); |
141 | } | 141 | } |
142 | 142 | ||
143 | void __init plat_smp_setup(void) | 143 | static void ip27_send_ipi_single(int destid, unsigned int action) |
144 | { | 144 | { |
145 | cnodeid_t cnode; | 145 | int irq; |
146 | 146 | ||
147 | for_each_online_node(cnode) { | 147 | switch (action) { |
148 | if (cnode == 0) | 148 | case SMP_RESCHEDULE_YOURSELF: |
149 | continue; | 149 | irq = CPU_RESCHED_A_IRQ; |
150 | intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); | 150 | break; |
151 | case SMP_CALL_FUNCTION: | ||
152 | irq = CPU_CALL_A_IRQ; | ||
153 | break; | ||
154 | default: | ||
155 | panic("sendintr"); | ||
151 | } | 156 | } |
152 | 157 | ||
153 | replicate_kernel_text(); | 158 | irq += cputoslice(destid); |
154 | 159 | ||
155 | /* | 160 | /* |
156 | * Assumption to be fixed: we're always booted on logical / physical | 161 | * Convert the compact hub number to the NASID to get the correct |
157 | * processor 0. While we're always running on logical processor 0 | 162 | * part of the address space. Then set the interrupt bit associated |
158 | * this still means this is physical processor zero; it might for | 163 | * with the CPU we want to send the interrupt to. |
159 | * example be disabled in the firwware. | ||
160 | */ | 164 | */ |
161 | alloc_cpupda(0, 0); | 165 | REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); |
162 | } | 166 | } |
163 | 167 | ||
164 | void __init plat_prepare_cpus(unsigned int max_cpus) | 168 | static void ip27_send_ipi_mask(cpumask_t mask, unsigned int action) |
169 | { | ||
170 | unsigned int i; | ||
171 | |||
172 | for_each_cpu_mask(i, mask) | ||
173 | ip27_send_ipi_single(i, action); | ||
174 | } | ||
175 | |||
176 | static void __cpuinit ip27_init_secondary(void) | ||
177 | { | ||
178 | per_cpu_init(); | ||
179 | local_irq_enable(); | ||
180 | } | ||
181 | |||
182 | static void __cpuinit ip27_smp_finish(void) | ||
183 | { | ||
184 | } | ||
185 | |||
186 | static void __init ip27_cpus_done(void) | ||
165 | { | 187 | { |
166 | /* We already did everything necessary earlier */ | ||
167 | } | 188 | } |
168 | 189 | ||
169 | /* | 190 | /* |
@@ -171,7 +192,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) | |||
171 | * set sp to the kernel stack of the newly created idle process, gp to the proc | 192 | * set sp to the kernel stack of the newly created idle process, gp to the proc |
172 | * struct so that current_thread_info() will work. | 193 | * struct so that current_thread_info() will work. |
173 | */ | 194 | */ |
174 | void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) | 195 | static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle) |
175 | { | 196 | { |
176 | unsigned long gp = (unsigned long)task_thread_info(idle); | 197 | unsigned long gp = (unsigned long)task_thread_info(idle); |
177 | unsigned long sp = __KSTK_TOS(idle); | 198 | unsigned long sp = __KSTK_TOS(idle); |
@@ -181,41 +202,39 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) | |||
181 | 0, (void *) sp, (void *) gp); | 202 | 0, (void *) sp, (void *) gp); |
182 | } | 203 | } |
183 | 204 | ||
184 | void __cpuinit prom_init_secondary(void) | 205 | static void __init ip27_smp_setup(void) |
185 | { | 206 | { |
186 | per_cpu_init(); | 207 | cnodeid_t cnode; |
187 | local_irq_enable(); | ||
188 | } | ||
189 | |||
190 | void __init prom_cpus_done(void) | ||
191 | { | ||
192 | } | ||
193 | |||
194 | void __cpuinit prom_smp_finish(void) | ||
195 | { | ||
196 | } | ||
197 | |||
198 | void core_send_ipi(int destid, unsigned int action) | ||
199 | { | ||
200 | int irq; | ||
201 | 208 | ||
202 | switch (action) { | 209 | for_each_online_node(cnode) { |
203 | case SMP_RESCHEDULE_YOURSELF: | 210 | if (cnode == 0) |
204 | irq = CPU_RESCHED_A_IRQ; | 211 | continue; |
205 | break; | 212 | intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); |
206 | case SMP_CALL_FUNCTION: | ||
207 | irq = CPU_CALL_A_IRQ; | ||
208 | break; | ||
209 | default: | ||
210 | panic("sendintr"); | ||
211 | } | 213 | } |
212 | 214 | ||
213 | irq += cputoslice(destid); | 215 | replicate_kernel_text(); |
214 | 216 | ||
215 | /* | 217 | /* |
216 | * Convert the compact hub number to the NASID to get the correct | 218 | * Assumption to be fixed: we're always booted on logical / physical |
217 | * part of the address space. Then set the interrupt bit associated | 219 | * processor 0. While we're always running on logical processor 0 |
218 | * with the CPU we want to send the interrupt to. | 220 | * this still means this is physical processor zero; it might for |
221 | * example be disabled in the firwware. | ||
219 | */ | 222 | */ |
220 | REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); | 223 | alloc_cpupda(0, 0); |
221 | } | 224 | } |
225 | |||
226 | static void __init ip27_prepare_cpus(unsigned int max_cpus) | ||
227 | { | ||
228 | /* We already did everything necessary earlier */ | ||
229 | } | ||
230 | |||
231 | struct plat_smp_ops ip27_smp_ops = { | ||
232 | .send_ipi_single = ip27_send_ipi_single, | ||
233 | .send_ipi_mask = ip27_send_ipi_mask, | ||
234 | .init_secondary = ip27_init_secondary, | ||
235 | .smp_finish = ip27_smp_finish, | ||
236 | .cpus_done = ip27_cpus_done, | ||
237 | .boot_secondary = ip27_boot_secondary, | ||
238 | .smp_setup = ip27_smp_setup, | ||
239 | .prepare_cpus = ip27_prepare_cpus, | ||
240 | }; | ||