summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/spi-nor/spi-nor.c
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2019-05-03 11:33:54 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-05-08 10:52:51 +0200
commitc8516869c49677bb1468e0e2e351bc05b815e4ef (patch)
tree233230d051ce0166cbdbb75ccaad7d599f61ad9c /drivers/mtd/spi-nor/spi-nor.c
parent167a27b5354910b92c7a4654a44d72a3d167f0ab (diff)
downloadbarebox-c8516869c49677bb1468e0e2e351bc05b815e4ef.tar.gz
barebox-c8516869c49677bb1468e0e2e351bc05b815e4ef.tar.xz
spi: Extend the core to ease integration of SPI memory controllers
Sync with Linux v5.1-rc1. This is the barebox adoption of the commit commit c36ff266dc82f4ae797a6f3513c6ffa344f7f1c7 Author: Boris Brezillon <boris.brezillon@bootlin.com> Date: Thu Apr 26 18:18:14 2018 +0200 spi: Extend the core to ease integration of SPI memory controllers Some controllers are exposing high-level interfaces to access various kind of SPI memories. Unfortunately they do not fit in the current spi_controller model and usually have drivers placed in drivers/mtd/spi-nor which are only supporting SPI NORs and not SPI memories in general. This is an attempt at defining a SPI memory interface which works for all kinds of SPI memories (NORs, NANDs, SRAMs). Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Reviewed-by: Frieder Schrempf <frieder.schrempf@exceet.de> Tested-by: Frieder Schrempf <frieder.schrempf@exceet.de> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mtd/spi-nor/spi-nor.c')
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 85b55c6982..851ac1c33e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -784,7 +784,8 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
struct spi_nor *nor = mtd_to_spi_nor(mtd);
- u32 page_offset, page_size, i;
+ size_t page_offset, page_remain, i;
+ size_t retval;
int ret;
dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
@@ -793,32 +794,23 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
if (ret)
return ret;
- write_enable(nor);
-
- page_offset = to & (nor->page_size - 1);
-
- /* do all the bytes fit onto one page? */
- if (page_offset + len <= nor->page_size) {
- nor->write(nor, to, len, retlen, buf);
- } else {
- /* the size of data remaining on the first page */
- page_size = nor->page_size - page_offset;
- nor->write(nor, to, page_size, retlen, buf);
+ for (i = 0; i < len; ) {
+ ssize_t written;
- /* write everything in nor->page_size chunks */
- for (i = page_size; i < len; i += page_size) {
- page_size = len - i;
- if (page_size > nor->page_size)
- page_size = nor->page_size;
+ page_offset = (to + i) & (nor->page_size - 1);
+ page_remain = min_t(size_t, nor->page_size - page_offset,
+ len - i);
- ret = spi_nor_wait_till_ready(nor);
- if (ret)
- goto write_err;
+ write_enable(nor);
+ nor->write(nor, to + i, page_remain, &retval, buf + i);
+ written = retval;
- write_enable(nor);
+ ret = spi_nor_wait_till_ready(nor);
+ if (ret)
+ goto write_err;
- nor->write(nor, to + i, page_size, retlen, buf + i);
- }
+ *retlen += written;
+ i += written;
}
ret = spi_nor_wait_till_ready(nor);