summaryrefslogtreecommitdiff
path: root/arch/m68k
diff options
context:
space:
mode:
authorAngelo Dureghello <angelo@sysam.it>2018-08-04 23:02:56 +0200
committerAngelo Dureghello <angelo@sysam.it>2018-09-16 00:01:13 +0200
commitfaae49543a0b366087cb733c26f8c581b17abe82 (patch)
treed695c1badfaa25d5332f51bae7509980c4b5a1d1 /arch/m68k
parenta1ed3a83be63bfc6e817854b29c9c0572a86bea7 (diff)
m68k: fix multiple memory accesses on swap operations
On a u32 val = __sw32(*addr); multiple memory accesses are not welcome, since "addr" may be an IO peripheral register address. This patch changes __sw16/32 to perform a single memory access for the source value. Signed-off-by: Angelo Dureghello <angelo@sysam.it>
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/include/asm/byteorder.h34
1 files changed, 20 insertions, 14 deletions
diff --git a/arch/m68k/include/asm/byteorder.h b/arch/m68k/include/asm/byteorder.h
index eb03b6a053..9179622250 100644
--- a/arch/m68k/include/asm/byteorder.h
+++ b/arch/m68k/include/asm/byteorder.h
@@ -10,21 +10,28 @@
#include <asm/types.h>
#ifdef __GNUC__
-#define __sw16(x) \
- ((__u16)( \
- (((__u16)(x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(x) & (__u16)0xff00U) >> 8) ))
-#define __sw32(x) \
- ((__u32)( \
- (((__u32)(x)) << 24) | \
- (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(x)) >> 24) ))
+
+static inline __u32 __sw32(__u32 x)
+{
+ __u32 v = x;
+
+ return v << 24 |
+ (v & (__u32)0x0000ff00UL) << 8 |
+ (v & (__u32)0x00ff0000UL) >> 8 |
+ v >> 24;
+}
+
+static inline __u16 __sw16(__u16 x)
+{
+ __u16 v = x;
+
+ return (v & (__u16)0x00ffU) << 8 |
+ (v & (__u16)0xff00U) >> 8;
+}
static __inline__ unsigned ld_le16(const volatile unsigned short *addr)
{
- unsigned result = *addr;
- return __sw16(result);
+ return __sw16(*addr);
}
static __inline__ void st_le16(volatile unsigned short *addr,
@@ -35,8 +42,7 @@ static __inline__ void st_le16(volatile unsigned short *addr,
static __inline__ unsigned ld_le32(const volatile unsigned *addr)
{
- unsigned result = *addr;
- return __sw32(result);
+ return __sw32(*addr);
}
static __inline__ void st_le32(volatile unsigned *addr, const unsigned val)