x86: consolidate header guards
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / include / asm-x86 / spinlock.h
index 23804c1890ffcd0780ba4c6171896db99d46a658..cbe01086ba640e4af05ad1b32a8f2bad2ae3699e 100644 (file)
@@ -1,12 +1,12 @@
-#ifndef _X86_SPINLOCK_H_
-#define _X86_SPINLOCK_H_
+#ifndef ASM_X86__SPINLOCK_H
+#define ASM_X86__SPINLOCK_H
 
 #include <asm/atomic.h>
 #include <asm/rwlock.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <linux/compiler.h>
-
+#include <asm/paravirt.h>
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  *
  */
 
 #ifdef CONFIG_X86_32
-typedef char _slock_t;
-# define LOCK_INS_DEC "decb"
-# define LOCK_INS_XCH "xchgb"
-# define LOCK_INS_MOV "movb"
-# define LOCK_INS_CMP "cmpb"
 # define LOCK_PTR_REG "a"
 #else
-typedef int _slock_t;
-# define LOCK_INS_DEC "decl"
-# define LOCK_INS_XCH "xchgl"
-# define LOCK_INS_MOV "movl"
-# define LOCK_INS_CMP "cmpl"
 # define LOCK_PTR_REG "D"
 #endif
 
@@ -64,25 +54,25 @@ typedef int _slock_t;
  * much between them in performance though, especially as locks are out of line.
  */
 #if (NR_CPUS < 256)
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) != (tmp & 0xff));
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
 {
        short inc = 0x0100;
 
-       __asm__ __volatile__ (
+       asm volatile (
                LOCK_PREFIX "xaddw %w0, %1\n"
                "1:\t"
                "cmpb %h0, %b0\n\t"
@@ -92,115 +82,198 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
                /* don't need lfence here, because loads are in-order */
                "jmp 1b\n"
                "2:"
-               :"+Q" (inc), "+m" (lock->slock)
+               : "+Q" (inc), "+m" (lock->slock)
                :
-               :"memory", "cc");
+               : "memory", "cc");
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 {
        int tmp;
        short new;
 
-       asm volatile(
-               "movw %2,%w0\n\t"
-               "cmpb %h0,%b0\n\t"
-               "jne 1f\n\t"
-               "movw %w0,%w1\n\t"
-               "incb %h1\n\t"
-               "lock ; cmpxchgw %w1,%2\n\t"
-               "1:"
-               "sete %b1\n\t"
-               "movzbl %b1,%0\n\t"
-               :"=&a" (tmp), "=Q" (new), "+m" (lock->slock)
-               :
-               : "memory", "cc");
+       asm volatile("movw %2,%w0\n\t"
+                    "cmpb %h0,%b0\n\t"
+                    "jne 1f\n\t"
+                    "movw %w0,%w1\n\t"
+                    "incb %h1\n\t"
+                    "lock ; cmpxchgw %w1,%2\n\t"
+                    "1:"
+                    "sete %b1\n\t"
+                    "movzbl %b1,%0\n\t"
+                    : "=&a" (tmp), "=Q" (new), "+m" (lock->slock)
+                    :
+                    : "memory", "cc");
 
        return tmp;
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
 {
-       __asm__ __volatile__(
-               UNLOCK_LOCK_PREFIX "incb %0"
-               :"+m" (lock->slock)
-               :
-               :"memory", "cc");
+       asm volatile(UNLOCK_LOCK_PREFIX "incb %0"
+                    : "+m" (lock->slock)
+                    :
+                    : "memory", "cc");
 }
 #else
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
 {
-       int tmp = *(volatile signed int *)(&(lock)->slock);
+       int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
 }
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
 {
        int inc = 0x00010000;
        int tmp;
 
-       __asm__ __volatile__ (
-               "lock ; xaddl %0, %1\n"
-               "movzwl %w0, %2\n\t"
-               "shrl $16, %0\n\t"
-               "1:\t"
-               "cmpl %0, %2\n\t"
-               "je 2f\n\t"
-               "rep ; nop\n\t"
-               "movzwl %1, %2\n\t"
-               /* don't need lfence here, because loads are in-order */
-               "jmp 1b\n"
-               "2:"
-               :"+Q" (inc), "+m" (lock->slock), "=r" (tmp)
-               :
-               :"memory", "cc");
+       asm volatile("lock ; xaddl %0, %1\n"
+                    "movzwl %w0, %2\n\t"
+                    "shrl $16, %0\n\t"
+                    "1:\t"
+                    "cmpl %0, %2\n\t"
+                    "je 2f\n\t"
+                    "rep ; nop\n\t"
+                    "movzwl %1, %2\n\t"
+                    /* don't need lfence here, because loads are in-order */
+                    "jmp 1b\n"
+                    "2:"
+                    : "+Q" (inc), "+m" (lock->slock), "=r" (tmp)
+                    :
+                    : "memory", "cc");
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 {
        int tmp;
        int new;
 
-       asm volatile(
-               "movl %2,%0\n\t"
-               "movl %0,%1\n\t"
-               "roll $16, %0\n\t"
-               "cmpl %0,%1\n\t"
-               "jne 1f\n\t"
-               "addl $0x00010000, %1\n\t"
-               "lock ; cmpxchgl %1,%2\n\t"
-               "1:"
-               "sete %b1\n\t"
-               "movzbl %b1,%0\n\t"
-               :"=&a" (tmp), "=r" (new), "+m" (lock->slock)
-               :
-               : "memory", "cc");
+       asm volatile("movl %2,%0\n\t"
+                    "movl %0,%1\n\t"
+                    "roll $16, %0\n\t"
+                    "cmpl %0,%1\n\t"
+                    "jne 1f\n\t"
+                    "addl $0x00010000, %1\n\t"
+                    "lock ; cmpxchgl %1,%2\n\t"
+                    "1:"
+                    "sete %b1\n\t"
+                    "movzbl %b1,%0\n\t"
+                    : "=&a" (tmp), "=r" (new), "+m" (lock->slock)
+                    :
+                    : "memory", "cc");
 
        return tmp;
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
 {
-       __asm__ __volatile__(
-               UNLOCK_LOCK_PREFIX "incw %0"
-               :"+m" (lock->slock)
-               :
-               :"memory", "cc");
+       asm volatile(UNLOCK_LOCK_PREFIX "incw %0"
+                    : "+m" (lock->slock)
+                    :
+                    : "memory", "cc");
 }
 #endif
 
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+#ifdef CONFIG_PARAVIRT
+/*
+ * Define virtualization-friendly old-style lock byte lock, for use in
+ * pv_lock_ops if desired.
+ *
+ * This differs from the pre-2.6.24 spinlock by always using xchgb
+ * rather than decb to take the lock; this allows it to use a
+ * zero-initialized lock structure.  It also maintains a 1-byte
+ * contention counter, so that we can implement
+ * __byte_spin_is_contended.
+ */
+struct __byte_spinlock {
+       s8 lock;
+       s8 spinners;
+};
+
+static inline int __byte_spin_is_locked(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       return bl->lock != 0;
+}
+
+static inline int __byte_spin_is_contended(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       return bl->spinners != 0;
+}
+
+static inline void __byte_spin_lock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       s8 val = 1;
+
+       asm("1: xchgb %1, %0\n"
+           "   test %1,%1\n"
+           "   jz 3f\n"
+           "   " LOCK_PREFIX "incb %2\n"
+           "2: rep;nop\n"
+           "   cmpb $1, %0\n"
+           "   je 2b\n"
+           "   " LOCK_PREFIX "decb %2\n"
+           "   jmp 1b\n"
+           "3:"
+           : "+m" (bl->lock), "+q" (val), "+m" (bl->spinners): : "memory");
+}
+
+static inline int __byte_spin_trylock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       u8 old = 1;
+
+       asm("xchgb %1,%0"
+           : "+m" (bl->lock), "+q" (old) : : "memory");
+
+       return old == 0;
+}
+
+static inline void __byte_spin_unlock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       smp_wmb();
+       bl->lock = 0;
+}
+#else  /* !CONFIG_PARAVIRT */
+static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+{
+       return __ticket_spin_is_locked(lock);
+}
+
+static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+{
+       return __ticket_spin_is_contended(lock);
+}
+
+static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+       __ticket_spin_lock(lock);
+}
+
+static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+       return __ticket_spin_trylock(lock);
+}
+
+static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+       __ticket_spin_unlock(lock);
+}
+#endif /* CONFIG_PARAVIRT */
+
 static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
 {
        while (__raw_spin_is_locked(lock))
@@ -293,4 +366,4 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
 #define _raw_read_relax(lock)  cpu_relax()
 #define _raw_write_relax(lock) cpu_relax()
 
-#endif
+#endif /* ASM_X86__SPINLOCK_H */