diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 6c68a51f1cc5..d7299d69ff79 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -198,6 +198,11 @@ do { \ }) #endif +static inline reg_size_t register_align(void *val) +{ + return (unsigned long)(signed long)val; +} + int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, struct mem_access *ma); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 943acf5ea07c..218b54d9d660 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -37,4 +37,9 @@ do { \ #define jump_to_uncached() do { } while (0) #define back_to_cached() do { } while (0) +static inline reg_size_t register_align(void *val) +{ + return (unsigned long long)(signed long long)(signed long)val; +} + #endif /* __ASM_SH_SYSTEM_64_H */ diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h index c7f3c94837dd..f8421f7ad63a 100644 --- a/arch/sh/include/asm/types.h +++ b/arch/sh/include/asm/types.h @@ -11,8 +11,10 @@ #ifdef CONFIG_SUPERH32 typedef u16 insn_size_t; +typedef u32 reg_size_t; #else typedef u32 insn_size_t; +typedef u64 reg_size_t; #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c index edefc53891a8..1b6b6a12a99b 100644 --- a/arch/sh/mm/flush-sh4.c +++ b/arch/sh/mm/flush-sh4.c @@ -10,10 +10,11 @@ */ void __weak __flush_wback_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES; @@ -52,10 +53,11 @@ void __weak __flush_wback_region(void *start, int size) */ void __weak __flush_purge_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES; @@ -90,10 +92,11 @@ void __weak __flush_purge_region(void *start, int size) */ void __weak __flush_invalidate_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES;