Blackfin arch: smp patch cleanup from LKML review
[safe/jmp/linux-2.6] / arch / blackfin / include / asm / system.h
index 8f1627d..dea9203 100644 (file)
 #include <linux/linkage.h>
 #include <linux/compiler.h>
 #include <mach/anomaly.h>
+#include <asm/pda.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
 
 /*
- * Interrupt configuring macros.
+ * Force strict CPU ordering.
  */
+#define nop()  asm volatile ("nop;\n\t"::)
+#define mb()   asm volatile (""   : : :"memory")
+#define rmb()  asm volatile (""   : : :"memory")
+#define wmb()  asm volatile (""   : : :"memory")
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
+#define read_barrier_depends()                 do { } while(0)
 
-extern unsigned long irq_flags;
-
-#define local_irq_enable() \
-       __asm__ __volatile__( \
-               "sti %0;" \
-               : \
-               : "d" (irq_flags) \
-       )
-
-#define local_irq_disable() \
-       do { \
-               int __tmp_dummy; \
-               __asm__ __volatile__( \
-                       "cli %0;" \
-                       : "=d" (__tmp_dummy) \
-               ); \
-       } while (0)
-
-#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
-# define NOP_PAD_ANOMALY_05000244 "nop; nop;"
-#else
-# define NOP_PAD_ANOMALY_05000244
-#endif
-
-#define idle_with_irq_disabled() \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000244 \
-               ".align 8;" \
-               "sti %0;" \
-               "idle;" \
-               : \
-               : "d" (irq_flags) \
-       )
-
-#ifdef CONFIG_DEBUG_HWERR
-# define __save_and_cli(x) \
-       __asm__ __volatile__( \
-               "cli %0;" \
-               "sti %1;" \
-               : "=&d" (x) \
-               : "d" (0x3F) \
-       )
-#else
-# define __save_and_cli(x) \
-       __asm__ __volatile__( \
-               "cli %0;" \
-               : "=&d" (x) \
-       )
-#endif
-
-#define local_save_flags(x) \
-       __asm__ __volatile__( \
-               "cli %0;" \
-               "sti %0;" \
-               : "=d" (x) \
-       )
+#ifdef CONFIG_SMP
+asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value);
+asmlinkage unsigned long __raw_xchg_2_asm(volatile void *ptr, unsigned long value);
+asmlinkage unsigned long __raw_xchg_4_asm(volatile void *ptr, unsigned long value);
+asmlinkage unsigned long __raw_cmpxchg_1_asm(volatile void *ptr,
+                                       unsigned long new, unsigned long old);
+asmlinkage unsigned long __raw_cmpxchg_2_asm(volatile void *ptr,
+                                       unsigned long new, unsigned long old);
+asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr,
+                                       unsigned long new, unsigned long old);
+
+#ifdef __ARCH_SYNC_CORE_DCACHE
+# define smp_mb()      do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0)
+# define smp_rmb()     do { barrier(); smp_check_barrier(); } while (0)
+# define smp_wmb()     do { barrier(); smp_mark_barrier(); } while (0)
+#define smp_read_barrier_depends()     do { barrier(); smp_check_barrier(); } while (0)
 
-#ifdef CONFIG_DEBUG_HWERR
-#define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
 #else
-#define irqs_enabled_from_flags(x) ((x) != 0x1f)
+# define smp_mb()      barrier()
+# define smp_rmb()     barrier()
+# define smp_wmb()     barrier()
+#define smp_read_barrier_depends()     barrier()
 #endif
 
-#define local_irq_restore(x) \
-       do { \
-               if (irqs_enabled_from_flags(x)) \
-                       local_irq_enable(); \
-       } while (0)
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+                                  int size)
+{
+       unsigned long tmp;
 
-/* For spinlocks etc */
-#define local_irq_save(x) __save_and_cli(x)
+       switch (size) {
+       case 1:
+               tmp = __raw_xchg_1_asm(ptr, x);
+               break;
+       case 2:
+               tmp = __raw_xchg_2_asm(ptr, x);
+               break;
+       case 4:
+               tmp = __raw_xchg_4_asm(ptr, x);
+               break;
+       }
 
-#define        irqs_disabled()                         \
-({                                             \
-       unsigned long flags;                    \
-       local_save_flags(flags);                \
-       !irqs_enabled_from_flags(flags);        \
-})
+       return tmp;
+}
 
 /*
- * Force strict CPU ordering.
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
  */
-#define nop()  asm volatile ("nop;\n\t"::)
-#define mb()   asm volatile (""   : : :"memory")
-#define rmb()  asm volatile (""   : : :"memory")
-#define wmb()  asm volatile (""   : : :"memory")
-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                                     unsigned long new, int size)
+{
+       unsigned long tmp;
 
-#define read_barrier_depends()                 do { } while(0)
+       switch (size) {
+       case 1:
+               tmp = __raw_cmpxchg_1_asm(ptr, new, old);
+               break;
+       case 2:
+               tmp = __raw_cmpxchg_2_asm(ptr, new, old);
+               break;
+       case 4:
+               tmp = __raw_cmpxchg_4_asm(ptr, new, old);
+               break;
+       }
+
+       return tmp;
+}
+#define cmpxchg(ptr, o, n) \
+       ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
+               (unsigned long)(n), sizeof(*(ptr))))
+
+#else /* !CONFIG_SMP */
 
-#ifdef CONFIG_SMP
-#define smp_mb()       mb()
-#define smp_rmb()      rmb()
-#define smp_wmb()      wmb()
-#define smp_read_barrier_depends()     read_barrier_depends()
-#else
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
 #define smp_read_barrier_depends()     do { } while(0)
-#endif
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
 struct __xchg_dummy {
        unsigned long a[100];
@@ -194,9 +178,12 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
                        (unsigned long)(n), sizeof(*(ptr))))
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 
-#ifndef CONFIG_SMP
 #include <asm-generic/cmpxchg.h>
-#endif
+
+#endif /* !CONFIG_SMP */
+
+#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define tas(ptr) ((void)xchg((ptr), 1))
 
 #define prepare_to_switch()     do { } while(0)
 
@@ -205,7 +192,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
  * ptr isn't the current task, in which case it does nothing.
  */
 
-#include <asm/blackfin.h>
+#include <asm/l1layout.h>
+#include <asm/mem_map.h>
 
 asmlinkage struct task_struct *resume(struct task_struct *prev, struct task_struct *next);
 
@@ -218,4 +206,4 @@ do {    \
        (last) = resume (prev, next);   \
 } while (0)
 
-#endif                         /* _BLACKFIN_SYSTEM_H */
+#endif /* _BLACKFIN_SYSTEM_H */