/*
 * Atomic operations that C can't guarantee us.  Useful for
 * resource counting etc.
 *
 * But use these as seldom as possible since they are slower than
 * regular operations.
 *
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef __ASM_AVR32_ATOMIC_H
#define __ASM_AVR32_ATOMIC_H

#include <linux/types.h>
#include <asm/system.h>

#define ATOMIC_INIT(i)  { (i) }

#define atomic_read(v)		(*(volatile int *)&(v)->counter)
#define atomic_set(v, i)	(((v)->counter) = i)

/*
 * atomic_sub_return - subtract the atomic variable
 * @i: integer value to subtract
 * @v: pointer of type atomic_t
 *
 * Atomically subtracts @i from @v. Returns the resulting value.
 */
static inline int atomic_sub_return(int i, atomic_t *v)
{
	int result;

	asm volatile(
		"/* atomic_sub_return */\n"
		"1:	ssrf	5\n"
		"	ld.w	%0, %2\n"
		"	sub	%0, %3\n"
		"	stcond	%1, %0\n"
		"	brne	1b"
		: "=&r"(result), "=o"(v->counter)
		: "m"(v->counter), "rKs21"(i)
		: "cc");

	return result;
}

/*
 * atomic_add_return - add integer to atomic variable
 * @i: integer value to add
 * @v: pointer of type atomic_t
 *
 * Atomically adds @i to @v. Returns the resulting value.
 */
static inline int atomic_add_return(int i, atomic_t *v)
{
	int result;

	if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
		result = atomic_sub_return(-i, v);
	else
		asm volatile(
			"/* atomic_add_return */\n"
			"1:	ssrf	5\n"
			"	ld.w	%0, %1\n"
			"	add	%0, %3\n"
			"	stcond	%2, %0\n"
			"	brne	1b"
			: "=&r"(result), "=o"(v->counter)
			: "m"(v->counter), "r"(i)
			: "cc", "memory");

	return result;
}

/*
 * atomic_sub_unless - sub unless the number is a given value
 * @v: pointer of type atomic_t
 * @a: the amount to subtract from v...
 * @u: ...unless v is equal to u.
 *
 * Atomically subtract @a from @v, so long as it was not @u.
 * Returns the old value of @v.
*/
static inline void atomic_sub_unless(atomic_t *v, int a, int u)
{
	int tmp;

	asm volatile(
		"/* atomic_sub_unless */\n"
		"1:	ssrf	5\n"
		"	ld.w	%0, %2\n"
		"	cp.w	%0, %4\n"
		"	breq	1f\n"
		"	sub	%0, %3\n"
		"	stcond	%1, %0\n"
		"	brne	1b\n"
		"1:"
		: "=&r"(tmp), "=o"(v->counter)
		: "m"(v->counter), "rKs21"(a), "rKs21"(u)
		: "cc", "memory");
}

/*
 * __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 the old value of @v.
*/
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
	int tmp, old = atomic_read(v);

	if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
		atomic_sub_unless(v, -a, u);
	else {
		asm volatile(
			"/* __atomic_add_unless */\n"
			"1:	ssrf	5\n"
			"	ld.w	%0, %2\n"
			"	cp.w	%0, %4\n"
			"	breq	1f\n"
			"	add	%0, %3\n"
			"	stcond	%1, %0\n"
			"	brne	1b\n"
			"1:"
			: "=&r"(tmp), "=o"(v->counter)
			: "m"(v->counter), "r"(a), "ir"(u)
			: "cc", "memory");
	}

	return old;
}

/*
 * atomic_sub_if_positive - conditionally subtract integer from atomic variable
 * @i: integer value to subtract
 * @v: pointer of type atomic_t
 *
 * Atomically test @v and subtract @i if @v is greater or equal than @i.
 * The function returns the old value of @v minus @i.
 */
static inline int atomic_sub_if_positive(int i, atomic_t *v)
{
	int result;

	asm volatile(
		"/* atomic_sub_if_positive */\n"
		"1:	ssrf	5\n"
		"	ld.w	%0, %2\n"
		"	sub	%0, %3\n"
		"	brlt	1f\n"
		"	stcond	%1, %0\n"
		"	brne	1b\n"
		"1:"
		: "=&r"(result), "=o"(v->counter)
		: "m"(v->counter), "ir"(i)
		: "cc", "memory");

	return result;
}

#define atomic_xchg(v, new)	(xchg(&((v)->counter), new))
#define atomic_cmpxchg(v, o, n)	(cmpxchg(&((v)->counter), (o), (n)))

#define atomic_sub(i, v)	(void)atomic_sub_return(i, v)
#define atomic_add(i, v)	(void)atomic_add_return(i, v)
#define atomic_dec(v)		atomic_sub(1, (v))
#define atomic_inc(v)		atomic_add(1, (v))

#define atomic_dec_return(v)	atomic_sub_return(1, v)
#define atomic_inc_return(v)	atomic_add_return(1, v)

#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
#define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0)

#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)

#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()

#endif /*  __ASM_AVR32_ATOMIC_H */
