Merge git://git.infradead.org/~dwmw2/iommu-2.6.32
[cascardo/linux.git] / arch / blackfin / include / asm / mutex.h
index 458c1f7..f726e3a 100644 (file)
@@ -4,6 +4,73 @@
  * TODO: implement optimized primitives instead, or leave the generic
  * implementation in place, or pick the atomic_xchg() based generic
  * implementation. (see asm-generic/mutex-xchg.h for details)
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
  */
 
-#include <asm-generic/mutex-dec.h>
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+#ifndef CONFIG_SMP
+#include <asm-generic/mutex.h>
+#else
+
+static inline void
+__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+       if (unlikely(atomic_dec_return(count) < 0))
+               fail_fn(count);
+       else
+               smp_mb();
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+       if (unlikely(atomic_dec_return(count) < 0))
+               return fail_fn(count);
+       else {
+               smp_mb();
+               return 0;
+       }
+}
+
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+       smp_mb();
+       if (unlikely(atomic_inc_return(count) <= 0))
+               fail_fn(count);
+}
+
+#define __mutex_slowpath_needs_to_unlock()             1
+
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+       /*
+        * We have two variants here. The cmpxchg based one is the best one
+        * because it never induce a false contention state.  It is included
+        * here because architectures using the inc/dec algorithms over the
+        * xchg ones are much more likely to support cmpxchg natively.
+        *
+        * If not we fall back to the spinlock based variant - that is
+        * just as efficient (and simpler) as a 'destructive' probing of
+        * the mutex state would be.
+        */
+#ifdef __HAVE_ARCH_CMPXCHG
+       if (likely(atomic_cmpxchg(count, 1, 0) == 1)) {
+               smp_mb();
+               return 1;
+       }
+       return 0;
+#else
+       return fail_fn(count);
+#endif
+}
+
+#endif
+
+#endif