1/* 2 * Copyright 2004-2009 Analog Devices Inc. 3 * Tony Kou (tonyko@lineo.ca) 4 * 5 * Licensed under the GPL-2 or later 6 */ 7 8#ifndef _BLACKFIN_BARRIER_H 9#define _BLACKFIN_BARRIER_H 10 11#include <asm/cache.h> 12 13#define nop() __asm__ __volatile__ ("nop;\n\t" : : ) 14 15/* 16 * Force strict CPU ordering. 17 */ 18#ifdef CONFIG_SMP 19 20#ifdef __ARCH_SYNC_CORE_DCACHE 21/* Force Core data cache coherence */ 22# define mb() do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0) 23# define rmb() do { barrier(); smp_check_barrier(); } while (0) 24# define wmb() do { barrier(); smp_mark_barrier(); } while (0) 25/* 26 * read_barrier_depends - Flush all pending reads that subsequents reads 27 * depend on. 28 * 29 * No data-dependent reads from memory-like regions are ever reordered 30 * over this barrier. All reads preceding this primitive are guaranteed 31 * to access memory (but not necessarily other CPUs' caches) before any 32 * reads following this primitive that depend on the data return by 33 * any of the preceding reads. This primitive is much lighter weight than 34 * rmb() on most CPUs, and is never heavier weight than is 35 * rmb(). 36 * 37 * These ordering constraints are respected by both the local CPU 38 * and the compiler. 39 * 40 * Ordering is not guaranteed by anything other than these primitives, 41 * not even by data dependencies. See the documentation for 42 * memory_barrier() for examples and URLs to more information. 43 * 44 * For example, the following code would force ordering (the initial 45 * value of "a" is zero, "b" is one, and "p" is "&a"): 46 * 47 * <programlisting> 48 * CPU 0 CPU 1 49 * 50 * b = 2; 51 * memory_barrier(); 52 * p = &b; q = p; 53 * read_barrier_depends(); 54 * d = *q; 55 * </programlisting> 56 * 57 * because the read of "*q" depends on the read of "p" and these 58 * two reads are separated by a read_barrier_depends(). However, 59 * the following code, with the same initial values for "a" and "b": 60 * 61 * <programlisting> 62 * CPU 0 CPU 1 63 * 64 * a = 2; 65 * memory_barrier(); 66 * b = 3; y = b; 67 * read_barrier_depends(); 68 * x = a; 69 * </programlisting> 70 * 71 * does not enforce ordering, since there is no data dependency between 72 * the read of "a" and the read of "b". Therefore, on some CPUs, such 73 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() 74 * in cases like this where there are no data dependencies. 75 */ 76# define read_barrier_depends() do { barrier(); smp_check_barrier(); } while (0) 77#endif 78 79#endif /* !CONFIG_SMP */ 80 81#define __smp_mb__before_atomic() barrier() 82#define __smp_mb__after_atomic() barrier() 83 84#include <asm-generic/barrier.h> 85 86#endif /* _BLACKFIN_BARRIER_H */ 87