[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20260109-winbond-v6-17-rc1-oddr-v2-24-1fff6a2ddb80@bootlin.com>
Date: Fri, 09 Jan 2026 18:18:22 +0100
From: Miquel Raynal <miquel.raynal@...tlin.com>
To: Mark Brown <broonie@...nel.org>, Richard Weinberger <richard@....at>,
Vignesh Raghavendra <vigneshr@...com>
Cc: Tudor Ambarus <tudor.ambarus@...aro.org>,
Pratyush Yadav <pratyush@...nel.org>,
Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
Steam Lin <STLin2@...bond.com>, Santhosh Kumar K <s-k6@...com>,
linux-spi@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-mtd@...ts.infradead.org, Miquel Raynal <miquel.raynal@...tlin.com>
Subject: [PATCH v2 24/27] mtd: spinand: Give the bus interface to the
configuration helper
The chip configuration hook is the one responsible to actually switch
the switch between bus interfaces. It is natural to give it the bus
interface we expect with a new parameter. For now the only value we can
give is SSDR, but this is subject to change in the future, so add a bit
of extra logic in the implementations of this callback to make sure
both the core and the chip driver are aligned on the request.
Signed-off-by: Miquel Raynal <miquel.raynal@...tlin.com>
---
drivers/mtd/nand/spi/core.c | 2 +-
drivers/mtd/nand/spi/winbond.c | 28 +++++++++++++++++++++-------
include/linux/mtd/spinand.h | 6 ++++--
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 019594182c60..1ac1d0181a91 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1606,7 +1606,7 @@ static int spinand_configure_chip(struct spinand_device *spinand)
return ret;
if (spinand->configure_chip) {
- ret = spinand->configure_chip(spinand);
+ ret = spinand->configure_chip(spinand, SSDR);
if (ret)
return ret;
}
diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 1d79a8ae7920..419f4303a0dc 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -311,13 +311,17 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand,
return -EINVAL;
}
-static int w25n0xjw_hs_cfg(struct spinand_device *spinand)
+static int w25n0xjw_hs_cfg(struct spinand_device *spinand,
+ enum spinand_bus_interface iface)
{
const struct spi_mem_op *op;
bool hs;
u8 sr4;
int ret;
+ if (iface != SSDR)
+ return -EOPNOTSUPP;
+
op = spinand->op_templates->read_cache;
if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
hs = false;
@@ -371,17 +375,25 @@ static int w35n0xjw_write_vcr(struct spinand_device *spinand, u8 reg, u8 val)
return 0;
}
-static int w35n0xjw_vcr_cfg(struct spinand_device *spinand)
+static int w35n0xjw_vcr_cfg(struct spinand_device *spinand,
+ enum spinand_bus_interface iface)
{
- const struct spi_mem_op *op;
+ const struct spi_mem_op *ref_op;
unsigned int dummy_cycles;
bool dtr, single;
u8 io_mode;
int ret;
- op = spinand->op_templates->read_cache;
+ switch (iface) {
+ case SSDR:
+ ref_op = spinand->ssdr_op_templates.read_cache;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ };
- dummy_cycles = ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
+ dummy_cycles = ((ref_op->dummy.nbytes * 8) / ref_op->dummy.buswidth) /
+ (ref_op->dummy.dtr ? 2 : 1);
switch (dummy_cycles) {
case 8:
case 12:
@@ -398,8 +410,10 @@ static int w35n0xjw_vcr_cfg(struct spinand_device *spinand)
if (ret)
return ret;
- single = (op->cmd.buswidth == 1 && op->addr.buswidth == 1 && op->data.buswidth == 1);
- dtr = (op->cmd.dtr && op->addr.dtr && op->data.dtr);
+ single = (ref_op->cmd.buswidth == 1 &&
+ ref_op->addr.buswidth == 1 &&
+ ref_op->data.buswidth == 1);
+ dtr = (ref_op->cmd.dtr && ref_op->addr.dtr && ref_op->data.dtr);
if (single && !dtr)
io_mode = W35N01JW_VCR_IO_MODE_SINGLE_SDR;
else if (!single && !dtr)
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 027923841bba..b7eb3eceb138 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -529,7 +529,8 @@ struct spinand_info {
const struct spinand_op_variants *vendor_ops;
int (*select_target)(struct spinand_device *spinand,
unsigned int target);
- int (*configure_chip)(struct spinand_device *spinand);
+ int (*configure_chip)(struct spinand_device *spinand,
+ enum spinand_bus_interface iface);
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
struct spinand_fact_otp fact_otp;
@@ -704,7 +705,8 @@ struct spinand_device {
const struct spinand_manufacturer *manufacturer;
void *priv;
- int (*configure_chip)(struct spinand_device *spinand);
+ int (*configure_chip)(struct spinand_device *spinand,
+ enum spinand_bus_interface iface);
bool cont_read_possible;
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
--
2.51.1
Powered by blists - more mailing lists