#ifndef _ASM_X86_RWLOCK_H
 #define _ASM_X86_RWLOCK_H
 
-#define RW_LOCK_BIAS            0x01000000
+#include <asm/asm.h>
+
+#if CONFIG_NR_CPUS <= 2048
+
+#ifndef __ASSEMBLY__
+typedef union {
+       s32 lock;
+       s32 write;
+} arch_rwlock_t;
+#endif
+
+#define RW_LOCK_BIAS           0x00100000
+#define READ_LOCK_SIZE(insn)   __ASM_FORM(insn##l)
+#define READ_LOCK_ATOMIC(n)    atomic_##n
+#define WRITE_LOCK_ADD(n)      __ASM_FORM_COMMA(addl n)
+#define WRITE_LOCK_SUB(n)      __ASM_FORM_COMMA(subl n)
+#define WRITE_LOCK_CMP         RW_LOCK_BIAS
+
+#else /* CONFIG_NR_CPUS > 2048 */
+
+#include <linux/const.h>
+
+#ifndef __ASSEMBLY__
+typedef union {
+       s64 lock;
+       struct {
+               u32 read;
+               s32 write;
+       };
+} arch_rwlock_t;
+#endif
+
+#define RW_LOCK_BIAS           (_AC(1,L) << 32)
+#define READ_LOCK_SIZE(insn)   __ASM_FORM(insn##q)
+#define READ_LOCK_ATOMIC(n)    atomic64_##n
+#define WRITE_LOCK_ADD(n)      __ASM_FORM(incl)
+#define WRITE_LOCK_SUB(n)      __ASM_FORM(decl)
+#define WRITE_LOCK_CMP         1
+
+#endif /* CONFIG_NR_CPUS */
+
+#define __ARCH_RW_LOCK_UNLOCKED                { RW_LOCK_BIAS }
 
 /* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
 
 
 #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>
  */
 static inline int arch_read_can_lock(arch_rwlock_t *lock)
 {
-       return (int)(lock)->lock > 0;
+       return lock->lock > 0;
 }
 
 /**
  */
 static inline int arch_write_can_lock(arch_rwlock_t *lock)
 {
-       return (lock)->lock == RW_LOCK_BIAS;
+       return lock->write == WRITE_LOCK_CMP;
 }
 
 static inline void arch_read_lock(arch_rwlock_t *rw)
 {
-       asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
+       asm volatile(LOCK_PREFIX READ_LOCK_SIZE(dec) " (%0)\n\t"
                     "jns 1f\n"
                     "call __read_lock_failed\n\t"
                     "1:\n"
 
 static inline void arch_write_lock(arch_rwlock_t *rw)
 {
-       asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
+       asm volatile(LOCK_PREFIX WRITE_LOCK_SUB(%1) "(%0)\n\t"
                     "jz 1f\n"
                     "call __write_lock_failed\n\t"
                     "1:\n"
-                    ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
+                    ::LOCK_PTR_REG (&rw->write), "i" (RW_LOCK_BIAS)
+                    : "memory");
 }
 
 static inline int arch_read_trylock(arch_rwlock_t *lock)
 {
-       atomic_t *count = (atomic_t *)lock;
+       READ_LOCK_ATOMIC(t) *count = (READ_LOCK_ATOMIC(t) *)lock;
 
-       if (atomic_dec_return(count) >= 0)
+       if (READ_LOCK_ATOMIC(dec_return)(count) >= 0)
                return 1;
-       atomic_inc(count);
+       READ_LOCK_ATOMIC(inc)(count);
        return 0;
 }
 
 static inline int arch_write_trylock(arch_rwlock_t *lock)
 {
-       atomic_t *count = (atomic_t *)lock;
+       atomic_t *count = (atomic_t *)&lock->write;
 
-       if (atomic_sub_and_test(RW_LOCK_BIAS, count))
+       if (atomic_sub_and_test(WRITE_LOCK_CMP, count))
                return 1;
-       atomic_add(RW_LOCK_BIAS, count);
+       atomic_add(WRITE_LOCK_CMP, count);
        return 0;
 }
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
-       asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
+       asm volatile(LOCK_PREFIX READ_LOCK_SIZE(inc) " %0"
+                    :"+m" (rw->lock) : : "memory");
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
-       asm volatile(LOCK_PREFIX "addl %1, %0"
-                    : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
+       asm volatile(LOCK_PREFIX WRITE_LOCK_ADD(%1) "%0"
+                    : "+m" (rw->write) : "i" (RW_LOCK_BIAS) : "memory");
 }
 
 #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
+#undef READ_LOCK_SIZE
+#undef READ_LOCK_ATOMIC
+#undef WRITE_LOCK_ADD
+#undef WRITE_LOCK_SUB
+#undef WRITE_LOCK_CMP
+
 #define arch_spin_relax(lock)  cpu_relax()
 #define arch_read_relax(lock)  cpu_relax()
 #define arch_write_relax(lock) cpu_relax()
 
        CFI_STARTPROC
        FRAME
 0:     LOCK_PREFIX
-       addl    $RW_LOCK_BIAS, (%__lock_ptr)
+       WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr)
 1:     rep; nop
-       cmpl    $RW_LOCK_BIAS, (%__lock_ptr)
+       cmpl    $WRITE_LOCK_CMP, (%__lock_ptr)
        jne     1b
        LOCK_PREFIX
-       subl    $RW_LOCK_BIAS, (%__lock_ptr)
+       WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr)
        jnz     0b
        ENDFRAME
        ret
        CFI_STARTPROC
        FRAME
 0:     LOCK_PREFIX
-       incl    (%__lock_ptr)
+       READ_LOCK_SIZE(inc) (%__lock_ptr)
 1:     rep; nop
-       cmpl    $1, (%__lock_ptr)
+       READ_LOCK_SIZE(cmp) $1, (%__lock_ptr)
        js      1b
        LOCK_PREFIX
-       decl    (%__lock_ptr)
+       READ_LOCK_SIZE(dec) (%__lock_ptr)
        js      0b
        ENDFRAME
        ret