]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mtd: spinand: Give the bus interface to the configuration helper
authorMiquel Raynal <miquel.raynal@bootlin.com>
Fri, 9 Jan 2026 17:18:22 +0000 (18:18 +0100)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Thu, 29 Jan 2026 19:21:41 +0000 (20:21 +0100)
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@bootlin.com>
drivers/mtd/nand/spi/core.c
drivers/mtd/nand/spi/winbond.c
include/linux/mtd/spinand.h

index 1aff2d3683398cde760d439a9546446db3612efd..bbda60b397886f266e898f0c9ea60773d32a05a7 100644 (file)
@@ -1604,7 +1604,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;
        }
index 1d79a8ae79206af7d823018c4603b3bd36a0dd88..419f4303a0dc7518017e2bd422584813dca14d48 100644 (file)
@@ -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)
index 154037749a6c2a59976e7e8f735b366be6c80de5..20643d1c395e82e5dc7ceba5091892c6b0c8acc8 100644 (file)
@@ -530,7 +530,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;
@@ -705,7 +706,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);