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: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
Aaron Sierra 2011-11-14 18:44:34 -06:00 committed by David Woodhouse
parent 342ff28f5a
commit 8e987465a1
4 changed files with 40 additions and 56 deletions

View File

@ -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 */

View File

@ -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,
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)
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)
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]);
} }
} }

View File

@ -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_BIG_ENDIAN 3
#define CFI_HOST_ENDIAN #if !defined(CONFIG_MTD_CFI_ADV_OPTIONS) || defined(CONFIG_MTD_CFI_NOSWAP)
#define CFI_DEFAULT_ENDIAN CFI_HOST_ENDIAN
#else #elif defined(CONFIG_MTD_CFI_LE_BYTE_SWAP)
#define CFI_DEFAULT_ENDIAN CFI_LITTLE_ENDIAN
#ifdef CONFIG_MTD_CFI_NOSWAP #elif defined(CONFIG_MTD_CFI_BE_BYTE_SWAP)
#define CFI_HOST_ENDIAN #define CFI_DEFAULT_ENDIAN CFI_BIG_ENDIAN
#endif
#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))

View File

@ -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.