[PATCH 25/28] mtd: spinand: Give the bus interface to the configuration helper
Miquel Raynal
miquel.raynal at bootlin.com
Fri Oct 31 10:27:09 PDT 2025
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 at bootlin.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 0d98cc1d987e1f6387f6bb243cd3720949b01b0b..044a84d7b47bf08a14f2310b971cdc85267b0fd2 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1521,7 +1521,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 1d79a8ae79206af7d823018c4603b3bd36a0dd88..419f4303a0dc7518017e2bd422584813dca14d48 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 7d059956c81a3a6fd337bab43fb4f1130997ab0f..94348344208861c9e1ca36bd86e206225cbbd816 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -528,7 +528,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;
@@ -703,7 +704,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.0
More information about the linux-mtd
mailing list