b5b778bb0b33a09bba089b3169e724c0d7125d27
[cascardo/linux.git] / arch / metag / include / asm / barrier.h
1 #ifndef _ASM_METAG_BARRIER_H
2 #define _ASM_METAG_BARRIER_H
3
4 #include <asm/metag_mem.h>
5
6 #define nop()           asm volatile ("NOP")
7
8 #ifdef CONFIG_METAG_META21
9
10 /* HTP and above have a system event to fence writes */
11 static inline void wr_fence(void)
12 {
13         volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE;
14         barrier();
15         *flushptr = 0;
16         barrier();
17 }
18
19 #else /* CONFIG_METAG_META21 */
20
21 /*
22  * ATP doesn't have system event to fence writes, so it is necessary to flush
23  * the processor write queues as well as possibly the write combiner (depending
24  * on the page being written).
25  * To ensure the write queues are flushed we do 4 writes to a system event
26  * register (in this case write combiner flush) which will also flush the write
27  * combiner.
28  */
29 static inline void wr_fence(void)
30 {
31         volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_COMBINE_FLUSH;
32         barrier();
33         *flushptr = 0;
34         *flushptr = 0;
35         *flushptr = 0;
36         *flushptr = 0;
37         barrier();
38 }
39
40 #endif /* !CONFIG_METAG_META21 */
41
42 /* flush writes through the write combiner */
43 #define mb()            wr_fence()
44 #define rmb()           barrier()
45 #define wmb()           mb()
46
47 #ifndef CONFIG_SMP
48 #define fence()         do { } while (0)
49 #define smp_mb()        barrier()
50 #define smp_rmb()       barrier()
51 #define smp_wmb()       barrier()
52 #else
53
54 #ifdef CONFIG_METAG_SMP_WRITE_REORDERING
55 /*
56  * Write to the atomic memory unlock system event register (command 0). This is
57  * needed before a write to shared memory in a critical section, to prevent
58  * external reordering of writes before the fence on other threads with writes
59  * after the fence on this thread (and to prevent the ensuing cache-memory
60  * incoherence). It is therefore ineffective if used after and on the same
61  * thread as a write.
62  */
63 static inline void fence(void)
64 {
65         volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
66         barrier();
67         *flushptr = 0;
68         barrier();
69 }
70 #define smp_mb()        fence()
71 #define smp_rmb()       fence()
72 #define smp_wmb()       barrier()
73 #else
74 #define fence()         do { } while (0)
75 #define smp_mb()        barrier()
76 #define smp_rmb()       barrier()
77 #define smp_wmb()       barrier()
78 #endif
79 #endif
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 /* _ASM_METAG_BARRIER_H */