aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r--arch/blackfin/mach-common/smp.c35
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 */
41struct corelock_slot corelock __attribute__ ((__section__(".l2.bss"))); 41struct corelock_slot corelock __attribute__ ((__section__(".l2.bss")));
42 42
43#ifdef CONFIG_ICACHE_FLUSH_L1
44unsigned long blackfin_iflush_l1_entry[NR_CPUS];
45#endif
46
43void __cpuinitdata *init_retx_coreb, *init_saved_retx_coreb, 47void __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