1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -115,6 +115,7 @@ struct m25p {
u8 program_opcode;
u8 *command;
enum read_type flash_read;
+ size_t max_read_len;
};
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -517,6 +518,7 @@ static int m25p80_read(struct mtd_info *
struct spi_message m;
uint8_t opcode;
int dummy;
+ loff_t ofs;
pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
__func__, (u32)from, len);
@@ -534,29 +536,51 @@ static int m25p80_read(struct mtd_info *
t[0].len = m25p_cmdsz(flash) + dummy;
spi_message_add_tail(&t[0], &m);
- t[1].rx_buf = buf;
- t[1].rx_nbits = m25p80_rx_nbits(flash);
- 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;
- }
-
/* Set up the write data buffer. */
opcode = flash->read_opcode;
flash->command[0] = opcode;
- m25p_addr2cmd(flash, from, flash->command);
+ 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].rx_nbits = m25p80_rx_nbits(flash);
+ t[1].len = readlen;
+
+ m25p_addr2cmd(flash, from + ofs, flash->command);
+
+ spi_sync(flash->spi, &m);
- spi_sync(flash->spi, &m);
+ done = m.actual_length - m25p_cmdsz(flash) -
+ dummy;
+ if (done != readlen) {
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
- *retlen = m.actual_length - m25p_cmdsz(flash) - dummy;
+ ofs += done;
+ len -= done;
+ }
+ *retlen = ofs;
mutex_unlock(&flash->lock);
return 0;
@@ -1193,6 +1217,12 @@ static int m25p_probe(struct spi_device
flash->mtd._unlock = m25p80_unlock;
}
+ 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 (info->flags & SST_WRITE)
flash->mtd._write = sst_write;
--- 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 */
};
|