mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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. -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQQTlUWNzXGEo3bFmyIR4drqP028CQUCZuWyzBQccHJhdHl1c2hA a2VybmVsLm9yZwAKCRAR4drqP028CXj6AQCvucu8Z8Z2WDwvpn51GGNOSmgIfHkJ i02EIQW5Cz3dygEA7pVZYyW1M/IfbgauX/NI/eYoEFwDfMD5t+MJ4HId+wY= =F9Ud -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
5d09909a19
@ -3281,7 +3281,8 @@ static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
|
||||
for (j = 0; j < manufacturers[i]->nparts; j++) {
|
||||
if (!strcmp(name, manufacturers[i]->parts[j].name)) {
|
||||
if (manufacturers[i]->parts[j].name &&
|
||||
!strcmp(name, manufacturers[i]->parts[j].name)) {
|
||||
nor->manufacturer = manufacturers[i];
|
||||
return &manufacturers[i]->parts[j];
|
||||
}
|
||||
|
@ -436,6 +436,8 @@ static const struct flash_info st_nor_parts[] = {
|
||||
.id = SNOR_ID(0x20, 0xbb, 0x17),
|
||||
.name = "n25q064a",
|
||||
.size = SZ_8M,
|
||||
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
|
||||
SPI_NOR_BP3_SR_BIT6,
|
||||
.no_sfdp_flags = SECT_4K | SPI_NOR_QUAD_READ,
|
||||
}, {
|
||||
.id = SNOR_ID(0x20, 0xbb, 0x18),
|
||||
|
@ -966,6 +966,10 @@ static const struct flash_info spansion_nor_parts[] = {
|
||||
.name = "s28hl01gt",
|
||||
.mfr_flags = USE_CLPEF,
|
||||
.fixups = &s28hx_t_fixups,
|
||||
}, {
|
||||
.id = SNOR_ID(0x34, 0x5b, 0x19),
|
||||
.mfr_flags = USE_CLPEF,
|
||||
.fixups = &s28hx_t_fixups,
|
||||
}, {
|
||||
.id = SNOR_ID(0x34, 0x5b, 0x1a),
|
||||
.name = "s28hs512t",
|
||||
|
@ -167,6 +167,21 @@ static const struct flash_info sst_nor_parts[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static int sst_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
|
||||
const u_char *buf)
|
||||
{
|
||||
u8 op = (len == 1) ? SPINOR_OP_BP : SPINOR_OP_AAI_WP;
|
||||
int ret;
|
||||
|
||||
nor->program_opcode = op;
|
||||
ret = spi_nor_write_data(nor, to, 1, buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
WARN(ret != len, "While writing %zu byte written %i bytes\n", len, ret);
|
||||
|
||||
return spi_nor_wait_till_ready(nor);
|
||||
}
|
||||
|
||||
static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
@ -188,16 +203,10 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
|
||||
/* Start write from odd address. */
|
||||
if (to % 2) {
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
|
||||
/* write one byte. */
|
||||
ret = spi_nor_write_data(nor, to, 1, buf);
|
||||
ret = sst_nor_write_data(nor, to, 1, buf);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
to++;
|
||||
actual++;
|
||||
@ -205,16 +214,11 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
|
||||
/* Write out most of the data here. */
|
||||
for (; actual < len - 1; actual += 2) {
|
||||
nor->program_opcode = SPINOR_OP_AAI_WP;
|
||||
|
||||
/* write two bytes. */
|
||||
ret = spi_nor_write_data(nor, to, 2, buf + actual);
|
||||
ret = sst_nor_write_data(nor, to, 2, buf + actual);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
WARN(ret != 2, "While writing 2 bytes written %i bytes\n", ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
to += 2;
|
||||
nor->sst_write_second = true;
|
||||
}
|
||||
@ -234,14 +238,9 @@ static int sst_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
ret = spi_nor_write_data(nor, to, 1, buf + actual);
|
||||
ret = sst_nor_write_data(nor, to, 1, buf + actual);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
WARN(ret != 1, "While writing 1 byte written %i bytes\n", ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
actual += 1;
|
||||
|
||||
|
@ -17,6 +17,31 @@
|
||||
SPI_MEM_OP_NO_DUMMY, \
|
||||
SPI_MEM_OP_DATA_OUT(1, buf, 0))
|
||||
|
||||
static int
|
||||
w25q128_post_bfpt_fixups(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *bfpt_header,
|
||||
const struct sfdp_bfpt *bfpt)
|
||||
{
|
||||
/*
|
||||
* Zetta ZD25Q128C is a clone of the Winbond device. But the encoded
|
||||
* size is really wrong. It seems that they confused Mbit with MiB.
|
||||
* Thus the flash is discovered as a 2MiB device.
|
||||
*/
|
||||
if (bfpt_header->major == SFDP_JESD216_MAJOR &&
|
||||
bfpt_header->minor == SFDP_JESD216_MINOR &&
|
||||
nor->params->size == SZ_2M &&
|
||||
nor->params->erase_map.regions[0].size == SZ_2M) {
|
||||
nor->params->size = SZ_16M;
|
||||
nor->params->erase_map.regions[0].size = SZ_16M;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_nor_fixups w25q128_fixups = {
|
||||
.post_bfpt = w25q128_post_bfpt_fixups,
|
||||
};
|
||||
|
||||
static int
|
||||
w25q256_post_bfpt_fixups(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *bfpt_header,
|
||||
@ -108,6 +133,7 @@ static const struct flash_info winbond_nor_parts[] = {
|
||||
.size = SZ_16M,
|
||||
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
|
||||
.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
|
||||
.fixups = &w25q128_fixups,
|
||||
}, {
|
||||
.id = SNOR_ID(0xef, 0x40, 0x19),
|
||||
.name = "w25q256",
|
||||
|
Loading…
Reference in New Issue
Block a user