|
@@ -27,85 +27,56 @@ static inline int atomic_read(const atomic_t *v)
|
|
return temp;
|
|
return temp;
|
|
}
|
|
}
|
|
|
|
|
|
-static inline void atomic_add(int i, atomic_t *v)
|
|
|
|
-{
|
|
|
|
- int temp;
|
|
|
|
-
|
|
|
|
- asm volatile (
|
|
|
|
- "1: LNKGETD %0, [%1]\n"
|
|
|
|
- " ADD %0, %0, %2\n"
|
|
|
|
- " LNKSETD [%1], %0\n"
|
|
|
|
- " DEFR %0, TXSTAT\n"
|
|
|
|
- " ANDT %0, %0, #HI(0x3f000000)\n"
|
|
|
|
- " CMPT %0, #HI(0x02000000)\n"
|
|
|
|
- " BNZ 1b\n"
|
|
|
|
- : "=&d" (temp)
|
|
|
|
- : "da" (&v->counter), "bd" (i)
|
|
|
|
- : "cc");
|
|
|
|
|
|
+#define ATOMIC_OP(op) \
|
|
|
|
+static inline void atomic_##op(int i, atomic_t *v) \
|
|
|
|
+{ \
|
|
|
|
+ int temp; \
|
|
|
|
+ \
|
|
|
|
+ asm volatile ( \
|
|
|
|
+ "1: LNKGETD %0, [%1]\n" \
|
|
|
|
+ " " #op " %0, %0, %2\n" \
|
|
|
|
+ " LNKSETD [%1], %0\n" \
|
|
|
|
+ " DEFR %0, TXSTAT\n" \
|
|
|
|
+ " ANDT %0, %0, #HI(0x3f000000)\n" \
|
|
|
|
+ " CMPT %0, #HI(0x02000000)\n" \
|
|
|
|
+ " BNZ 1b\n" \
|
|
|
|
+ : "=&d" (temp) \
|
|
|
|
+ : "da" (&v->counter), "bd" (i) \
|
|
|
|
+ : "cc"); \
|
|
|
|
+} \
|
|
|
|
+
|
|
|
|
+#define ATOMIC_OP_RETURN(op) \
|
|
|
|
+static inline int atomic_##op##_return(int i, atomic_t *v) \
|
|
|
|
+{ \
|
|
|
|
+ int result, temp; \
|
|
|
|
+ \
|
|
|
|
+ smp_mb(); \
|
|
|
|
+ \
|
|
|
|
+ asm volatile ( \
|
|
|
|
+ "1: LNKGETD %1, [%2]\n" \
|
|
|
|
+ " " #op " %1, %1, %3\n" \
|
|
|
|
+ " LNKSETD [%2], %1\n" \
|
|
|
|
+ " DEFR %0, TXSTAT\n" \
|
|
|
|
+ " ANDT %0, %0, #HI(0x3f000000)\n" \
|
|
|
|
+ " CMPT %0, #HI(0x02000000)\n" \
|
|
|
|
+ " BNZ 1b\n" \
|
|
|
|
+ : "=&d" (temp), "=&da" (result) \
|
|
|
|
+ : "da" (&v->counter), "bd" (i) \
|
|
|
|
+ : "cc"); \
|
|
|
|
+ \
|
|
|
|
+ smp_mb(); \
|
|
|
|
+ \
|
|
|
|
+ return result; \
|
|
}
|
|
}
|
|
|
|
|
|
-static inline void atomic_sub(int i, atomic_t *v)
|
|
|
|
-{
|
|
|
|
- int temp;
|
|
|
|
|
|
+#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
|
|
|
|
|
|
- asm volatile (
|
|
|
|
- "1: LNKGETD %0, [%1]\n"
|
|
|
|
- " SUB %0, %0, %2\n"
|
|
|
|
- " LNKSETD [%1], %0\n"
|
|
|
|
- " DEFR %0, TXSTAT\n"
|
|
|
|
- " ANDT %0, %0, #HI(0x3f000000)\n"
|
|
|
|
- " CMPT %0, #HI(0x02000000)\n"
|
|
|
|
- " BNZ 1b\n"
|
|
|
|
- : "=&d" (temp)
|
|
|
|
- : "da" (&v->counter), "bd" (i)
|
|
|
|
- : "cc");
|
|
|
|
-}
|
|
|
|
|
|
+ATOMIC_OPS(add)
|
|
|
|
+ATOMIC_OPS(sub)
|
|
|
|
|
|
-static inline int atomic_add_return(int i, atomic_t *v)
|
|
|
|
-{
|
|
|
|
- int result, temp;
|
|
|
|
-
|
|
|
|
- smp_mb();
|
|
|
|
-
|
|
|
|
- asm volatile (
|
|
|
|
- "1: LNKGETD %1, [%2]\n"
|
|
|
|
- " ADD %1, %1, %3\n"
|
|
|
|
- " LNKSETD [%2], %1\n"
|
|
|
|
- " DEFR %0, TXSTAT\n"
|
|
|
|
- " ANDT %0, %0, #HI(0x3f000000)\n"
|
|
|
|
- " CMPT %0, #HI(0x02000000)\n"
|
|
|
|
- " BNZ 1b\n"
|
|
|
|
- : "=&d" (temp), "=&da" (result)
|
|
|
|
- : "da" (&v->counter), "bd" (i)
|
|
|
|
- : "cc");
|
|
|
|
-
|
|
|
|
- smp_mb();
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static inline int atomic_sub_return(int i, atomic_t *v)
|
|
|
|
-{
|
|
|
|
- int result, temp;
|
|
|
|
-
|
|
|
|
- smp_mb();
|
|
|
|
-
|
|
|
|
- asm volatile (
|
|
|
|
- "1: LNKGETD %1, [%2]\n"
|
|
|
|
- " SUB %1, %1, %3\n"
|
|
|
|
- " LNKSETD [%2], %1\n"
|
|
|
|
- " DEFR %0, TXSTAT\n"
|
|
|
|
- " ANDT %0, %0, #HI(0x3f000000)\n"
|
|
|
|
- " CMPT %0, #HI(0x02000000)\n"
|
|
|
|
- " BNZ 1b\n"
|
|
|
|
- : "=&d" (temp), "=&da" (result)
|
|
|
|
- : "da" (&v->counter), "bd" (i)
|
|
|
|
- : "cc");
|
|
|
|
-
|
|
|
|
- smp_mb();
|
|
|
|
-
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
|
|
+#undef ATOMIC_OPS
|
|
|
|
+#undef ATOMIC_OP_RETURN
|
|
|
|
+#undef ATOMIC_OP
|
|
|
|
|
|
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
|
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
|
{
|
|
{
|