[ubicom32] remove target
[openwrt/svn-archive/archive.git] / target / linux / ubicom32 / files / arch / ubicom32 / include / asm / atomic.h
diff --git a/target/linux/ubicom32/files/arch/ubicom32/include/asm/atomic.h b/target/linux/ubicom32/files/arch/ubicom32/include/asm/atomic.h
deleted file mode 100644 (file)
index aaf7726..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * arch/ubicom32/include/asm/atomic.h
- *   Atomic operations definitions for Ubicom32 architecture.
- *
- * (C) Copyright 2009, Ubicom, Inc.
- *
- * This file is part of the Ubicom32 Linux Kernel Port.
- *
- * The Ubicom32 Linux Kernel Port is free software: you can redistribute
- * it and/or modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 2 of the
- * License, or (at your option) any later version.
- *
- * The Ubicom32 Linux Kernel Port is distributed in the hope that it
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Ubicom32 Linux Kernel Port.  If not,
- * see <http://www.gnu.org/licenses/>.
- *
- * Ubicom32 implementation derived from (with many thanks):
- *   arch/m68knommu
- *   arch/blackfin
- *   arch/parisc
- */
-#ifndef _ASM_UBICOM32_ATOMIC_H
-#define _ASM_UBICOM32_ATOMIC_H
-
-#include <asm/system.h>
-#include <asm/ubicom32-common.h>
-#include <asm/types.h>
-
-/*
- * Most instructions on the Ubicom32 processor are atomic in that they
- * execute in one clock cycle.  However, Linux has several operations
- * (e.g. compare and swap) which will require more than a single instruction
- * to perform.   To achieve this, the Ubicom32 processor uses a single
- * global bit in a scratchpad register as a critical section lock. All
- * atomic operations acquire this lock.
- *
- * NOTE: To AVOID DEADLOCK(s), the atomic lock must only be used for atomic
- * operations or by the ldsr to avoid disabling a thread performing an atomic
- * operation.
- *
- * Do not attempt to disable interrupts while holding the atomic operations
- * lock or you will DEADLOCK the system.
- */
-
-#define ATOMIC_INIT(i) { (i) }
-
-/*
- * __atomic_add()
- *     Add i to v and return the result.
- */
-static inline void __atomic_add(int i, atomic_t *v)
-{
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       vt->counter += i;
-       __atomic_lock_release();
-}
-
-/*
- * __atomic_sub()
- *     Subtract i from v and return the result.
- */
-static inline void __atomic_sub(int i, atomic_t *v)
-{
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       vt->counter -= i;
-       __atomic_lock_release();
-}
-
-/*
- * __atomic_add_return()
- *     Add i to v and return the result.
- *
- * The implementation here looks rather odd because we appear to be doing
- * the addition twice.  In fact that's exactly what we're doing but with
- * the ubicom32 instruction set we can do the inner load and add with two
- * instructions whereas generating both the atomic result and the "ret"
- * result requires three instructions.  The second add is generally only as
- * costly as a move instruction and in cases where we compare the result
- * with a constant the compiler can fold two constant values and do a
- * single instruction, thus saving an instruction overall!
- *
- * At the worst we save one instruction inside the atomic lock.
- */
-static inline int __atomic_add_return(int i, atomic_t *v)
-{
-       int ret;
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       ret = vt->counter;
-       vt->counter = ret + i;
-       __atomic_lock_release();
-
-       return ret + i;
-}
-
-/*
- * __atomic_sub_return()
- *     Subtract i from v and return the result.
- *
- * The implementation here looks rather odd because we appear to be doing
- * the subtraction twice.  In fact that's exactly what we're doing but with
- * the ubicom32 instruction set we can do the inner load and sub with two
- * instructions whereas generating both the atomic result and the "ret"
- * result requires three instructions.  The second sub is generally only as
- * costly as a move instruction and in cases where we compare the result
- * with a constant the compiler can fold two constant values and do a
- * single instruction, thus saving an instruction overall!
- *
- * At the worst we save one instruction inside the atomic lock.
- */
-static inline int __atomic_sub_return(int i, atomic_t *v)
-{
-       int ret;
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       ret = vt->counter;
-       vt->counter = ret - i;
-       __atomic_lock_release();
-
-       return ret - i;
-}
-
-/*
- * PUBLIC API FOR ATOMIC!
- */
-#define atomic_add(i,v)        (__atomic_add( ((int)i),(v)))
-#define atomic_sub(i,v)        (__atomic_sub( ((int)i),(v)))
-#define atomic_inc(v)  (__atomic_add(   1,(v)))
-#define atomic_dec(v)  (__atomic_sub(   1,(v)))
-#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v)))
-#define atomic_sub_return(i,v) (__atomic_sub_return( ((int)i),(v)))
-#define atomic_inc_return(v)   (__atomic_add_return(   1,(v)))
-#define atomic_dec_return(v)   (__atomic_sub_return(   1,(v)))
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
-#define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
-#define atomic_sub_and_test(i,v)       (atomic_sub_return((i),(v)) == 0)
-
-/*
- * atomic_read()
- *     Acquire the atomic lock and read the variable.
- */
-static inline int atomic_read(const atomic_t *v)
-{
-       int ret;
-       const atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       ret = vt->counter;
-       __atomic_lock_release();
-
-       return ret;
-}
-
-/*
- * atomic_set()
- *     Acquire the atomic lock and set the variable.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       vt->counter = i;
-       __atomic_lock_release();
-}
-
-/*
- * atomic_cmpxchg
- *     Acquire the atomic lock and exchange if current == old.
- */
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-       int prev;
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       prev = vt->counter;
-       if (prev == old) {
-               vt->counter = new;
-       }
-       __atomic_lock_release();
-
-       return prev;
-}
-
-/*
- * atomic_xchg()
- *     Acquire the atomic lock and exchange values.
- */
-static inline int atomic_xchg(atomic_t *v, int new)
-{
-       int prev;
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       prev = vt->counter;
-       vt->counter = new;
-       __atomic_lock_release();
-
-       return prev;
-}
-
-/*
- * atomic_add_unless()
- *     Acquire the atomic lock and add a unless the value is u.
- */
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
-       int prev;
-       atomic_t *vt = v;
-
-       __atomic_lock_acquire();
-       prev = vt->counter;
-       if (prev != u) {
-               vt->counter += a;
-               __atomic_lock_release();
-               return 1;
-       }
-
-       __atomic_lock_release();
-       return 0;
-}
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
-#include <asm-generic/atomic-long.h>
-#else
-#include <asm-generic/atomic.h>
-#endif
-
-/*
- * The following is not a real function.  The compiler should remove the function
- * call as long as the user does not pass in a size that __xchg and __cmpxchg
- * are not prepared for.  If the user does pass in an unknown size, the user
- * will get a link time error.
- *
- * The no return is to prevent a compiler error that can occur when dealing with
- * uninitialized variables. Given that the function doesn't exist there is no
- * net effect (and if it did it would not return).
- */
-extern void __xchg_called_with_bad_pointer(void) __attribute__((noreturn));
-
-/*
- * __xchg()
- *     Xchange *ptr for x atomically.
- *
- * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
- * atomic exchange instruction so we use the global atomic_lock.
- */
-static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
-{
-       unsigned long ret;
-
-       __atomic_lock_acquire();
-
-       switch (size) {
-       case 1:
-               ret = *(volatile unsigned char *)ptr;
-               *(volatile unsigned char *)ptr = x;
-               break;
-
-       case 2:
-               ret = *(volatile unsigned short *)ptr;
-               *(volatile unsigned short *)ptr = x;
-               break;
-
-       case 4:
-               ret = *(volatile unsigned int *)ptr;
-               *(volatile unsigned int *)ptr = x;
-               break;
-
-       default:
-               __xchg_called_with_bad_pointer();
-               break;
-       }
-       __atomic_lock_release();
-       return ret;
-}
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
-/*
- * __cmpxchg()
- *     Compare and Xchange *ptr for x atomically.
- *
- * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
- * atomic exchange instruction so we use the global atomic_lock.
- */
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long next, int size)
-{
-       unsigned long prev;
-
-       __atomic_lock_acquire();
-       switch (size) {
-       case 1:
-               prev = *(u8 *)ptr;
-               if (prev == old) {
-                       *(u8 *)ptr = (u8)next;
-               }
-               break;
-
-       case 2:
-               prev = *(u16 *)ptr;
-               if (prev == old) {
-                       *(u16 *)ptr = (u16)next;
-               }
-               break;
-
-       case 4:
-               prev = *(u32 *)ptr;
-               if (prev == old) {
-                       *(u32 *)ptr = (u32)next;
-               }
-               break;
-
-       default:
-               __xchg_called_with_bad_pointer();
-               break;
-       }
-       __atomic_lock_release();
-       return prev;
-}
-
-/*
- * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
- * them available.
- */
-#define cmpxchg_local(ptr, o, n) \
-       ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
-
-#define cmpxchg(ptr, o, n) __cmpxchg((ptr), (o), (n), sizeof(*(ptr)))
-
-#define smp_mb__before_atomic_inc() asm volatile ("" : : : "memory")
-#define smp_mb__after_atomic_inc() asm volatile ("" : : : "memory")
-#define smp_mb__before_atomic_dec() asm volatile ("" : : : "memory")
-#define smp_mb__after_atomic_dec() asm volatile ("" : : : "memory")
-
-#endif /* _ASM_UBICOM32_ATOMIC_H */