Blackfin: flush caches on SMP when one core calls another via IPI
[pandora-kernel.git] / arch / blackfin / mach-common / smp.c
index 369e687..eddb720 100644 (file)
@@ -122,9 +122,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
        wait = msg->call_struct.wait;
        cpu_clear(cpu, msg->call_struct.pending);
        func(info);
-       if (wait)
+       if (wait) {
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * 'wait' usually means synchronization between CPUs.
+                * Invalidate D cache in case shared data was changed
+                * by func() to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                cpu_clear(cpu, msg->call_struct.waitmask);
-       else
+       else
                kfree(msg);
 }
 
@@ -219,6 +227,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
                        blackfin_dcache_invalidate_range(
                                (unsigned long)(&msg->call_struct.waitmask),
                                (unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * Invalidate D cache in case shared data was changed by
+                * other processors to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                kfree(msg);
        }
        return 0;
@@ -261,6 +276,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
                        blackfin_dcache_invalidate_range(
                                (unsigned long)(&msg->call_struct.waitmask),
                                (unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * Invalidate D cache in case shared data was changed by
+                * other processors to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                kfree(msg);
        }
        return 0;