aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorYi Li <yi.li@analog.com>2009-12-04 01:56:21 -0500
committerMike Frysinger <vapier@gentoo.org>2010-03-09 00:30:45 -0500
commitc9784ebb23be1e2ef23f537d6df04e0ea0206802 (patch)
treefd0eb67c23deb8f1073c9162bd105d8b0d9e3962 /arch/blackfin/mach-common
parent3630ac34b0ab346ff0910401dbed7af624be7027 (diff)
Blackfin: flush caches on SMP when one core calls another via IPI
Sometimes a SMP system will randomly panic at boot. This is due to caches being out of sync when one core tries to signal the other. So when one core calls another via IPI, flush the data caches. Signed-off-by: Yi Li <yi.li@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/smp.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 369e687582b7..eddb720c718e 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -122,9 +122,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
122 wait = msg->call_struct.wait; 122 wait = msg->call_struct.wait;
123 cpu_clear(cpu, msg->call_struct.pending); 123 cpu_clear(cpu, msg->call_struct.pending);
124 func(info); 124 func(info);
125 if (wait) 125 if (wait) {
126#ifdef __ARCH_SYNC_CORE_DCACHE
127 /*
128 * 'wait' usually means synchronization between CPUs.
129 * Invalidate D cache in case shared data was changed
130 * by func() to ensure cache coherence.
131 */
132 resync_core_dcache();
133#endif
126 cpu_clear(cpu, msg->call_struct.waitmask); 134 cpu_clear(cpu, msg->call_struct.waitmask);
127 else 135 } else
128 kfree(msg); 136 kfree(msg);
129} 137}
130 138
@@ -219,6 +227,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
219 blackfin_dcache_invalidate_range( 227 blackfin_dcache_invalidate_range(
220 (unsigned long)(&msg->call_struct.waitmask), 228 (unsigned long)(&msg->call_struct.waitmask),
221 (unsigned long)(&msg->call_struct.waitmask)); 229 (unsigned long)(&msg->call_struct.waitmask));
230#ifdef __ARCH_SYNC_CORE_DCACHE
231 /*
232 * Invalidate D cache in case shared data was changed by
233 * other processors to ensure cache coherence.
234 */
235 resync_core_dcache();
236#endif
222 kfree(msg); 237 kfree(msg);
223 } 238 }
224 return 0; 239 return 0;
@@ -261,6 +276,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
261 blackfin_dcache_invalidate_range( 276 blackfin_dcache_invalidate_range(
262 (unsigned long)(&msg->call_struct.waitmask), 277 (unsigned long)(&msg->call_struct.waitmask),
263 (unsigned long)(&msg->call_struct.waitmask)); 278 (unsigned long)(&msg->call_struct.waitmask));
279#ifdef __ARCH_SYNC_CORE_DCACHE
280 /*
281 * Invalidate D cache in case shared data was changed by
282 * other processors to ensure cache coherence.
283 */
284 resync_core_dcache();
285#endif
264 kfree(msg); 286 kfree(msg);
265 } 287 }
266 return 0; 288 return 0;