Commit 8e987465 authored by Aaron Sierra's avatar Aaron Sierra Committed by David Woodhouse

mtd: cfi: Allow per-mapping CFI device endianness

This patch allows each CFI device map to use its own endianness. The
globally defined CFI endianness (CONFIG_MTD_CFI_NOSWAP,
CONFIG_MTD_CFI_BE_BYTE_SWAP or CONFIG_MTD_CFI_LE_BYTE_SWAP) becomes the
default value which can be overridden by a driver for a particular device.
Signed-off-by: default avatarAaron Sierra <asierra@xes-inc.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 342ff28f
...@@ -139,8 +139,9 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) ...@@ -139,8 +139,9 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
} }
/* Do some byteswapping if necessary */ /* Do some byteswapping if necessary */
extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); extp->FeatureSupport = cfi32_to_cpu(map, extp->FeatureSupport);
extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); extp->BlkStatusRegMask = cfi32_to_cpu(map,
extp->BlkStatusRegMask);
#ifdef DEBUG_CFI_FEATURES #ifdef DEBUG_CFI_FEATURES
/* Tell the user about it in lots of lovely detail */ /* Tell the user about it in lots of lovely detail */
......
...@@ -354,10 +354,10 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf ...@@ -354,10 +354,10 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf
onecmd = cmd; onecmd = cmd;
break; break;
case 2: case 2:
onecmd = cpu_to_cfi16(cmd); onecmd = cpu_to_cfi16(map, cmd);
break; break;
case 4: case 4:
onecmd = cpu_to_cfi32(cmd); onecmd = cpu_to_cfi32(map, cmd);
break; break;
} }
...@@ -437,10 +437,10 @@ static inline unsigned long cfi_merge_status(map_word val, struct map_info *map, ...@@ -437,10 +437,10 @@ static inline unsigned long cfi_merge_status(map_word val, struct map_info *map,
case 1: case 1:
break; break;
case 2: case 2:
res = cfi16_to_cpu(res); res = cfi16_to_cpu(map, res);
break; break;
case 4: case 4:
res = cfi32_to_cpu(res); res = cfi32_to_cpu(map, res);
break; break;
default: BUG(); default: BUG();
} }
...@@ -480,12 +480,12 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) ...@@ -480,12 +480,12 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr)
if (map_bankwidth_is_1(map)) { if (map_bankwidth_is_1(map)) {
return val.x[0]; return val.x[0];
} else if (map_bankwidth_is_2(map)) { } else if (map_bankwidth_is_2(map)) {
return cfi16_to_cpu(val.x[0]); return cfi16_to_cpu(map, val.x[0]);
} else { } else {
/* No point in a 64-bit byteswap since that would just be /* No point in a 64-bit byteswap since that would just be
swapping the responses from different chips, and we are swapping the responses from different chips, and we are
only interested in one chip (a representative sample) */ only interested in one chip (a representative sample) */
return cfi32_to_cpu(val.x[0]); return cfi32_to_cpu(map, val.x[0]);
} }
} }
...@@ -496,12 +496,12 @@ static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) ...@@ -496,12 +496,12 @@ static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr)
if (map_bankwidth_is_1(map)) { if (map_bankwidth_is_1(map)) {
return val.x[0] & 0xff; return val.x[0] & 0xff;
} else if (map_bankwidth_is_2(map)) { } else if (map_bankwidth_is_2(map)) {
return cfi16_to_cpu(val.x[0]); return cfi16_to_cpu(map, val.x[0]);
} else { } else {
/* No point in a 64-bit byteswap since that would just be /* No point in a 64-bit byteswap since that would just be
swapping the responses from different chips, and we are swapping the responses from different chips, and we are
only interested in one chip (a representative sample) */ only interested in one chip (a representative sample) */
return cfi32_to_cpu(val.x[0]); return cfi32_to_cpu(map, val.x[0]);
} }
} }
......
...@@ -19,53 +19,35 @@ ...@@ -19,53 +19,35 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifndef CONFIG_MTD_CFI_ADV_OPTIONS #define CFI_HOST_ENDIAN 1
#define CFI_LITTLE_ENDIAN 2
#define CFI_HOST_ENDIAN #define CFI_BIG_ENDIAN 3
#else #if !defined(CONFIG_MTD_CFI_ADV_OPTIONS) || defined(CONFIG_MTD_CFI_NOSWAP)
#define CFI_DEFAULT_ENDIAN CFI_HOST_ENDIAN
#ifdef CONFIG_MTD_CFI_NOSWAP #elif defined(CONFIG_MTD_CFI_LE_BYTE_SWAP)
#define CFI_HOST_ENDIAN #define CFI_DEFAULT_ENDIAN CFI_LITTLE_ENDIAN
#endif #elif defined(CONFIG_MTD_CFI_BE_BYTE_SWAP)
#define CFI_DEFAULT_ENDIAN CFI_BIG_ENDIAN
#ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP
#define CFI_LITTLE_ENDIAN
#endif
#ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP
#define CFI_BIG_ENDIAN
#endif
#endif
#if defined(CFI_LITTLE_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_le16(x)
#define cpu_to_cfi32(x) cpu_to_le32(x)
#define cpu_to_cfi64(x) cpu_to_le64(x)
#define cfi16_to_cpu(x) le16_to_cpu(x)
#define cfi32_to_cpu(x) le32_to_cpu(x)
#define cfi64_to_cpu(x) le64_to_cpu(x)
#elif defined (CFI_BIG_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_be16(x)
#define cpu_to_cfi32(x) cpu_to_be32(x)
#define cpu_to_cfi64(x) cpu_to_be64(x)
#define cfi16_to_cpu(x) be16_to_cpu(x)
#define cfi32_to_cpu(x) be32_to_cpu(x)
#define cfi64_to_cpu(x) be64_to_cpu(x)
#elif defined (CFI_HOST_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) (x)
#define cpu_to_cfi32(x) (x)
#define cpu_to_cfi64(x) (x)
#define cfi16_to_cpu(x) (x)
#define cfi32_to_cpu(x) (x)
#define cfi64_to_cpu(x) (x)
#else #else
#error No CFI endianness defined #error No CFI endianness defined
#endif #endif
#define cfi_default(s) ((s)?:CFI_DEFAULT_ENDIAN)
#define cfi_be(s) (cfi_default(s) == CFI_BIG_ENDIAN)
#define cfi_le(s) (cfi_default(s) == CFI_LITTLE_ENDIAN)
#define cfi_host(s) (cfi_default(s) == CFI_HOST_ENDIAN)
#define cpu_to_cfi8(map, x) (x)
#define cfi8_to_cpu(map, x) (x)
#define cpu_to_cfi16(map, x) _cpu_to_cfi(16, (map)->swap, (x))
#define cpu_to_cfi32(map, x) _cpu_to_cfi(32, (map)->swap, (x))
#define cpu_to_cfi64(map, x) _cpu_to_cfi(64, (map)->swap, (x))
#define cfi16_to_cpu(map, x) _cfi_to_cpu(16, (map)->swap, (x))
#define cfi32_to_cpu(map, x) _cfi_to_cpu(32, (map)->swap, (x))
#define cfi64_to_cpu(map, x) _cfi_to_cpu(64, (map)->swap, (x))
#define _cpu_to_cfi(w, s, x) (cfi_host(s)?(x):_swap_to_cfi(w, s, x))
#define _cfi_to_cpu(w, s, x) (cfi_host(s)?(x):_swap_to_cpu(w, s, x))
#define _swap_to_cfi(w, s, x) (cfi_be(s)?cpu_to_be##w(x):cpu_to_le##w(x))
#define _swap_to_cpu(w, s, x) (cfi_be(s)?be##w##_to_cpu(x):le##w##_to_cpu(x))
...@@ -214,6 +214,7 @@ struct map_info { ...@@ -214,6 +214,7 @@ struct map_info {
void __iomem *virt; void __iomem *virt;
void *cached; void *cached;
int swap; /* this mapping's byte-swapping requirement */
int bankwidth; /* in octets. This isn't necessarily the width int bankwidth; /* in octets. This isn't necessarily the width
of actual bus cycles -- it's the repeat interval of actual bus cycles -- it's the repeat interval
in bytes, before you are talking to the first chip again. in bytes, before you are talking to the first chip again.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment