]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mtd: spinand: Add a ->configure_chip() hook
authorMiquel Raynal <miquel.raynal@bootlin.com>
Sat, 13 Sep 2025 15:30:47 +0000 (11:30 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Sep 2025 14:37:33 +0000 (16:37 +0200)
[ Upstream commit da55809ebb45d1d80b7a388ffef841ed683e1a6f ]

There is already a manufacturer hook, which is manufacturer specific but
not chip specific. We no longer have access to the actual NAND identity
at this stage so let's add a per-chip configuration hook to align the
chip configuration (if any) with the core's setting.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Stable-dep-of: 4550d33e1811 ("mtd: spinand: winbond: Fix oob_layout for W25N01JW")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/mtd/nand/spi/core.c
include/linux/mtd/spinand.h

index b90f15c986a3177f70e4874d08575edc7aec7987..83e5e79e2f0db99395b56a90732ffdacf3a7c186 100644 (file)
@@ -1253,8 +1253,19 @@ static int spinand_id_detect(struct spinand_device *spinand)
 
 static int spinand_manufacturer_init(struct spinand_device *spinand)
 {
-       if (spinand->manufacturer->ops->init)
-               return spinand->manufacturer->ops->init(spinand);
+       int ret;
+
+       if (spinand->manufacturer->ops->init) {
+               ret = spinand->manufacturer->ops->init(spinand);
+               if (ret)
+                       return ret;
+       }
+
+       if (spinand->configure_chip) {
+               ret = spinand->configure_chip(spinand);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
@@ -1349,6 +1360,7 @@ int spinand_match_and_init(struct spinand_device *spinand,
                spinand->flags = table[i].flags;
                spinand->id.len = 1 + table[i].devid.len;
                spinand->select_target = table[i].select_target;
+               spinand->configure_chip = table[i].configure_chip;
                spinand->set_cont_read = table[i].set_cont_read;
                spinand->fact_otp = &table[i].fact_otp;
                spinand->user_otp = &table[i].user_otp;
index 15eaa09da998cec3f4999ca805f7bfb6b881a5f7..c13b088ef75f15ab7972bf9260595950587a94dd 100644 (file)
@@ -484,6 +484,7 @@ struct spinand_user_otp {
  * @op_variants.update_cache: variants of the update-cache operation
  * @select_target: function used to select a target/die. Required only for
  *                multi-die chips
+ * @configure_chip: Align the chip configuration with the core settings
  * @set_cont_read: enable/disable continuous cached reads
  * @fact_otp: SPI NAND factory OTP info.
  * @user_otp: SPI NAND user OTP info.
@@ -507,6 +508,7 @@ struct spinand_info {
        } op_variants;
        int (*select_target)(struct spinand_device *spinand,
                             unsigned int target);
+       int (*configure_chip)(struct spinand_device *spinand);
        int (*set_cont_read)(struct spinand_device *spinand,
                             bool enable);
        struct spinand_fact_otp fact_otp;
@@ -539,6 +541,9 @@ struct spinand_info {
 #define SPINAND_SELECT_TARGET(__func)                                  \
        .select_target = __func
 
+#define SPINAND_CONFIGURE_CHIP(__configure_chip)                       \
+       .configure_chip = __configure_chip
+
 #define SPINAND_CONT_READ(__set_cont_read)                             \
        .set_cont_read = __set_cont_read
 
@@ -607,6 +612,7 @@ struct spinand_dirmap {
  *             passed in spi_mem_op be DMA-able, so we can't based the bufs on
  *             the stack
  * @manufacturer: SPI NAND manufacturer information
+ * @configure_chip: Align the chip configuration with the core settings
  * @cont_read_possible: Field filled by the core once the whole system
  *             configuration is known to tell whether continuous reads are
  *             suitable to use or not in general with this chip/configuration.
@@ -647,6 +653,7 @@ struct spinand_device {
        const struct spinand_manufacturer *manufacturer;
        void *priv;
 
+       int (*configure_chip)(struct spinand_device *spinand);
        bool cont_read_possible;
        int (*set_cont_read)(struct spinand_device *spinand,
                             bool enable);