| 1 | --- a/drivers/mtd/devices/m25p80.c |
| 2 | +++ b/drivers/mtd/devices/m25p80.c |
| 3 | @@ -100,6 +100,7 @@ struct m25p { |
| 4 | u16 addr_width; |
| 5 | u8 erase_opcode; |
| 6 | u8 *command; |
| 7 | + size_t max_read_len; |
| 8 | }; |
| 9 | |
| 10 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) |
| 11 | @@ -349,6 +350,7 @@ static int m25p80_read(struct mtd_info * |
| 12 | struct m25p *flash = mtd_to_m25p(mtd); |
| 13 | struct spi_transfer t[2]; |
| 14 | struct spi_message m; |
| 15 | + loff_t ofs; |
| 16 | |
| 17 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), |
| 18 | __func__, (u32)from, len); |
| 19 | @@ -364,19 +366,10 @@ static int m25p80_read(struct mtd_info * |
| 20 | t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; |
| 21 | spi_message_add_tail(&t[0], &m); |
| 22 | |
| 23 | - t[1].rx_buf = buf; |
| 24 | - t[1].len = len; |
| 25 | spi_message_add_tail(&t[1], &m); |
| 26 | |
| 27 | mutex_lock(&flash->lock); |
| 28 | |
| 29 | - /* Wait till previous write/erase is done. */ |
| 30 | - if (wait_till_ready(flash)) { |
| 31 | - /* REVISIT status return?? */ |
| 32 | - mutex_unlock(&flash->lock); |
| 33 | - return 1; |
| 34 | - } |
| 35 | - |
| 36 | /* FIXME switch to OPCODE_FAST_READ. It's required for higher |
| 37 | * clocks; and at this writing, every chip this driver handles |
| 38 | * supports that opcode. |
| 39 | @@ -384,11 +377,44 @@ static int m25p80_read(struct mtd_info * |
| 40 | |
| 41 | /* Set up the write data buffer. */ |
| 42 | flash->command[0] = OPCODE_READ; |
| 43 | - m25p_addr2cmd(flash, from, flash->command); |
| 44 | |
| 45 | - spi_sync(flash->spi, &m); |
| 46 | + ofs = 0; |
| 47 | + while (len) { |
| 48 | + size_t readlen; |
| 49 | + size_t done; |
| 50 | + int ret; |
| 51 | + |
| 52 | + ret = wait_till_ready(flash); |
| 53 | + if (ret) { |
| 54 | + mutex_unlock(&flash->lock); |
| 55 | + return 1; |
| 56 | + } |
| 57 | + |
| 58 | + if (flash->max_read_len > 0 && |
| 59 | + flash->max_read_len < len) |
| 60 | + readlen = flash->max_read_len; |
| 61 | + else |
| 62 | + readlen = len; |
| 63 | + |
| 64 | + t[1].rx_buf = buf + ofs; |
| 65 | + t[1].len = readlen; |
| 66 | + |
| 67 | + m25p_addr2cmd(flash, from + ofs, flash->command); |
| 68 | + |
| 69 | + spi_sync(flash->spi, &m); |
| 70 | |
| 71 | - *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; |
| 72 | + done = m.actual_length - m25p_cmdsz(flash) - |
| 73 | + FAST_READ_DUMMY_BYTE; |
| 74 | + if (done != readlen) { |
| 75 | + mutex_unlock(&flash->lock); |
| 76 | + return 1; |
| 77 | + } |
| 78 | + |
| 79 | + ofs += done; |
| 80 | + len -= done; |
| 81 | + } |
| 82 | + |
| 83 | + *retlen = ofs; |
| 84 | |
| 85 | mutex_unlock(&flash->lock); |
| 86 | |
| 87 | @@ -899,6 +925,12 @@ static int __devinit m25p_probe(struct s |
| 88 | flash->mtd._erase = m25p80_erase; |
| 89 | flash->mtd._read = m25p80_read; |
| 90 | |
| 91 | + if (data && data->max_read_len) { |
| 92 | + flash->max_read_len = data->max_read_len; |
| 93 | + dev_warn(&spi->dev, "max_read_len set to %d bytes\n", |
| 94 | + flash->max_read_len); |
| 95 | + } |
| 96 | + |
| 97 | /* sst flash chips use AAI word program */ |
| 98 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) |
| 99 | flash->mtd._write = sst_write; |
| 100 | --- a/include/linux/spi/flash.h |
| 101 | +++ b/include/linux/spi/flash.h |
| 102 | @@ -25,6 +25,7 @@ struct flash_platform_data { |
| 103 | |
| 104 | char *type; |
| 105 | |
| 106 | + size_t max_read_len; |
| 107 | /* we'll likely add more ... use JEDEC IDs, etc */ |
| 108 | }; |
| 109 | |
| 110 | |