From f8e6f48efb6728ec01f6c624e5611e4a0f223005 Mon Sep 17 00:00:00 2001 From: nbd Date: Tue, 17 Jul 2012 11:35:29 -0400 Subject: [PATCH 091/123] 406-mtd-m25p80-allow-to-specify-max-read-size Import of the above patch from openwrt trunk, as of this commit: ---------- commit c1d79f64eed0a7ac36b5b9bca52275b397bec424 Author: nbd Date: Mon Jul 16 16:26:51 2012 +0000 uboot-ar71xx: fix compile on recent mac os x versions git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32750 3c298f89-4303-0410-b956-a3cf2f4a3e73 ---------- Path to patch in the repo is: target/linux/ar71xx/patches-3.3 Repo is: git://nbd.name/openwrt.git Signed-off-by: Paul Gortmaker --- drivers/mtd/devices/m25p80.c | 56 +++++++++++++++++++++++++++++++++--------- include/linux/spi/flash.h | 1 + 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 64c1e0d..4a170c7 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -100,6 +100,7 @@ struct m25p { u16 addr_width; u8 erase_opcode; u8 *command; + size_t max_read_len; }; static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) @@ -349,6 +350,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, struct m25p *flash = mtd_to_m25p(mtd); struct spi_transfer t[2]; struct spi_message m; + loff_t ofs; pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)from, len); @@ -364,19 +366,10 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; spi_message_add_tail(&t[0], &m); - t[1].rx_buf = buf; - t[1].len = len; spi_message_add_tail(&t[1], &m); mutex_lock(&flash->lock); - /* Wait till previous write/erase is done. */ - if (wait_till_ready(flash)) { - /* REVISIT status return?? */ - mutex_unlock(&flash->lock); - return 1; - } - /* FIXME switch to OPCODE_FAST_READ. It's required for higher * clocks; and at this writing, every chip this driver handles * supports that opcode. @@ -384,11 +377,44 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, /* Set up the write data buffer. */ flash->command[0] = OPCODE_READ; - m25p_addr2cmd(flash, from, flash->command); - spi_sync(flash->spi, &m); + ofs = 0; + while (len) { + size_t readlen; + size_t done; + int ret; + + ret = wait_till_ready(flash); + if (ret) { + mutex_unlock(&flash->lock); + return 1; + } + + if (flash->max_read_len > 0 && + flash->max_read_len < len) + readlen = flash->max_read_len; + else + readlen = len; + + t[1].rx_buf = buf + ofs; + t[1].len = readlen; + + m25p_addr2cmd(flash, from + ofs, flash->command); + + spi_sync(flash->spi, &m); - *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; + done = m.actual_length - m25p_cmdsz(flash) - + FAST_READ_DUMMY_BYTE; + if (done != readlen) { + mutex_unlock(&flash->lock); + return 1; + } + + ofs += done; + len -= done; + } + + *retlen = ofs; mutex_unlock(&flash->lock); @@ -893,6 +919,12 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd._erase = m25p80_erase; flash->mtd._read = m25p80_read; + if (data && data->max_read_len) { + flash->max_read_len = data->max_read_len; + dev_warn(&spi->dev, "max_read_len set to %d bytes\n", + flash->max_read_len); + } + /* sst flash chips use AAI word program */ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) flash->mtd._write = sst_write; diff --git a/include/linux/spi/flash.h b/include/linux/spi/flash.h index 3f22932..e4f872c 100644 --- a/include/linux/spi/flash.h +++ b/include/linux/spi/flash.h @@ -25,6 +25,7 @@ struct flash_platform_data { char *type; + size_t max_read_len; /* we'll likely add more ... use JEDEC IDs, etc */ }; -- 1.7.9.7