]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-sh/system.h
sh: Fix libata build.
[linux-2.6-omap-h63xx.git] / include / asm-sh / system.h
index bb0330499bdfef3987cc88d7dd454ead0df3a929..eb4902ed920a94c1ef379020b036fce88a434728 100644 (file)
@@ -6,14 +6,14 @@
  * Copyright (C) 2002 Paul Mundt
  */
 
-#include <linux/config.h>
+#include <asm/types.h>
 
 /*
  *     switch_to() should switch tasks to task nr n, first
  */
 
 #define switch_to(prev, next, last) do {                               \
task_t *__last;                                                       \
struct task_struct *__last;                                           \
  register unsigned long *__ts1 __asm__ ("r1") = &prev->thread.sp;      \
  register unsigned long *__ts2 __asm__ ("r2") = &prev->thread.pc;      \
  register unsigned long *__ts4 __asm__ ("r4") = (unsigned long *)prev; \
@@ -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()
@@ -102,7 +109,6 @@ extern void __xchg_called_with_bad_pointer(void);
 #endif
 
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 /* Interrupt Control */
 static __inline__ void local_irq_enable(void)
@@ -262,6 +268,45 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int
        return x;
 }
 
+static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
+       unsigned long new)
+{
+       __u32 retval;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       retval = *m;
+       if (retval == old)
+               *m = new;
+       local_irq_restore(flags);       /* implies memory barrier  */
+       return retval;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
+               unsigned long new, int size)
+{
+       switch (size) {
+       case 4:
+               return __cmpxchg_u32(ptr, old, new);
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#define cmpxchg(ptr,o,n)                                                \
+  ({                                                                    \
+     __typeof__(*(ptr)) _o_ = (o);                                      \
+     __typeof__(*(ptr)) _n_ = (n);                                      \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
+                                   (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
 /* XXX
  * disable hlt during certain critical i/o operations
  */