diff --git a/configure.in b/configure.in
index 35fd89f..bb56eb6 100644
--- a/configure.in
+++ b/configure.in
@@ -309,40 +309,6 @@ fi
 
 AC_SUBST(ALSA_DEPLIBS)
 
-dnl Check for architecture
-AC_MSG_CHECKING(for architecture)
-case "$host" in
-i?86*)
-  AC_MSG_RESULT(x86)
-  ;;
-x86_64*)
-  AC_MSG_RESULT(x86)
-  ;;
-alpha*)
-  AC_MSG_RESULT(alpha)
-  ;;
-powerpc*|ppc*)
-  AC_MSG_RESULT(ppc)
-  CPPFLAGS="$CPPFLAGS -D__ppc__"
-  ;;
-ia64*)
-  AC_MSG_RESULT(ia64)
-  CPPFLAGS="$CPPFLAGS -D__ia64__"
-  ;;
-mips*)
-  AC_MSG_RESULT(mips)
-  CPPFLAGS="$CPPFLAGS -D__mips__"
-  ;;
-arm*)
-  AC_MSG_RESULT(arm)
-  CPPFLAGS="$CPPFLAGS -D__arm__"
-  ;;
-*)
-  AC_MSG_RESULT($host_cpu)
-  echo "No atomic operations supported.." 
-  ;;
-esac
-
 dnl Check for wordexp.h
 AC_CHECK_HEADERS([wordexp.h])
 
@@ -488,6 +454,21 @@ else
 pcm_plugins=""
 fi
 
+dnl check atomics for pcm_meter
+
+AC_MSG_CHECKING([whether GCC supports builtin atomic intrinsics])
+if test -z "$gcc_have_atomics"; then
+  gcc_have_atomics=no
+  AC_TRY_LINK([],
+    [int i;
+     __atomic_load_n(&i, __ATOMIC_SEQ_CST);
+     __atomic_add_fetch(&i, 0, __ATOMIC_SEQ_CST);
+    ],
+    [gcc_have_atomics=yes],
+    [gcc_have_atomics=no])
+fi
+AC_MSG_RESULT($gcc_have_atomics)
+
 PCM_PLUGIN_LIST="copy linear route mulaw alaw adpcm rate plug multi shm file null empty share meter hooks lfloat ladspa dmix dshare dsnoop asym iec958 softvol extplug ioplug mmap_emul"
 
 build_pcm_plugin="no"
@@ -531,6 +512,10 @@ if test "$softfloat" = "yes"; then
   build_pcm_ladspa="no"
 fi
 
+if test "$gcc_have_atomics" != "yes"; then
+  build_pcm_meter="no"
+fi
+
 AM_CONDITIONAL([BUILD_PCM_PLUGIN], [test x$build_pcm_plugin = xyes])
 AM_CONDITIONAL([BUILD_PCM_PLUGIN_COPY], [test x$build_pcm_copy = xyes])
 AM_CONDITIONAL([BUILD_PCM_PLUGIN_LINEAR], [test x$build_pcm_linear = xyes])
diff --git a/include/iatomic.h b/include/iatomic.h
index 2393297..acdd3e2 100644
--- a/include/iatomic.h
+++ b/include/iatomic.h
@@ -1,349 +1,21 @@
 #ifndef __ALSA_IATOMIC_H
 #define __ALSA_IATOMIC_H
 
-#if defined(__i386__) || defined(__x86_64__)
-
-/*
- * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
- */
-
-#define ATOMIC_SMP_LOCK "lock ; "
-
-/*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-/**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- * 
- * Atomically reads the value of @v.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-#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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-#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.  Note that the guaranteed useful range
- * of an atomic_t is only 24 bits.
- */
-static __inline__ void atomic_add(int i, atomic_t *v)
-{
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "addl %1,%0"
-		:"=m" (v->counter)
-		:"ir" (i), "m" (v->counter));
-}
-
-/**
- * atomic_sub - subtract the atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
- * 
- * Atomically subtracts @i from @v.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-static __inline__ void atomic_sub(int i, atomic_t *v)
-{
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "subl %1,%0"
-		:"=m" (v->counter)
-		:"ir" (i), "m" (v->counter));
-}
-
-/**
- * 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "subl %2,%0; sete %1"
-		:"=m" (v->counter), "=qm" (c)
-		:"ir" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- * 
- * Atomically increments @v by 1.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-static __inline__ void atomic_inc(atomic_t *v)
-{
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "incl %0"
-		:"=m" (v->counter)
-		:"m" (v->counter));
-}
-
-/**
- * atomic_dec - decrement atomic variable
- * @v: pointer of type atomic_t
- * 
- * Atomically decrements @v by 1.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-static __inline__ void atomic_dec(atomic_t *v)
-{
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "decl %0"
-		:"=m" (v->counter)
-		:"m" (v->counter));
-}
-
-/**
- * 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-static __inline__ int atomic_dec_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "decl %0; sete %1"
-		:"=m" (v->counter), "=qm" (c)
-		:"m" (v->counter) : "memory");
-	return c != 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-static __inline__ int atomic_inc_and_test(atomic_t *v)
-{
-	unsigned char c;
-
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "incl %0; sete %1"
-		:"=m" (v->counter), "=qm" (c)
-		:"m" (v->counter) : "memory");
-	return c != 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */ 
-static __inline__ int atomic_add_negative(int i, atomic_t *v)
-{
-	unsigned char c;
-
-	__asm__ __volatile__(
-		ATOMIC_SMP_LOCK "addl %2,%0; sets %1"
-		:"=m" (v->counter), "=qm" (c)
-		:"ir" (i), "m" (v->counter) : "memory");
-	return c;
-}
-
-/* These are x86-specific, used by some header files */
-#define atomic_clear_mask(mask, addr) \
-__asm__ __volatile__(ATOMIC_SMP_LOCK "andl %0,%1" \
-: : "r" (~(mask)),"m" (*addr) : "memory")
-
-#define atomic_set_mask(mask, addr) \
-__asm__ __volatile__(ATOMIC_SMP_LOCK "orl %0,%1" \
-: : "r" (mask),"m" (*addr) : "memory")
-
-/*
- * Force strict CPU ordering.
- * And yes, this is required on UP too when we're talking
- * to devices.
- *
- * For now, "wmb()" doesn't actually do anything, as all
- * Intel CPU's follow what Intel calls a *Processor Order*,
- * in which all writes are seen in the program order even
- * outside the CPU.
- *
- * I expect future Intel CPU's to have a weaker ordering,
- * but I'd also expect them to finally get their act together
- * and add some real memory barriers if so.
- */
- 
 #ifdef __i386__
 #define mb() 	__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
 #define rmb()	mb()
 #define wmb()	__asm__ __volatile__ ("": : :"memory")
-#else
+#define IATOMIC_DEFINED		1
+#endif 
+
+#ifdef __x86_64__
 #define mb() 	asm volatile("mfence":::"memory")
 #define rmb()	asm volatile("lfence":::"memory")
 #define wmb()	asm volatile("sfence":::"memory")
-#endif
-
-#undef ATOMIC_SMP_LOCK
-
 #define IATOMIC_DEFINED		1
-
-#endif /* __i386__ */
+#endif
 
 #ifdef __ia64__
-
-/*
- * On IA-64, counter must always be volatile to ensure that that the
- * memory accesses are ordered.
- */
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)		((atomic_t) { (i) })
-
-#define atomic_read(v)		((v)->counter)
-#define atomic_set(v,i)		(((v)->counter) = (i))
-
-/* stripped version - we need only 4byte version */
-#define ia64_cmpxchg(sem,ptr,old,new,size) \
-({ \
-	__typeof__(ptr) _p_ = (ptr); \
-	__typeof__(new) _n_ = (new); \
-	unsigned long _o_, _r_; \
-	_o_ = (unsigned int) (long) (old); \
-	__asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_)); \
-	__asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv" \
-			      : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \
-	(__typeof__(old)) _r_; \
-})
-
-static __inline__ int
-ia64_atomic_add (int i, atomic_t *v)
-{
-	int old, new;
-	// CMPXCHG_BUGCHECK_DECL
-
-	do {
-		// CMPXCHG_BUGCHECK(v);
-		old = atomic_read(v);
-		new = old + i;
-	} while (ia64_cmpxchg("acq", v, old, old + i, sizeof(atomic_t)) != old);
-	return new;
-}
-
-static __inline__ int
-ia64_atomic_sub (int i, atomic_t *v)
-{
-	int old, new;
-	// CMPXCHG_BUGCHECK_DECL
-
-	do {
-		// CMPXCHG_BUGCHECK(v);
-		old = atomic_read(v);
-		new = old - i;
-	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
-	return new;
-}
-
-#define IA64_FETCHADD(tmp,v,n,sz)						\
-({										\
-	switch (sz) {								\
-	      case 4:								\
-		__asm__ __volatile__ ("fetchadd4.rel %0=[%1],%2"		\
-				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
-		break;								\
-										\
-	      case 8:								\
-		__asm__ __volatile__ ("fetchadd8.rel %0=[%1],%2"		\
-				      : "=r"(tmp) : "r"(v), "i"(n) : "memory");	\
-		break;								\
-	}									\
-})
-
-#define ia64_fetch_and_add(i,v)							\
-({										\
-	unsigned long _tmp;								\
-	volatile __typeof__(*(v)) *_v = (v);					\
-	switch (i) {								\
-	      case -16:	IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v))); break;	\
-	      case  -8:	IA64_FETCHADD(_tmp, _v,  -8, sizeof(*(v))); break;	\
-	      case  -4:	IA64_FETCHADD(_tmp, _v,  -4, sizeof(*(v))); break;	\
-	      case  -1:	IA64_FETCHADD(_tmp, _v,  -1, sizeof(*(v))); break;	\
-	      case   1:	IA64_FETCHADD(_tmp, _v,   1, sizeof(*(v))); break;	\
-	      case   4:	IA64_FETCHADD(_tmp, _v,   4, sizeof(*(v))); break;	\
-	      case   8:	IA64_FETCHADD(_tmp, _v,   8, sizeof(*(v))); break;	\
-	      case  16:	IA64_FETCHADD(_tmp, _v,  16, sizeof(*(v))); break;	\
-	}									\
-	(__typeof__(*v)) (_tmp + (i));	/* return new value */			\
-})
-
-/*
- * Atomically add I to V and return TRUE if the resulting value is
- * negative.
- */
-static __inline__ int
-atomic_add_negative (int i, atomic_t *v)
-{
-	return ia64_atomic_add(i, v) < 0;
-}
-
-#define atomic_add_return(i,v)						\
-	((__builtin_constant_p(i) &&					\
-	  (   (i ==  1) || (i ==  4) || (i ==  8) || (i ==  16)		\
-	   || (i == -1) || (i == -4) || (i == -8) || (i == -16)))	\
-	 ? ia64_fetch_and_add(i, &(v)->counter)				\
-	 : ia64_atomic_add(i, v))
-
-#define atomic_sub_return(i,v)						\
-	((__builtin_constant_p(i) &&					\
-	  (   (i ==  1) || (i ==  4) || (i ==  8) || (i ==  16)		\
-	   || (i == -1) || (i == -4) || (i == -8) || (i == -16)))	\
-	 ? ia64_fetch_and_add(-(i), &(v)->counter)			\
-	 : ia64_atomic_sub(i, 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_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
-#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) != 0)
-
-#define atomic_add(i,v)			atomic_add_return((i), (v))
-#define atomic_sub(i,v)			atomic_sub_return((i), (v))
-#define atomic_inc(v)			atomic_add(1, (v))
-#define atomic_dec(v)			atomic_sub(1, (v))
-
 /*
  * Macros to force memory ordering.  In these descriptions, "previous"
  * and "subsequent" refer to program order; "visible" means that all
@@ -376,111 +48,6 @@ atomic_add_negative (int i, atomic_t *v)
 
 #ifdef __alpha__
 
-/*
- * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc...
- *
- * But use these as seldom as possible since they are much slower
- * than regular operations.
- */
-
-
-/*
- * Counter is volatile to make sure gcc doesn't try to be clever
- * and move things around on us. We need to use _exactly_ the address
- * the user gave us, not some alias that contains the same information.
- */
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	( (atomic_t) { (i) } )
-
-#define atomic_read(v)		((v)->counter)
-#define atomic_set(v,i)		((v)->counter = (i))
-
-/*
- * To get proper branch prediction for the main line, we must branch
- * forward to code at the end of this object's .text section, then
- * branch back to restart the operation.
- */
-
-static __inline__ void atomic_add(int i, atomic_t * v)
-{
-	unsigned long temp;
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%1\n"
-	"	addl %0,%2,%0\n"
-	"	stl_c %0,%1\n"
-	"	beq %0,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	:"=&r" (temp), "=m" (v->counter)
-	:"Ir" (i), "m" (v->counter));
-}
-
-static __inline__ void atomic_sub(int i, atomic_t * v)
-{
-	unsigned long temp;
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%1\n"
-	"	subl %0,%2,%0\n"
-	"	stl_c %0,%1\n"
-	"	beq %0,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	:"=&r" (temp), "=m" (v->counter)
-	:"Ir" (i), "m" (v->counter));
-}
-
-/*
- * Same as above, but return the result value
- */
-static __inline__ long atomic_add_return(int i, atomic_t * v)
-{
-	long temp, result;
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%1\n"
-	"	addl %0,%3,%2\n"
-	"	addl %0,%3,%0\n"
-	"	stl_c %0,%1\n"
-	"	beq %0,2f\n"
-	"	mb\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	:"=&r" (temp), "=m" (v->counter), "=&r" (result)
-	:"Ir" (i), "m" (v->counter) : "memory");
-	return result;
-}
-
-static __inline__ long atomic_sub_return(int i, atomic_t * v)
-{
-	long temp, result;
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%1\n"
-	"	subl %0,%3,%2\n"
-	"	subl %0,%3,%0\n"
-	"	stl_c %0,%1\n"
-	"	beq %0,2f\n"
-	"	mb\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	:"=&r" (temp), "=m" (v->counter), "=&r" (result)
-	:"Ir" (i), "m" (v->counter) : "memory");
-	return result;
-}
-
-#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_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
-
-#define atomic_inc(v) atomic_add(1,(v))
-#define atomic_dec(v) atomic_sub(1,(v))
-
 #define mb() \
 __asm__ __volatile__("mb": : :"memory")
 
@@ -496,168 +63,6 @@ __asm__ __volatile__("wmb": : :"memory")
 
 #ifdef __powerpc__
 
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-#define atomic_read(v)		((v)->counter)
-#define atomic_set(v,i)		(((v)->counter) = (i))
-
-extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
-extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
-
-#define SMP_ISYNC	"\n\tisync"
-
-static __inline__ void atomic_add(int a, atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%3		# atomic_add\n\
-	add	%0,%2,%0\n\
-	stwcx.	%0,0,%3\n\
-	bne-	1b"
-	: "=&r" (t), "=m" (v->counter)
-	: "r" (a), "r" (&v->counter), "m" (v->counter)
-	: "cc");
-}
-
-static __inline__ int atomic_add_return(int a, atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%2		# atomic_add_return\n\
-	add	%0,%1,%0\n\
-	stwcx.	%0,0,%2\n\
-	bne-	1b"
-	SMP_ISYNC
-	: "=&r" (t)
-	: "r" (a), "r" (&v->counter)
-	: "cc", "memory");
-
-	return t;
-}
-
-static __inline__ void atomic_sub(int a, atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%3		# atomic_sub\n\
-	subf	%0,%2,%0\n\
-	stwcx.	%0,0,%3\n\
-	bne-	1b"
-	: "=&r" (t), "=m" (v->counter)
-	: "r" (a), "r" (&v->counter), "m" (v->counter)
-	: "cc");
-}
-
-static __inline__ int atomic_sub_return(int a, atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%2		# atomic_sub_return\n\
-	subf	%0,%1,%0\n\
-	stwcx.	%0,0,%2\n\
-	bne-	1b"
-	SMP_ISYNC
-	: "=&r" (t)
-	: "r" (a), "r" (&v->counter)
-	: "cc", "memory");
-
-	return t;
-}
-
-static __inline__ void atomic_inc(atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%2		# atomic_inc\n\
-	addic	%0,%0,1\n\
-	stwcx.	%0,0,%2\n\
-	bne-	1b"
-	: "=&r" (t), "=m" (v->counter)
-	: "r" (&v->counter), "m" (v->counter)
-	: "cc");
-}
-
-static __inline__ int atomic_inc_return(atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%1		# atomic_inc_return\n\
-	addic	%0,%0,1\n\
-	stwcx.	%0,0,%1\n\
-	bne-	1b"
-	SMP_ISYNC
-	: "=&r" (t)
-	: "r" (&v->counter)
-	: "cc", "memory");
-
-	return t;
-}
-
-static __inline__ void atomic_dec(atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%2		# atomic_dec\n\
-	addic	%0,%0,-1\n\
-	stwcx.	%0,0,%2\n\
-	bne-	1b"
-	: "=&r" (t), "=m" (v->counter)
-	: "r" (&v->counter), "m" (v->counter)
-	: "cc");
-}
-
-static __inline__ int atomic_dec_return(atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%1		# atomic_dec_return\n\
-	addic	%0,%0,-1\n\
-	stwcx.	%0,0,%1\n\
-	bne-	1b"
-	SMP_ISYNC
-	: "=&r" (t)
-	: "r" (&v->counter)
-	: "cc", "memory");
-
-	return t;
-}
-
-#define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
-#define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
-
-/*
- * Atomically test *v and decrement if it is greater than 0.
- * The function returns the old value of *v minus 1.
- */
-static __inline__ int atomic_dec_if_positive(atomic_t *v)
-{
-	int t;
-
-	__asm__ __volatile__(
-"1:	lwarx	%0,0,%1		# atomic_dec_if_positive\n\
-	addic.	%0,%0,-1\n\
-	blt-	2f\n\
-	stwcx.	%0,0,%1\n\
-	bne-	1b"
-	SMP_ISYNC
-	"\n\
-2:"	: "=&r" (t)
-	: "r" (&v->counter)
-	: "cc", "memory");
-
-	return t;
-}
-
 /*
  * Memory barrier.
  * The sync instruction guarantees that all memory accesses initiated
@@ -682,447 +87,14 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
 
 #endif /* __powerpc__ */
 
-#ifdef __mips__
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)    { (i) }
-
-/*
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_set(v,i)	((v)->counter = (i))
-
-/*
- * for MIPS II and better we can use ll/sc instruction, and kernel 2.4.3+
- * will emulate it on MIPS I.
- */
-
-/*
- * atomic_add - add integer to atomic variable
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v.  Note that the guaranteed useful range
- * of an atomic_t is only 24 bits.
- */
-static __inline__ void atomic_add(int i, atomic_t * v)
-{
-	unsigned long temp;
-
-	__asm__ __volatile__(
-		".set push                            \n"
-		".set mips2                           \n"
-		"1:   ll      %0, %1      # atomic_add\n"
-		"     addu    %0, %2                  \n"
-		"     sc      %0, %1                  \n"
-		"     beqz    %0, 1b                  \n"
-		".set pop                             \n"
-		: "=&r" (temp), "=m" (v->counter)
-		: "Ir" (i), "m" (v->counter));
-}
-
-/*
- * atomic_sub - subtract the atomic variable
- * @i: integer value to subtract
- * @v: pointer of type atomic_t
- *
- * Atomically subtracts @i from @v.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-static __inline__ void atomic_sub(int i, atomic_t * v)
-{
-	unsigned long temp;
-
-	__asm__ __volatile__(
-		".set push                            \n"
-		".set mips2                           \n"
-		"1:   ll      %0, %1      # atomic_sub\n"
-		"     subu    %0, %2                  \n"
-		"     sc      %0, %1                  \n"
-		"     beqz    %0, 1b                  \n"
-		".set pop                             \n"
-		: "=&r" (temp), "=m" (v->counter)
-		: "Ir" (i), "m" (v->counter));
-}
-
-/*
- * Same as above, but return the result value
- */
-static __inline__ int atomic_add_return(int i, atomic_t * v)
-{
-	unsigned long temp, result;
-
-	__asm__ __volatile__(
-		".set push               # atomic_add_return\n"
-		".set noreorder                             \n"
-		".set mips2                                 \n"
-		"1:   ll      %1, %2                        \n"
-		"     addu    %0, %1, %3                    \n"
-		"     sc      %0, %2                        \n"
-		"     beqz    %0, 1b                        \n"
-		"     addu    %0, %1, %3                    \n"
-		".set pop                                   \n"
-		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
-		: "Ir" (i), "m" (v->counter)
-		: "memory");
-
-	return result;
-}
-
-static __inline__ int atomic_sub_return(int i, atomic_t * v)
-{
-	unsigned long temp, result;
-
-	__asm__ __volatile__(
-		".set push                                   \n"
-		".set mips2                                  \n"
-		".set noreorder           # atomic_sub_return\n"
-		"1:   ll    %1, %2                           \n"
-		"     subu  %0, %1, %3                       \n"
-		"     sc    %0, %2                           \n"
-		"     beqz  %0, 1b                           \n"
-		"     subu  %0, %1, %3                       \n"
-		".set pop                                    \n"
-		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
-		: "Ir" (i), "m" (v->counter)
-		: "memory");
-
-	return result;
-}
-
-#define atomic_dec_return(v) atomic_sub_return(1,(v))
-#define atomic_inc_return(v) atomic_add_return(1,(v))
-
-/*
- * 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(1, (v)) == 0)
-
-/*
- * atomic_dec_and_test - decrement by 1 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
-
-/*
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_inc(v) atomic_add(1,(v))
-
-/*
- * atomic_dec - decrement and test
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- */
-#define atomic_dec(v) atomic_sub(1,(v))
-
-/*
- * 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.  Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
- *
- * Currently not implemented for MIPS.
- */
-
-#define mb()						\
-__asm__ __volatile__(					\
-	"# prevent instructions being moved around\n\t"	\
-	".set\tnoreorder\n\t"				\
-	"# 8 nops to fool the R4400 pipeline\n\t"	\
-	"nop;nop;nop;nop;nop;nop;nop;nop\n\t"		\
-	".set\treorder"					\
-	: /* no output */				\
-	: /* no input */				\
-	: "memory")
-#define rmb() mb()
-#define wmb() mb()
-
-#define IATOMIC_DEFINED		1
-
-#endif /* __mips__ */
-
-#ifdef __arm__
-
-/*
- * FIXME: bellow code is valid only for SA11xx
- */
-
-/*
- * Save the current interrupt enable state & disable IRQs
- */
-#define local_irq_save(x)					\
-	({							\
-		unsigned long temp;				\
-	__asm__ __volatile__(					\
-	"mrs	%0, cpsr		@ local_irq_save\n"	\
-"	orr	%1, %0, #128\n"					\
-"	msr	cpsr_c, %1"					\
-	: "=r" (x), "=r" (temp)					\
-	:							\
-	: "memory");						\
-	})
-
-/*
- * restore saved IRQ & FIQ state
- */
-#define local_irq_restore(x)					\
-	__asm__ __volatile__(					\
-	"msr	cpsr_c, %0		@ local_irq_restore\n"	\
-	:							\
-	: "r" (x)						\
-	: "memory")
-
-#define __save_flags_cli(x) local_irq_save(x)
-#define __restore_flags(x) local_irq_restore(x)
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-#define atomic_read(v)	((v)->counter)
-#define atomic_set(v,i)	(((v)->counter) = (i))
-
-static __inline__ void atomic_add(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	__save_flags_cli(flags);
-	v->counter += i;
-	__restore_flags(flags);
-}
-
-static __inline__ void atomic_sub(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	__save_flags_cli(flags);
-	v->counter -= i;
-	__restore_flags(flags);
-}
-
-static __inline__ void atomic_inc(volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	__save_flags_cli(flags);
-	v->counter += 1;
-	__restore_flags(flags);
-}
-
-static __inline__ void atomic_dec(volatile atomic_t *v)
-{
-	unsigned long flags;
-
-	__save_flags_cli(flags);
-	v->counter -= 1;
-	__restore_flags(flags);
-}
-
-static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
-{
-	unsigned long flags;
-	int result;
-
-	__save_flags_cli(flags);
-	v->counter -= 1;
-	result = (v->counter == 0);
-	__restore_flags(flags);
-
-	return result;
-}
-
-static __inline__ int atomic_add_negative(int i, volatile atomic_t *v)
-{
-	unsigned long flags;
-	int result;
-
-	__save_flags_cli(flags);
-	v->counter += i;
-	result = (v->counter < 0);
-	__restore_flags(flags);
-
-	return result;
-}
-
-static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr)
-{
-	unsigned long flags;
-
-	__save_flags_cli(flags);
-	*addr &= ~mask;
-	__restore_flags(flags);
-}
-
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-
-#define IATOMIC_DEFINED		1
-
-#endif /* __arm__ */
-
-#ifdef __sh__
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-#define atomic_read(v)			((v)->counter)
-#define atomic_set(v,i)			(((v)->counter) = (i))
-
-#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_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
-#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) != 0)
-
-#define atomic_add(i,v)			atomic_add_return((i),(v))
-#define atomic_sub(i,v)			atomic_sub_return((i),(v))
-#define atomic_inc(v)			atomic_add(1,(v))
-#define atomic_dec(v)			atomic_sub(1,(v))
-
-static __inline__ int atomic_add_return(int i, volatile atomic_t *v)
-{
-	int result;
-
-	asm volatile (
-	"	.align	2\n"
-	"	mova	99f, r0\n"
-	"	mov	r15, r1\n"
-	"	mov	#-6, r15\n"
-	"	mov.l	@%2, %0\n"
-	"	add	%1, %0\n"
-	"	mov.l	%0, @%2\n"
-	"99:	mov	r1, r15"
-	: "=&r"(result)
-	: "r"(i), "r"(v)
-	: "r0", "r1");
-
-	return result;
-}
-
-static __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
-{
-	int result;
-
-	asm volatile (
-	"	.align	2\n"
-	"	mova	99f, r0\n"
-	"	mov	r15, r1\n"
-	"	mov	#-6, r15\n"
-	"	mov.l	@%2, %0\n"
-	"	sub	%1, %0\n"
-	"	mov.l	%0, @%2\n"
-	"99:	mov	r1, r15"
-	: "=&r"(result)
-	: "r"(i), "r"(v)
-	: "r0", "r1");
-
-	return result;
-}
-
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-
-#define IATOMIC_DEFINED		1
-
-#endif /* __sh__ */
-
-#ifdef __bfin__
-
-#include <bfin_fixed_code.h>
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)   { (i) }
+#ifndef IATOMIC_DEFINED
 
-#define atomic_read(v)   ((v)->counter)
-#define atomic_set(v,i)  (((v)->counter) = (i))
-#define atomic_add(i,v)  bfin_atomic_add32(&(v)->counter, i)
-#define atomic_sub(i,v)  bfin_atomic_sub32(&(v)->counter, i)
-#define atomic_inc(v)    bfin_atomic_inc32(&(v)->counter);
-#define atomic_dec(v)    bfin_atomic_dec32(&(v)->counter);
+/* Generic __sync_synchronize is available from gcc 4.1 */
 
-#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define mb() __sync_synchronize()
 #define rmb() mb()
 #define wmb() mb()
 
-#define IATOMIC_DEFINED 1
-
-#endif /* __bfin__ */
-
-#ifndef IATOMIC_DEFINED
-/*
- * non supported architecture.
- */
-#warning "Atomic operations are not supported on this architecture."
-
-typedef struct { volatile int counter; } atomic_t;
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-#define atomic_read(v)	((v)->counter)
-#define atomic_set(v,i)	(((v)->counter) = (i))
-#define atomic_add(i,v) (((v)->counter) += (i))
-#define atomic_sub(i,v) (((v)->counter) -= (i))
-#define atomic_inc(v)   (((v)->counter)++)
-#define atomic_dec(v)   (((v)->counter)--)
-
-#define mb()
-#define rmb()
-#define wmb()
-
 #define IATOMIC_DEFINED		1
 
 #endif /* IATOMIC_DEFINED */
diff --git a/src/pcm/pcm_meter.c b/src/pcm/pcm_meter.c
index 573b6fe..676fbef 100644
--- a/src/pcm/pcm_meter.c
+++ b/src/pcm/pcm_meter.c
@@ -33,7 +33,10 @@
 #include <dlfcn.h>
 #include "pcm_local.h"
 #include "pcm_plugin.h"
-#include "iatomic.h"
+
+#define atomic_read(ptr)    __atomic_load_n(ptr, __ATOMIC_SEQ_CST )
+#define atomic_add(ptr, n)  __atomic_add_fetch(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_dec(ptr)     __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
 
 #ifndef PIC
 /* entry for static linking */
@@ -61,7 +64,7 @@ typedef struct _snd_pcm_meter {
 	struct list_head scopes;
 	int closed;
 	int running;
-	atomic_t reset;
+	int reset;
 	pthread_t thread;
 	pthread_mutex_t update_mutex;
 	pthread_mutex_t running_mutex;
@@ -288,7 +291,7 @@ static int snd_pcm_meter_prepare(snd_pcm_t *pcm)
 {
 	snd_pcm_meter_t *meter = pcm->private_data;
 	int err;
-	atomic_inc(&meter->reset);
+	atomic_add(&meter->reset, 1);
 	err = snd_pcm_prepare(meter->gen.slave);
 	if (err >= 0) {
 		if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
