summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorAlison Wang <b18965@freescale.com>2017-05-19 03:11:58 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:33 (GMT)
commitf7c1d52082366e24d50dd6dc94329f5d3ac2610e (patch)
tree152ebbdb6f2037a9f83315e2bc7aad6fcd349759 /drivers/mtd
parent14c016af42fae909221dcdf552541810b2087c75 (diff)
downloadlinux-f7c1d52082366e24d50dd6dc94329f5d3ac2610e.tar.xz
mtd: fsl-quadspi: add u32 to u8 transform function
The TX/RX Buffer Data Register in QSPI is 32-bit register. So the 32bit data need transform to 4bytes data. But the "*((u32 *)rxbuf) = tmp" will depend on endian of the core. We add endian independence function to do the 32bit data to 4bytes transition. Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/spi-nor/fsl-quadspi.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 5a5b355..307b3c2 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -366,6 +366,31 @@ static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
return ioread32(addr);
}
+static inline u32 *u8tou32(u32 *dest, const u8 *src, size_t n)
+{
+ size_t i;
+ *dest = 0;
+
+ n = n > 4 ? 4 : n;
+ for (i = 0; i < n; i++)
+ *dest |= *src++ << i * 8;
+
+ return dest;
+
+}
+
+static inline u8 *u32tou8(u8 *dest, const u32 *src, size_t n)
+{
+ size_t i;
+ u8 *xdest = dest;
+
+ n = n > 4 ? 4 : n;
+ for (i = 0; i < n; i++)
+ *xdest++ = *src >> i * 8;
+
+ return dest;
+}
+
/*
* An IC bug makes us to re-arrange the 32-bit data.
* The following chips, such as IMX6SLX, have fixed this bug.
@@ -700,10 +725,10 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
q->chip_base_addr, tmp);
if (len >= 4) {
- *((u32 *)rxbuf) = tmp;
+ u32tou8(rxbuf, &tmp, 4);
rxbuf += 4;
} else {
- memcpy(rxbuf, &tmp, len);
+ u32tou8(rxbuf, &tmp, len);
break;
}
@@ -737,7 +762,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
}
static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
- u8 opcode, unsigned int to, u32 *txbuf,
+ u8 opcode, unsigned int to, u8 *txbuf,
unsigned count)
{
int ret, i, j;
@@ -752,9 +777,10 @@ static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
/* fill the TX data to the FIFO */
for (j = 0, i = ((count + 3) / 4); j < i; j++) {
- tmp = fsl_qspi_endian_xchg(q, *txbuf);
+ u8tou32(&tmp, txbuf, 4);
+ tmp = fsl_qspi_endian_xchg(q, tmp);
qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
- txbuf++;
+ txbuf += 4;
}
/* fill the TXFIFO upto 16 bytes for i.MX7d */
@@ -1011,7 +1037,7 @@ static int fsl_qspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
u32 to = 0;
if (opcode == SPINOR_OP_SPANSION_RDAR)
- memcpy(&to, nor->cmd_buf, 4);
+ u8tou32(&to, nor->cmd_buf, 4);
ret = fsl_qspi_runcmd(q, opcode, to, len);
if (ret)
@@ -1028,7 +1054,7 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
u32 to = 0;
if (opcode == SPINOR_OP_SPANSION_WRAR)
- memcpy(&to, nor->cmd_buf, 4);
+ u8tou32(&to, nor->cmd_buf, 4);
if (!buf) {
ret = fsl_qspi_runcmd(q, opcode, to, 1);
@@ -1040,7 +1066,7 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
} else if (len > 0) {
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
- (u32 *)buf, len);
+ buf, len);
if (ret > 0)
return 0;
} else {
@@ -1056,7 +1082,7 @@ static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
{
struct fsl_qspi *q = nor->priv;
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
- (u32 *)buf, len);
+ (u8 *)buf, len);
/* invalid the data in the AHB buffer. */
fsl_qspi_invalid(q);