diff options
author | Han Xu <han.xu@nxp.com> | 2017-07-21 16:17:59 -0500 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 120587fee2bbd3ca9e1f56913e73558fd42a94a0 (patch) | |
tree | a38e59b0f2f2ddf5b7a442f23ed09e353d6e8f4b /drivers/mtd | |
parent | 888f445fc4f8d0e02139ee5f65cef2f28f6c28b5 (diff) |
MLK-16060: mtd: fsl-quadspi: fix the unalignment issue for qspi
ARM64 platforms may access QSPI from non-64-bit-aligned address which
causes unalignment fault. Fixed the issue for AHB reading.
Signed-off-by: Han Xu <han.xu@nxp.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/spi-nor/fsl-quadspi.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 47f675098d63..dd0d817047fa 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -2,6 +2,7 @@ * Freescale QuadSPI driver. * * Copyright (C) 2013-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1090,6 +1091,8 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from, { struct fsl_qspi *q = nor->priv; u8 cmd = nor->read_opcode; + u8 tmp[8] = {0}; + int i, j; /* if necessary,ioremap buffer before AHB read, */ if (!q->ahb_addr) { @@ -1124,9 +1127,21 @@ static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from, cmd, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs, len); - /* Read out the data directly from the AHB buffer.*/ - memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs, - len); + /* For non-8-byte alignment cases */ + if (from % 8) { + j = 8 - (from & 0x7); + for (i = 0; i < j; ++i) { + memcpy(tmp + i, q->ahb_addr + q->chip_base_addr + from + - q->memmap_offs + i, 1); + } + memcpy(buf, tmp, j); + memcpy(buf + j, q->ahb_addr + q->chip_base_addr + from + - q->memmap_offs + j, len - j); + } else { + /* Read out the data directly from the AHB buffer.*/ + memcpy(buf, q->ahb_addr + q->chip_base_addr + from + - q->memmap_offs, len); + } return len; } |