Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: spi-nor: spansion: Fixup params->set_4byte_addr_mode for SEMPER

Infineon SEMPER flash family does not support E9h opcode as Exit 4-byte
mode (EX4B). Therefore, params->set_4byte_addr_mode is not determined by
BFPT parse. Fixup it up by introducing vendor specific EX4B opcode (B8h)
and function.

Fixes: c87c9b11c53ce ("mtd: spi-nor: spansion: Determine current address mode")
Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Acked-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Acked-by: Pratyush Yadav <pratyush@kernel.org>
Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
Link: https://lore.kernel.org/r/20250612074427.22263-1-Takahiro.Kuwano@infineon.com

authored by

Takahiro Kuwano and committed by
Pratyush Yadav
a45ab839 d8b73ce1

+31
+31
drivers/mtd/spi-nor/spansion.c
··· 17 17 18 18 #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ 19 19 #define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */ 20 + #define SPINOR_OP_CYPRESS_EX4B 0xB8 /* Exit 4-byte address mode */ 20 21 #define SPINOR_OP_CYPRESS_DIE_ERASE 0x61 /* Chip (die) erase */ 21 22 #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ 22 23 #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ ··· 58 57 SPI_MEM_OP_ADDR(naddr, addr, 0), \ 59 58 SPI_MEM_OP_DUMMY(ndummy, 0), \ 60 59 SPI_MEM_OP_DATA_IN(1, buf, 0)) 60 + 61 + #define CYPRESS_NOR_EN4B_EX4B_OP(enable) \ 62 + SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : \ 63 + SPINOR_OP_CYPRESS_EX4B, 0), \ 64 + SPI_MEM_OP_NO_ADDR, \ 65 + SPI_MEM_OP_NO_DUMMY, \ 66 + SPI_MEM_OP_NO_DATA) 61 67 62 68 #define SPANSION_OP(opcode) \ 63 69 SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \ ··· 364 356 return 0; 365 357 } 366 358 359 + static int cypress_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) 360 + { 361 + int ret; 362 + struct spi_mem_op op = CYPRESS_NOR_EN4B_EX4B_OP(enable); 363 + 364 + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); 365 + 366 + ret = spi_mem_exec_op(nor->spimem, &op); 367 + if (ret) 368 + dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); 369 + 370 + return ret; 371 + } 372 + 367 373 /** 368 374 * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode 369 375 * (3 or 4-byte) by querying status ··· 548 526 struct spi_mem_op op; 549 527 int ret; 550 528 529 + /* Assign 4-byte address mode method that is not determined in BFPT */ 530 + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; 531 + 551 532 ret = cypress_nor_set_addr_mode_nbytes(nor); 552 533 if (ret) 553 534 return ret; ··· 615 590 const struct sfdp_bfpt *bfpt) 616 591 { 617 592 int ret; 593 + 594 + /* Assign 4-byte address mode method that is not determined in BFPT */ 595 + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; 618 596 619 597 ret = cypress_nor_set_addr_mode_nbytes(nor); 620 598 if (ret) ··· 746 718 const struct sfdp_parameter_header *bfpt_header, 747 719 const struct sfdp_bfpt *bfpt) 748 720 { 721 + /* Assign 4-byte address mode method that is not determined in BFPT */ 722 + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; 723 + 749 724 return cypress_nor_set_addr_mode_nbytes(nor); 750 725 } 751 726