sh: Support for SH-4A memory barriers.
authorPaul Mundt <lethal@linux-sh.org>
Wed, 27 Sep 2006 05:05:52 +0000 (14:05 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 27 Sep 2006 05:05:52 +0000 (14:05 +0900)
SH-4A supports 'synco' as a barrier, sprinkle it around
the cache ops as necessary..

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/mm/cache-sh4.c
include/asm-sh/system.h

index 94c05d09c3f7e046077f93f2416f3ac4484dafcf..846b63d6f5e8b39aaa971d94ce9ec51b5dca709b 100644 (file)
@@ -184,6 +184,7 @@ void flush_cache_sigtramp(unsigned long addr)
             i++, index += cpu_data->icache.way_incr)
                ctrl_outl(0, index);    /* Clear out Valid-bit */
        back_to_P1();
+       wmb();
        local_irq_restore(flags);
 }
 
@@ -223,6 +224,8 @@ void flush_dcache_page(struct page *page)
                flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys);
                flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys);
        }
+
+       wmb();
 }
 
 static inline void flush_icache_all(void)
@@ -247,6 +250,7 @@ void flush_dcache_all(void)
                __flush_dcache_all();
        else
                __flush_dcache_all_ex();
+       wmb();
 }
 
 void flush_cache_all(void)
@@ -377,5 +381,6 @@ void flush_icache_user_range(struct vm_area_struct *vma,
                             struct page *page, unsigned long addr, int len)
 {
        flush_cache_page(vma, addr, page_to_pfn(page));
+       mb();
 }
 
index e89728d405d8380ac6177b18c7b54ca6bbb2bcc9..eb4902ed920a94c1ef379020b036fce88a434728 100644 (file)
@@ -84,10 +84,17 @@ static __inline__ unsigned long tas(volatile int *m)
 
 extern void __xchg_called_with_bad_pointer(void);
 
+#ifdef CONFIG_CPU_SH4A
+#define mb()   __asm__ __volatile__ ("synco": : :"memory")
+#define rmb()  mb()
+#define wmb()  __asm__ __volatile__ ("synco": : :"memory")
+#define read_barrier_depends() do { } while(0)
+#else
 #define mb()   __asm__ __volatile__ ("": : :"memory")
 #define rmb()  mb()
 #define wmb()  __asm__ __volatile__ ("": : :"memory")
 #define read_barrier_depends() do { } while(0)
+#endif
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()