diff options
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 9f251406a76a..8bce5ed031e4 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -40,6 +40,10 @@ | |||
40 | */ | 40 | */ |
41 | struct corelock_slot corelock __attribute__ ((__section__(".l2.bss"))); | 41 | struct corelock_slot corelock __attribute__ ((__section__(".l2.bss"))); |
42 | 42 | ||
43 | #ifdef CONFIG_ICACHE_FLUSH_L1 | ||
44 | unsigned long blackfin_iflush_l1_entry[NR_CPUS]; | ||
45 | #endif | ||
46 | |||
43 | void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, | 47 | void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, |
44 | *init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb, | 48 | *init_saved_seqstat_coreb, *init_saved_icplb_fault_addr_coreb, |
45 | *init_saved_dcplb_fault_addr_coreb; | 49 | *init_saved_dcplb_fault_addr_coreb; |
@@ -108,6 +112,19 @@ static void ipi_flush_icache(void *info) | |||
108 | blackfin_dcache_invalidate_range((unsigned long)fdata, | 112 | blackfin_dcache_invalidate_range((unsigned long)fdata, |
109 | (unsigned long)fdata + sizeof(*fdata)); | 113 | (unsigned long)fdata + sizeof(*fdata)); |
110 | 114 | ||
115 | /* Make sure all write buffers in the data side of the core | ||
116 | * are flushed before trying to invalidate the icache. This | ||
117 | * needs to be after the data flush and before the icache | ||
118 | * flush so that the SSYNC does the right thing in preventing | ||
119 | * the instruction prefetcher from hitting things in cached | ||
120 | * memory at the wrong time -- it runs much further ahead than | ||
121 | * the pipeline. | ||
122 | */ | ||
123 | SSYNC(); | ||
124 | |||
125 | /* ipi_flaush_icache is invoked by generic flush_icache_range, | ||
126 | * so call blackfin arch icache flush directly here. | ||
127 | */ | ||
111 | blackfin_icache_flush_range(fdata->start, fdata->end); | 128 | blackfin_icache_flush_range(fdata->start, fdata->end); |
112 | } | 129 | } |
113 | 130 | ||
@@ -244,12 +261,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait) | |||
244 | { | 261 | { |
245 | cpumask_t callmap; | 262 | cpumask_t callmap; |
246 | 263 | ||
264 | preempt_disable(); | ||
247 | callmap = cpu_online_map; | 265 | callmap = cpu_online_map; |
248 | cpu_clear(smp_processor_id(), callmap); | 266 | cpu_clear(smp_processor_id(), callmap); |
249 | if (cpus_empty(callmap)) | 267 | if (!cpus_empty(callmap)) |
250 | return 0; | 268 | smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); |
251 | 269 | ||
252 | smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); | 270 | preempt_enable(); |
253 | 271 | ||
254 | return 0; | 272 | return 0; |
255 | } | 273 | } |
@@ -286,12 +304,13 @@ void smp_send_stop(void) | |||
286 | { | 304 | { |
287 | cpumask_t callmap; | 305 | cpumask_t callmap; |
288 | 306 | ||
307 | preempt_disable(); | ||
289 | callmap = cpu_online_map; | 308 | callmap = cpu_online_map; |
290 | cpu_clear(smp_processor_id(), callmap); | 309 | cpu_clear(smp_processor_id(), callmap); |
291 | if (cpus_empty(callmap)) | 310 | if (!cpus_empty(callmap)) |
292 | return; | 311 | smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); |
293 | 312 | ||
294 | smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); | 313 | preempt_enable(); |
295 | 314 | ||
296 | return; | 315 | return; |
297 | } | 316 | } |
@@ -361,8 +380,6 @@ void __cpuinit secondary_start_kernel(void) | |||
361 | */ | 380 | */ |
362 | init_exception_vectors(); | 381 | init_exception_vectors(); |
363 | 382 | ||
364 | bfin_setup_caches(cpu); | ||
365 | |||
366 | local_irq_disable(); | 383 | local_irq_disable(); |
367 | 384 | ||
368 | /* Attach the new idle task to the global mm. */ | 385 | /* Attach the new idle task to the global mm. */ |
@@ -381,6 +398,8 @@ void __cpuinit secondary_start_kernel(void) | |||
381 | 398 | ||
382 | local_irq_enable(); | 399 | local_irq_enable(); |
383 | 400 | ||
401 | bfin_setup_caches(cpu); | ||
402 | |||
384 | /* | 403 | /* |
385 | * Calibrate loops per jiffy value. | 404 | * Calibrate loops per jiffy value. |
386 | * IRQs need to be enabled here - D-cache can be invalidated | 405 | * IRQs need to be enabled here - D-cache can be invalidated |