From: Linus Torvalds Date: Wed, 7 Jan 2009 19:56:29 +0000 (-0800) Subject: Merge git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=52fefcec97c25b15887e6a9a885ca54e7f7c0928;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git Merge git://git./linux/kernel/git/czankel/xtensa-2.6 * git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6: xtensa: Update platform files to reflect new location of the header files. xtensa: switch to packed struct unaligned access implementation xtensa: Add xt2000 support files. xtensa: move headers files to arch/xtensa/include xtensa: use the new byteorder headers --- 52fefcec97c25b15887e6a9a885ca54e7f7c0928 diff --cc arch/xtensa/include/asm/atomic.h index 000000000000,b3b23540f14d..67ad67bed8c1 mode 000000,100644..100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@@ -1,0 -1,300 +1,299 @@@ + /* + * include/asm-xtensa/atomic.h + * + * Atomic operations that C can't guarantee us. Useful for resource counting.. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + */ + + #ifndef _XTENSA_ATOMIC_H + #define _XTENSA_ATOMIC_H + + #include - -typedef struct { volatile int counter; } atomic_t; ++#include + + #ifdef __KERNEL__ + #include + #include + + #define ATOMIC_INIT(i) { (i) } + + /* + * This Xtensa implementation assumes that the right mechanism + * for exclusion is for locking interrupts to level 1. + * + * Locking interrupts looks like this: + * + * rsil a15, 1 + * + * wsr a15, PS + * rsync + * + * Note that a15 is used here because the register allocation + * done by the compiler is not guaranteed and a window overflow + * may not occur between the rsil and wsr instructions. By using + * a15 in the rsil, the machine is guaranteed to be in a state + * where no register reference will cause an overflow. + */ + + /** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. + */ + #define atomic_read(v) ((v)->counter) + + /** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. + */ + #define atomic_set(v,i) ((v)->counter = (i)) + + /** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. + */ + static inline void atomic_add(int i, atomic_t * v) + { + unsigned int vval; + + __asm__ __volatile__( + "rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "add %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + } + + /** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v. + */ + static inline void atomic_sub(int i, atomic_t *v) + { + unsigned int vval; + + __asm__ __volatile__( + "rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "sub %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + } + + /* + * We use atomic_{add|sub}_return to define other functions. + */ + + static inline int atomic_add_return(int i, atomic_t * v) + { + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "add %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; + } + + static inline int atomic_sub_return(int i, atomic_t * v) + { + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "sub %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; + } + + /** + * atomic_sub_and_test - subtract value from variable and test result + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v and returns + * true if the result is zero, or false for all + * other cases. + */ + #define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) + + /** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. + */ + #define atomic_inc(v) atomic_add(1,(v)) + + /** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. + */ + #define atomic_inc_return(v) atomic_add_return(1,(v)) + + /** + * atomic_dec - decrement atomic variable + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. + */ + #define atomic_dec(v) atomic_sub(1,(v)) + + /** + * atomic_dec_return - decrement atomic variable + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. + */ + #define atomic_dec_return(v) atomic_sub_return(1,(v)) + + /** + * atomic_dec_and_test - decrement and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. + */ + #define atomic_dec_and_test(v) (atomic_sub_return(1,(v)) == 0) + + /** + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ + #define atomic_inc_and_test(v) (atomic_add_return(1,(v)) == 0) + + /** + * atomic_add_negative - add and test if negative + * @v: pointer of type atomic_t + * @i: integer value to add + * + * Atomically adds @i to @v and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. + */ + #define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0) + + #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) + #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + + /** + * atomic_add_unless - add unless the number is a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as it was not @u. + * Returns non-zero if @v was not @u, and zero otherwise. + */ + static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) + { + int c, old; + c = atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + return c != (u); + } + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + + static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) + { + unsigned int all_f = -1; + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "xor %1, %4, %3 \n\t" + "and %0, %0, %4 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval), "=a" (mask) + : "a" (v), "a" (all_f), "1" (mask) + : "a15", "memory" + ); + } + + static inline void atomic_set_mask(unsigned int mask, atomic_t *v) + { + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "or %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, "__stringify(PS)" \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (mask), "a" (v) + : "a15", "memory" + ); + } + + /* Atomic operations are already serializing */ + #define smp_mb__before_atomic_dec() barrier() + #define smp_mb__after_atomic_dec() barrier() + #define smp_mb__before_atomic_inc() barrier() + #define smp_mb__after_atomic_inc() barrier() + + #include + #endif /* __KERNEL__ */ + + #endif /* _XTENSA_ATOMIC_H */ + diff --cc arch/xtensa/include/asm/bitops.h index 000000000000,23261e8f2e5a..6c3930397bd3 mode 000000,100644..100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@@ -1,0 -1,121 +1,132 @@@ + /* + * include/asm-xtensa/bitops.h + * + * Atomic operations that C can't guarantee us.Useful for resource counting etc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2007 Tensilica Inc. + */ + + #ifndef _XTENSA_BITOPS_H + #define _XTENSA_BITOPS_H + + #ifdef __KERNEL__ + + #ifndef _LINUX_BITOPS_H + #error only can be included directly + #endif + + #include + #include + #include + + #ifdef CONFIG_SMP + # error SMP not supported on this architecture + #endif + + #define smp_mb__before_clear_bit() barrier() + #define smp_mb__after_clear_bit() barrier() + + #include + #include + + #if XCHAL_HAVE_NSA + + static inline unsigned long __cntlz (unsigned long x) + { + int lz; + asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); + return lz; + } + + /* + * ffz: Find first zero in word. Undefined if no zero exists. + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + + static inline int ffz(unsigned long x) + { + return 31 - __cntlz(~x & -~x); + } + + /* + * __ffs: Find first bit set in word. Return 0 for bit 0 + */ + + static inline int __ffs(unsigned long x) + { + return 31 - __cntlz(x & -x); + } + + /* + * ffs: Find first bit set in word. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + + static inline int ffs(unsigned long x) + { + return 32 - __cntlz(x & -x); + } + + /* + * fls: Find last (most-significant) bit set in word. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ + + static inline int fls (unsigned int x) + { + return 32 - __cntlz(x); + } + ++/** ++ * __fls - find last (most-significant) set bit in a long word ++ * @word: the word to search ++ * ++ * Undefined if no set bit exists, so code should check against 0 first. ++ */ ++static inline unsigned long __fls(unsigned long word) ++{ ++ return 31 - __cntlz(word); ++} + #else + + /* Use the generic implementation if we don't have the nsa/nsau instructions. */ + + # include + # include + # include + # include ++# include + + #endif + + #include + #include + #include + + #ifdef __XTENSA_EL__ + # define ext2_set_bit_atomic(lock,nr,addr) \ + test_and_set_bit((nr), (unsigned long*)(addr)) + # define ext2_clear_bit_atomic(lock,nr,addr) \ + test_and_clear_bit((nr), (unsigned long*)(addr)) + #elif defined(__XTENSA_EB__) + # define ext2_set_bit_atomic(lock,nr,addr) \ + test_and_set_bit((nr) ^ 0x18, (unsigned long*)(addr)) + # define ext2_clear_bit_atomic(lock,nr,addr) \ + test_and_clear_bit((nr) ^ 0x18, (unsigned long*)(addr)) + #else + # error processor byte order undefined! + #endif + + #include + #include + #include + #include + + #endif /* __KERNEL__ */ + + #endif /* _XTENSA_BITOPS_H */