diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h index d2d11b7..989595d 100644 --- a/arch/parisc/include/asm/ldcw.h +++ b/arch/parisc/include/asm/ldcw.h @@ -1,6 +1,8 @@ #ifndef __PARISC_LDCW_H #define __PARISC_LDCW_H +#include + #ifndef CONFIG_PA20 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, and GCC only guarantees 8-byte alignment for stack locals, we can't @@ -34,12 +36,22 @@ #endif /*!CONFIG_PA20*/ /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ -#define __ldcw(a) ({ \ - unsigned __ret; \ - __asm__ __volatile__(__LDCW " 0(%2),%0" \ - : "=r" (__ret), "+m" (*(a)) : "r" (a)); \ - __ret; \ -}) +static inline unsigned int __ldcw(volatile unsigned int *address) +{ +#if GCC_VERSION >= 40900 + /* work around gcc-4.9 bug: + * error: can't find a register in class 'R1_REGS' while reloading 'asm' + */ + __asm__ __volatile__(__LDCW " 0(%0),%0" + : "=r" (address), "+m" (*(address)) : "0" (address)); + return (unsigned long) address; +#else + unsigned int val; + __asm__ __volatile__(__LDCW " 0(%2),%0" + : "=r" (val), "+m" (*(address)) : "r" (address)); + return val; +#endif +} #ifdef CONFIG_SMP # define __lock_aligned __attribute__((__section__(".data..lock_aligned")))