[ARM] 3849/1: fix get_unaligned() for gcc >= 4.1

gcc 4.1's __typeof__ propagates 'const', which breaks get_unaligned().
Rewrite get_unaligned() not to use __typeof__.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h
index 1b39c2f..795b9e5 100644
--- a/include/asm-arm/unaligned.h
+++ b/include/asm-arm/unaligned.h
@@ -3,7 +3,7 @@
 
 #include <asm/types.h>
 
-extern int __bug_unaligned_x(void *ptr);
+extern int __bug_unaligned_x(const void *ptr);
 
 /*
  * What is the most efficient way of loading/storing an unaligned value?
@@ -51,44 +51,32 @@
 #define __get_unaligned_4_be(__p)					\
 	(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
 
-#define __get_unaligned_le(ptr)					\
-	({							\
-		__typeof__(*(ptr)) __v;				\
-		__u8 *__p = (__u8 *)(ptr);			\
-		switch (sizeof(*(ptr))) {			\
-		case 1:	__v = *(ptr);			break;	\
-		case 2: __v = __get_unaligned_2_le(__p);	break;	\
-		case 4: __v = __get_unaligned_4_le(__p);	break;	\
-		case 8: {					\
-				unsigned int __v1, __v2;	\
-				__v2 = __get_unaligned_4_le((__p+4)); \
-				__v1 = __get_unaligned_4_le(__p);	\
-				__v = ((unsigned long long)__v2 << 32 | __v1);	\
-			}					\
-			break;					\
-		default: __v = __bug_unaligned_x(__p);	break;	\
-		}						\
-		__v;						\
+#define __get_unaligned_8_le(__p)					\
+	((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 |	\
+		__get_unaligned_4_le(__p))
+
+#define __get_unaligned_8_be(__p)					\
+	((unsigned long long)__get_unaligned_4_be(__p) << 32 |		\
+		__get_unaligned_4_be((__p+4)))
+
+#define __get_unaligned_le(ptr)						\
+	({								\
+		const __u8 *__p = (const __u8 *)(ptr);			\
+		__builtin_choose_expr(sizeof(*(ptr)) == 1, *__p,	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p),	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p),	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p),	\
+		    (void)__bug_unaligned_x(__p)))));			\
 	})
 
-#define __get_unaligned_be(ptr)					\
-	({							\
-		__typeof__(*(ptr)) __v;				\
-		__u8 *__p = (__u8 *)(ptr);			\
-		switch (sizeof(*(ptr))) {			\
-		case 1:	__v = *(ptr);			break;	\
-		case 2: __v = __get_unaligned_2_be(__p);	break;	\
-		case 4: __v = __get_unaligned_4_be(__p);	break;	\
-		case 8: {					\
-				unsigned int __v1, __v2;	\
-				__v2 = __get_unaligned_4_be(__p); \
-				__v1 = __get_unaligned_4_be((__p+4));	\
-				__v = ((unsigned long long)__v2 << 32 | __v1);	\
-			}					\
-			break;					\
-		default: __v = __bug_unaligned_x(__p);	break;	\
-		}						\
-		__v;						\
+#define __get_unaligned_be(ptr)						\
+	({								\
+		const __u8 *__p = (const __u8 *)(ptr);			\
+		__builtin_choose_expr(sizeof(*(ptr)) == 1, *__p,	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p),	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p),	\
+		  __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p),	\
+		    (void)__bug_unaligned_x(__p)))));			\
 	})