Skip to content

Commit 5d09909

Browse files
committed
Merge tag 'spi-nor/for-6.12' into mtd/next
SPI NOR changes for 6.12 Notable changes: - Add Write Protect support for N25Q064A. - New flash support for Zetta ZD25Q128C and Spansion S28HS256T. - Fix a NULL dereference in probe path for flashes without a name. The probe path tries to access the name without checking its existence first. S28HS256T is the first flash to define its entry without a name, uncovering this issue.
2 parents 3959998 + ac5bfa9 commit 5d09909

File tree

5 files changed

+53
-21
lines changed

5 files changed

+53
-21
lines changed

drivers/mtd/spi-nor/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3281,7 +3281,8 @@ static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
32813281

32823282
for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
32833283
for (j = 0; j < manufacturers[i]->nparts; j++) {
3284-
if (!strcmp(name, manufacturers[i]->parts[j].name)) {
3284+
if (manufacturers[i]->parts[j].name &&
3285+
!strcmp(name, manufacturers[i]->parts[j].name)) {
32853286
nor->manufacturer = manufacturers[i];
32863287
return &manufacturers[i]->parts[j];
32873288
}

drivers/mtd/spi-nor/micron-st.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ static const struct flash_info st_nor_parts[] = {
436436
.id = SNOR_ID(0x20, 0xbb, 0x17),
437437
.name = "n25q064a",
438438
.size = SZ_8M,
439+
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
440+
SPI_NOR_BP3_SR_BIT6,
439441
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
440442
}, {
441443
.id = SNOR_ID(0x20, 0xbb, 0x18),

drivers/mtd/spi-nor/spansion.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,10 @@ static const struct flash_info spansion_nor_parts[] = {
966966
.name = "s28hl01gt",
967967
.mfr_flags = USE_CLPEF,
968968
.fixups = &s28hx_t_fixups,
969+
}, {
970+
.id = SNOR_ID(0x34, 0x5b, 0x19),
971+
.mfr_flags = USE_CLPEF,
972+
.fixups = &s28hx_t_fixups,
969973
}, {
970974
.id = SNOR_ID(0x34, 0x5b, 0x1a),
971975
.name = "s28hs512t",

drivers/mtd/spi-nor/sst.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,21 @@ static const struct flash_info sst_nor_parts[] = {
167167
}
168168
};
169169

170+
static int sst_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
171+
const u_char *buf)
172+
{
173+
u8 op = (len == 1) ? SPINOR_OP_BP : SPINOR_OP_AAI_WP;
174+
int ret;
175+
176+
nor->program_opcode = op;
177+
ret = spi_nor_write_data(nor, to, 1, buf);
178+
if (ret < 0)
179+
return ret;
180+
WARN(ret != len, "While writing %zu byte written %i bytes\n", len, ret);
181+
182+
return spi_nor_wait_till_ready(nor);
183+
}
184+
170185
static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
171186
size_t *retlen, const u_char *buf)
172187
{
@@ -188,33 +203,22 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
188203

189204
/* Start write from odd address. */
190205
if (to % 2) {
191-
nor->program_opcode = SPINOR_OP_BP;
192-
193206
/* write one byte. */
194-
ret = spi_nor_write_data(nor, to, 1, buf);
207+
ret = sst_nor_write_data(nor, to, 1, buf);
195208
if (ret < 0)
196209
goto out;
197-
WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
198-
ret = spi_nor_wait_till_ready(nor);
199-
if (ret)
200-
goto out;
201210

202211
to++;
203212
actual++;
204213
}
205214

206215
/* Write out most of the data here. */
207216
for (; actual < len - 1; actual += 2) {
208-
nor->program_opcode = SPINOR_OP_AAI_WP;
209-
210217
/* write two bytes. */
211-
ret = spi_nor_write_data(nor, to, 2, buf + actual);
218+
ret = sst_nor_write_data(nor, to, 2, buf + actual);
212219
if (ret < 0)
213220
goto out;
214-
WARN(ret != 2, "While writing 2 bytes written %i bytes\n", ret);
215-
ret = spi_nor_wait_till_ready(nor);
216-
if (ret)
217-
goto out;
221+
218222
to += 2;
219223
nor->sst_write_second = true;
220224
}
@@ -234,14 +238,9 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
234238
if (ret)
235239
goto out;
236240

237-
nor->program_opcode = SPINOR_OP_BP;
238-
ret = spi_nor_write_data(nor, to, 1, buf + actual);
241+
ret = sst_nor_write_data(nor, to, 1, buf + actual);
239242
if (ret < 0)
240243
goto out;
241-
WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
242-
ret = spi_nor_wait_till_ready(nor);
243-
if (ret)
244-
goto out;
245244

246245
actual += 1;
247246

drivers/mtd/spi-nor/winbond.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,31 @@
1717
SPI_MEM_OP_NO_DUMMY, \
1818
SPI_MEM_OP_DATA_OUT(1, buf, 0))
1919

20+
static int
21+
w25q128_post_bfpt_fixups(struct spi_nor *nor,
22+
const struct sfdp_parameter_header *bfpt_header,
23+
const struct sfdp_bfpt *bfpt)
24+
{
25+
/*
26+
* Zetta ZD25Q128C is a clone of the Winbond device. But the encoded
27+
* size is really wrong. It seems that they confused Mbit with MiB.
28+
* Thus the flash is discovered as a 2MiB device.
29+
*/
30+
if (bfpt_header->major == SFDP_JESD216_MAJOR &&
31+
bfpt_header->minor == SFDP_JESD216_MINOR &&
32+
nor->params->size == SZ_2M &&
33+
nor->params->erase_map.regions[0].size == SZ_2M) {
34+
nor->params->size = SZ_16M;
35+
nor->params->erase_map.regions[0].size = SZ_16M;
36+
}
37+
38+
return 0;
39+
}
40+
41+
static const struct spi_nor_fixups w25q128_fixups = {
42+
.post_bfpt = w25q128_post_bfpt_fixups,
43+
};
44+
2045
static int
2146
w25q256_post_bfpt_fixups(struct spi_nor *nor,
2247
const struct sfdp_parameter_header *bfpt_header,
@@ -108,6 +133,7 @@ static const struct flash_info winbond_nor_parts[] = {
108133
.size = SZ_16M,
109134
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
110135
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
136+
.fixups = &w25q128_fixups,
111137
}, {
112138
.id = SNOR_ID(0xef, 0x40, 0x19),
113139
.name = "w25q256",

0 commit comments

Comments
 (0)