Skip to content

Commit 26fd6bf

Browse files
committed
Merge tag 'mtd/fixes-for-7.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd fixes from Miquel Raynal: "Besides an out-of-bound bug, this is about properly supporting Winbond octal SPI NAND chips which use a specific pattern for stuffing more address bits in some operations. This uses the spi-mem flag in SPI NAND that was added to the spi-mem layer just before the merge window through the spi tree" * tag 'mtd/fixes-for-7.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: spinand: winbond: Fix ODTR write VCR on W35NxxJW mtd: spinand: winbond: Set the packed page read flag to W35N02/04JW mtd: spinand: Add support for packed read data ODTR commands mtd: spi-nor: debugfs: fix out-of-bounds read in spi_nor_params_show()
2 parents cae4ef6 + 135ac3b commit 26fd6bf

4 files changed

Lines changed: 34 additions & 7 deletions

File tree

drivers/mtd/nand/spi/core.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ spinand_fill_page_read_op(struct spinand_device *spinand, u64 addr)
100100
return op;
101101
}
102102

103+
static struct spi_mem_op
104+
spinand_fill_page_read_packed_op(struct spinand_device *spinand, u64 addr)
105+
{
106+
struct spi_mem_op op = spinand->op_templates->page_read;
107+
108+
op.cmd.opcode |= addr >> 16;
109+
op.addr.val = addr & 0xFFFF;
110+
111+
return op;
112+
}
113+
103114
struct spi_mem_op
104115
spinand_fill_prog_exec_op(struct spinand_device *spinand, u64 addr)
105116
{
@@ -453,7 +464,10 @@ static int spinand_load_page_op(struct spinand_device *spinand,
453464
{
454465
struct nand_device *nand = spinand_to_nand(spinand);
455466
unsigned int row = nanddev_pos_to_row(nand, &req->pos);
456-
struct spi_mem_op op = SPINAND_OP(spinand, page_read, row);
467+
bool packed = spinand->flags & SPINAND_ODTR_PACKED_PAGE_READ;
468+
struct spi_mem_op op = packed ?
469+
SPINAND_OP(spinand, page_read_packed, row) :
470+
SPINAND_OP(spinand, page_read, row);
457471

458472
return spi_mem_exec_op(spinand->spimem, &op);
459473
}
@@ -1489,9 +1503,13 @@ static int spinand_init_odtr_instruction_set(struct spinand_device *spinand)
14891503
if (!spi_mem_supports_op(spinand->spimem, &tmpl->blk_erase))
14901504
return -EOPNOTSUPP;
14911505

1492-
tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_8D_8D_0_OP(0);
1493-
if (!spi_mem_supports_op(spinand->spimem, &tmpl->page_read))
1506+
if (spinand->flags & SPINAND_ODTR_PACKED_PAGE_READ)
1507+
tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_PACKED_8D_8D_0_OP(0);
1508+
else
1509+
tmpl->page_read = (struct spi_mem_op)SPINAND_PAGE_READ_8D_8D_0_OP(0);
1510+
if (!spi_mem_supports_op(spinand->spimem, &tmpl->page_read)) {
14941511
return -EOPNOTSUPP;
1512+
}
14951513

14961514
tmpl->prog_exec = (struct spi_mem_op)SPINAND_PROG_EXEC_8D_8D_0_OP(0);
14971515
if (!spi_mem_supports_op(spinand->spimem, &tmpl->prog_exec))

drivers/mtd/nand/spi/winbond.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
9999

100100
#define SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(reg, buf) \
101101
SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x81, 8), \
102-
SPI_MEM_DTR_OP_ADDR(4, reg, 8), \
102+
SPI_MEM_DTR_OP_ADDR(4, reg << 8, 8), \
103103
SPI_MEM_OP_NO_DUMMY, \
104104
SPI_MEM_DTR_OP_DATA_OUT(2, buf, 8))
105105

@@ -518,7 +518,7 @@ static const struct spinand_info winbond_spinand_table[] = {
518518
SPINAND_INFO_OP_VARIANTS(&read_cache_octal_variants,
519519
&write_cache_octal_variants,
520520
&update_cache_octal_variants),
521-
0,
521+
SPINAND_ODTR_PACKED_PAGE_READ,
522522
SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
523523
SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
524524
SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),
@@ -529,7 +529,7 @@ static const struct spinand_info winbond_spinand_table[] = {
529529
SPINAND_INFO_OP_VARIANTS(&read_cache_octal_variants,
530530
&write_cache_octal_variants,
531531
&update_cache_octal_variants),
532-
0,
532+
SPINAND_ODTR_PACKED_PAGE_READ,
533533
SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops),
534534
SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL),
535535
SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)),

drivers/mtd/spi-nor/debugfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3+
#include <linux/array_size.h>
34
#include <linux/debugfs.h>
45
#include <linux/mtd/spi-nor.h>
56
#include <linux/spi/spi.h>
@@ -92,7 +93,8 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
9293
seq_printf(s, "address nbytes\t%u\n", nor->addr_nbytes);
9394

9495
seq_puts(s, "flags\t\t");
95-
spi_nor_print_flags(s, nor->flags, snor_f_names, sizeof(snor_f_names));
96+
spi_nor_print_flags(s, nor->flags, snor_f_names,
97+
ARRAY_SIZE(snor_f_names));
9698
seq_puts(s, "\n");
9799

98100
seq_puts(s, "\nopcodes\n");

include/linux/mtd/spinand.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@
290290
SPI_MEM_OP_NO_DUMMY, \
291291
SPI_MEM_OP_NO_DATA)
292292

293+
#define SPINAND_PAGE_READ_PACKED_8D_8D_0_OP(addr) \
294+
SPI_MEM_OP(SPI_MEM_DTR_OP_PACKED_CMD(0x13, addr >> 16, 8), \
295+
SPI_MEM_DTR_OP_ADDR(2, addr & 0xffff, 8), \
296+
SPI_MEM_OP_NO_DUMMY, \
297+
SPI_MEM_OP_NO_DATA)
298+
293299
#define SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(addr, ndummy, buf, len, freq) \
294300
SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x9d, 8), \
295301
SPI_MEM_DTR_OP_ADDR(2, addr, 8), \
@@ -483,6 +489,7 @@ struct spinand_ecc_info {
483489
#define SPINAND_HAS_PROG_PLANE_SELECT_BIT BIT(2)
484490
#define SPINAND_HAS_READ_PLANE_SELECT_BIT BIT(3)
485491
#define SPINAND_NO_RAW_ACCESS BIT(4)
492+
#define SPINAND_ODTR_PACKED_PAGE_READ BIT(5)
486493

487494
/**
488495
* struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure

0 commit comments

Comments
 (0)