From 47c3697e25d5167a60d6a3253f2da47452ba0a97 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Sat, 10 Sep 2022 00:01:10 +0200 Subject: [PATCH 01/76] dt-bindings: mtd: rockchip: add rockchip,rk3128-nfc Add rockchip,rk3128-nfc compatible string. Signed-off-by: Johan Jonker Acked-by: Krzysztof Kozlowski Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/f09665c1-9938-38c1-9a31-f196a3ef9cf0@gmail.com --- .../devicetree/bindings/mtd/rockchip,nand-controller.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml index d681a4676f069..566f330851f7b 100644 --- a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml @@ -19,7 +19,9 @@ properties: - const: rockchip,rk2928-nfc - const: rockchip,rv1108-nfc - items: - - const: rockchip,rk3036-nfc + - enum: + - rockchip,rk3036-nfc + - rockchip,rk3128-nfc - const: rockchip,rk2928-nfc - items: - const: rockchip,rk3308-nfc From 78e2d5410a440bc232c2f5eedb6ab0403e9675b6 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 22 Sep 2022 23:06:54 +0800 Subject: [PATCH 02/76] mtd: rawnand: gpmi: using pm_runtime_resume_and_get instead of pm_runtime_get_sync Using the newest pm_runtime_resume_and_get is more appropriate for simplifing code here. Signed-off-by: Zhang Qilong Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220922150654.117568-1-zhangqilong3@huawei.com --- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 01ccbde748f30..ada83344b0f92 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -148,11 +148,9 @@ static int gpmi_init(struct gpmi_nand_data *this) struct resources *r = &this->resources; int ret; - ret = pm_runtime_get_sync(this->dev); - if (ret < 0) { - pm_runtime_put_noidle(this->dev); + ret = pm_runtime_resume_and_get(this->dev); + if (ret < 0) return ret; - } ret = gpmi_reset_block(r->gpmi_regs, false); if (ret) @@ -2504,11 +2502,9 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, for (i = 0; i < GPMI_MAX_TRANSFERS; i++) this->transfers[i].direction = DMA_NONE; - ret = pm_runtime_get_sync(this->dev); - if (ret < 0) { - pm_runtime_put_noidle(this->dev); + ret = pm_runtime_resume_and_get(this->dev); + if (ret < 0) return ret; - } /* * This driver currently supports only one NAND chip. Plus, dies share From d4353decd4fdec71b9f9d1ba8fa85b7e595e8924 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Thu, 29 Sep 2022 14:34:31 +0200 Subject: [PATCH 03/76] MAINTAINERS: rectify entry for MESON NAND controller bindings Commit fbc00b5e746f ("dt-bindings: nand: meson: convert txt to yaml") converts amlogic,meson-nand.txt to yaml, but misses to adjust its reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Repair this file reference in MESON NAND CONTROLLER DRIVER FOR AMLOGIC SOCS. Signed-off-by: Lukas Bulwahn Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220929123431.23180-1-lukas.bulwahn@gmail.com --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index cf0f185023724..358d7383d2286 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13376,7 +13376,7 @@ MESON NAND CONTROLLER DRIVER FOR AMLOGIC SOCS M: Liang Yang L: linux-mtd@lists.infradead.org S: Maintained -F: Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt +F: Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml F: drivers/mtd/nand/raw/meson_* MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS From 782e32a990d9d7029a8400f09a4d02b1ba78cb77 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 28 Sep 2022 16:00:18 -0700 Subject: [PATCH 04/76] mtd: rawnand: lpc32xx_mlc: switch to using gpiod API This switches the driver from legacy gpio API to a newer gpiod API. Signed-off-by: Dmitry Torokhov Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220928230019.2140896-1-dmitry.torokhov@gmail.com --- drivers/mtd/nand/raw/lpc32xx_mlc.c | 36 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c index 452ecaf7775ac..306e2c2165011 100644 --- a/drivers/mtd/nand/raw/lpc32xx_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -122,7 +122,6 @@ struct lpc32xx_nand_cfg_mlc { uint32_t rd_low; uint32_t wr_high; uint32_t wr_low; - int wp_gpio; struct mtd_partition *parts; unsigned num_parts; }; @@ -177,6 +176,7 @@ struct lpc32xx_nand_host { struct nand_chip nand_chip; struct lpc32xx_mlc_platform_data *pdata; struct clk *clk; + struct gpio_desc *wp_gpio; void __iomem *io_base; int irq; struct lpc32xx_nand_cfg_mlc *ncfg; @@ -370,8 +370,8 @@ static int lpc32xx_waitfunc(struct nand_chip *chip) */ static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) { - if (gpio_is_valid(host->ncfg->wp_gpio)) - gpio_set_value(host->ncfg->wp_gpio, 0); + if (host->wp_gpio) + gpiod_set_value_cansleep(host->wp_gpio, 1); } /* @@ -379,8 +379,8 @@ static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) */ static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) { - if (gpio_is_valid(host->ncfg->wp_gpio)) - gpio_set_value(host->ncfg->wp_gpio, 1); + if (host->wp_gpio) + gpiod_set_value_cansleep(host->wp_gpio, 0); } static void lpc32xx_dma_complete_func(void *completion) @@ -636,8 +636,6 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev) return NULL; } - ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0); - return ncfg; } @@ -713,14 +711,18 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) "Missing or bad NAND config from device tree\n"); return -ENOENT; } - if (host->ncfg->wp_gpio == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (gpio_is_valid(host->ncfg->wp_gpio) && - gpio_request(host->ncfg->wp_gpio, "NAND WP")) { - dev_err(&pdev->dev, "GPIO not available\n"); - return -EBUSY; + + /* Start with WP disabled, if available */ + host->wp_gpio = gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); + res = PTR_ERR_OR_ZERO(host->wp_gpio); + if (res) { + if (res != -EPROBE_DEFER) + dev_err(&pdev->dev, "WP GPIO is not available: %d\n", + res); + return res; } - lpc32xx_wp_disable(host); + + gpiod_set_consumer_name(host->wp_gpio, "NAND WP"); host->pdata = dev_get_platdata(&pdev->dev); @@ -817,7 +819,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) clk_put(host->clk); free_gpio: lpc32xx_wp_enable(host); - gpio_free(host->ncfg->wp_gpio); + gpiod_put(host->wp_gpio); return res; } @@ -843,7 +845,7 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) clk_put(host->clk); lpc32xx_wp_enable(host); - gpio_free(host->ncfg->wp_gpio); + gpiod_put(host->wp_gpio); return 0; } From 6b923db2867cb5e18ac4a1d5d5b4eecf0b619538 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 28 Sep 2022 16:00:19 -0700 Subject: [PATCH 05/76] mtd: rawnand: lpc32xx_slc: switch to using gpiod API This switches the driver from legacy gpio API to a newer gpiod API. Signed-off-by: Dmitry Torokhov Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220928230019.2140896-2-dmitry.torokhov@gmail.com --- drivers/mtd/nand/raw/lpc32xx_slc.c | 33 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c index 6b7269cfb7d83..4702577f74e5d 100644 --- a/drivers/mtd/nand/raw/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c @@ -23,9 +23,8 @@ #include #include #include -#include +#include #include -#include #include #define LPC32XX_MODNAME "lpc32xx-nand" @@ -208,7 +207,6 @@ struct lpc32xx_nand_cfg_slc { uint32_t rwidth; uint32_t rhold; uint32_t rsetup; - int wp_gpio; struct mtd_partition *parts; unsigned num_parts; }; @@ -217,6 +215,7 @@ struct lpc32xx_nand_host { struct nand_chip nand_chip; struct lpc32xx_slc_platform_data *pdata; struct clk *clk; + struct gpio_desc *wp_gpio; void __iomem *io_base; struct lpc32xx_nand_cfg_slc *ncfg; @@ -309,8 +308,8 @@ static int lpc32xx_nand_device_ready(struct nand_chip *chip) */ static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) { - if (gpio_is_valid(host->ncfg->wp_gpio)) - gpio_set_value(host->ncfg->wp_gpio, 0); + if (host->wp_gpio) + gpiod_set_value_cansleep(host->wp_gpio, 1); } /* @@ -318,8 +317,8 @@ static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host) */ static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) { - if (gpio_is_valid(host->ncfg->wp_gpio)) - gpio_set_value(host->ncfg->wp_gpio, 1); + if (host->wp_gpio) + gpiod_set_value_cansleep(host->wp_gpio, 0); } /* @@ -764,8 +763,6 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev) return NULL; } - ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0); - return ncfg; } @@ -852,14 +849,18 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) "Missing or bad NAND config from device tree\n"); return -ENOENT; } - if (host->ncfg->wp_gpio == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev, - host->ncfg->wp_gpio, "NAND WP")) { - dev_err(&pdev->dev, "GPIO not available\n"); - return -EBUSY; + + /* Start with WP disabled, if available */ + host->wp_gpio = gpiod_get_optional(&pdev->dev, NULL, GPIOD_OUT_LOW); + res = PTR_ERR_OR_ZERO(host->wp_gpio); + if (res) { + if (res != -EPROBE_DEFER) + dev_err(&pdev->dev, "WP GPIO is not available: %d\n", + res); + return res; } - lpc32xx_wp_disable(host); + + gpiod_set_consumer_name(host->wp_gpio, "NAND WP"); host->pdata = dev_get_platdata(&pdev->dev); From 3fea699cb2d6c8c47289b16500590630f507d8fd Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 6 Oct 2022 07:29:12 +0200 Subject: [PATCH 06/76] mtd: rawnand: mpc5121: Replace NO_IRQ by 0 NO_IRQ is used to check the return of irq_of_parse_and_map(). On some architecture NO_IRQ is 0, on other architectures it is -1. irq_of_parse_and_map() returns 0 on error, independent of NO_IRQ. So use 0 instead of using NO_IRQ. Signed-off-by: Christophe Leroy Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/4e3ca3e0077ea124ea210c312e6e620f0f9e8bca.1665034065.git.christophe.leroy@csgroup.eu --- drivers/mtd/nand/raw/mpc5121_nfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c index 800d774aed8ef..f68349cb7824a 100644 --- a/drivers/mtd/nand/raw/mpc5121_nfc.c +++ b/drivers/mtd/nand/raw/mpc5121_nfc.c @@ -663,7 +663,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) } prv->irq = irq_of_parse_and_map(dn, 0); - if (prv->irq == NO_IRQ) { + if (!prv->irq) { dev_err(dev, "Error mapping IRQ!\n"); return -EINVAL; } From dbf70fc204d2fbb0d8ad8f42038a60846502efda Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Mon, 10 Oct 2022 13:51:09 +0300 Subject: [PATCH 07/76] mtd: spinand: winbond: fix flash identification Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1, but current driver uses only first 2 bytes of it for devices identification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22) is identified as W25N01GV (id_bytes: EF, AA, 21). Fix this by adding missed identification bytes. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Frieder Schrempf Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-1-mikhail.kshevetskiy@iopsys.eu --- drivers/mtd/nand/spi/winbond.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index 76684428354eb..ed368a55d68f2 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c @@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand, static const struct spinand_info winbond_spinand_table[] = { SPINAND_INFO("W25M02GV", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, @@ -86,7 +86,7 @@ static const struct spinand_info winbond_spinand_table[] = { SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), SPINAND_SELECT_TARGET(w25m02gv_select_target)), SPINAND_INFO("W25N01GV", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, From 6154c7a583483d7b69f53bea868efdc369edd563 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Mon, 10 Oct 2022 13:51:10 +0300 Subject: [PATCH 08/76] mtd: spinand: winbond: add Winbond W25N02KV flash support Add support of Winbond W25N02KV flash Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Frieder Schrempf Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-2-mikhail.kshevetskiy@iopsys.eu --- drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index ed368a55d68f2..3ad58cd284d8b 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c @@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct spinand_device *spinand, return spi_mem_exec_op(spinand->spimem, &op); } +static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + if (section > 3) + return -ERANGE; + + region->offset = 64 + (16 * section); + region->length = 13; + + return 0; +} + +static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + if (section > 3) + return -ERANGE; + + region->offset = (16 * section) + 2; + region->length = 14; + + return 0; +} + +static const struct mtd_ooblayout_ops w25n02kv_ooblayout = { + .ecc = w25n02kv_ooblayout_ecc, + .free = w25n02kv_ooblayout_free, +}; + +static int w25n02kv_ecc_get_status(struct spinand_device *spinand, + u8 status) +{ + struct nand_device *nand = spinand_to_nand(spinand); + u8 mbf = 0; + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); + + switch (status & STATUS_ECC_MASK) { + case STATUS_ECC_NO_BITFLIPS: + return 0; + + case STATUS_ECC_UNCOR_ERROR: + return -EBADMSG; + + case STATUS_ECC_HAS_BITFLIPS: + /* + * Let's try to retrieve the real maximum number of bitflips + * in order to avoid forcing the wear-leveling layer to move + * data around if it's not necessary. + */ + if (spi_mem_exec_op(spinand->spimem, &op)) + return nanddev_get_ecc_conf(nand)->strength; + + mbf >>= 4; + + if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) + return nanddev_get_ecc_conf(nand)->strength; + + return mbf; + + default: + break; + } + + return -EINVAL; +} + static const struct spinand_info winbond_spinand_table[] = { SPINAND_INFO("W25M02GV", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), @@ -94,6 +160,15 @@ static const struct spinand_info winbond_spinand_table[] = { &update_cache_variants), 0, SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), + SPINAND_INFO("W25N02KV", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + 0, + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), }; static int winbond_spinand_init(struct spinand_device *spinand) From 7c3fc99819fd812b00f1881537599e66b989e392 Mon Sep 17 00:00:00 2001 From: Valentin Korenblit Date: Tue, 18 Oct 2022 11:30:00 +0200 Subject: [PATCH 09/76] mtd: rawnand: cadence: support 64-bit slave dma interface 32-bit accesses on 64-bit sdma trigger sdma_err in intr_status register. Check dma capabilities before reading/writing from/to sdma interface. Link: https://lore.kernel.org/all/b7e5ebb4-0de8-4958-9bc4-fe06ec4c3635@www.fastmail.com/t/ Signed-off-by: Valentin Korenblit Reviewed-by: Arnd Bergmann Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221018093000.12072-1-vkorenblit@sequans.com --- .../mtd/nand/raw/cadence-nand-controller.c | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index 9dac3ca69d576..7661a5cf1883a 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -1184,6 +1184,14 @@ static int cadence_nand_hw_init(struct cdns_nand_ctrl *cdns_ctrl) if (cadence_nand_read_bch_caps(cdns_ctrl)) return -EIO; +#ifndef CONFIG_64BIT + if (cdns_ctrl->caps2.data_dma_width == 8) { + dev_err(cdns_ctrl->dev, + "cannot access 64-bit dma on !64-bit architectures"); + return -EIO; + } +#endif + /* * Set IO width access to 8. * It is because during SW device discovering width access @@ -1882,17 +1890,36 @@ static int cadence_nand_read_buf(struct cdns_nand_ctrl *cdns_ctrl, return status; if (!cdns_ctrl->caps1->has_dma) { - int len_in_words = len >> 2; + u8 data_dma_width = cdns_ctrl->caps2.data_dma_width; + + int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3; /* read alingment data */ - ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words); + if (data_dma_width == 4) + ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words); +#ifdef CONFIG_64BIT + else + readsq(cdns_ctrl->io.virt, buf, len_in_words); +#endif + if (sdma_size > len) { + int read_bytes = (data_dma_width == 4) ? + len_in_words << 2 : len_in_words << 3; + /* read rest data from slave DMA interface if any */ - ioread32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf, - sdma_size / 4 - len_in_words); + if (data_dma_width == 4) + ioread32_rep(cdns_ctrl->io.virt, + cdns_ctrl->buf, + sdma_size / 4 - len_in_words); +#ifdef CONFIG_64BIT + else + readsq(cdns_ctrl->io.virt, cdns_ctrl->buf, + sdma_size / 8 - len_in_words); +#endif + /* copy rest of data */ - memcpy(buf + (len_in_words << 2), cdns_ctrl->buf, - len - (len_in_words << 2)); + memcpy(buf + read_bytes, cdns_ctrl->buf, + len - read_bytes); } return 0; } @@ -1936,16 +1963,35 @@ static int cadence_nand_write_buf(struct cdns_nand_ctrl *cdns_ctrl, return status; if (!cdns_ctrl->caps1->has_dma) { - int len_in_words = len >> 2; + u8 data_dma_width = cdns_ctrl->caps2.data_dma_width; + + int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3; + + if (data_dma_width == 4) + iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words); +#ifdef CONFIG_64BIT + else + writesq(cdns_ctrl->io.virt, buf, len_in_words); +#endif - iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words); if (sdma_size > len) { + int written_bytes = (data_dma_width == 4) ? + len_in_words << 2 : len_in_words << 3; + /* copy rest of data */ - memcpy(cdns_ctrl->buf, buf + (len_in_words << 2), - len - (len_in_words << 2)); + memcpy(cdns_ctrl->buf, buf + written_bytes, + len - written_bytes); + /* write all expected by nand controller data */ - iowrite32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf, - sdma_size / 4 - len_in_words); + if (data_dma_width == 4) + iowrite32_rep(cdns_ctrl->io.virt, + cdns_ctrl->buf, + sdma_size / 4 - len_in_words); +#ifdef CONFIG_64BIT + else + writesq(cdns_ctrl->io.virt, cdns_ctrl->buf, + sdma_size / 8 - len_in_words); +#endif } return 0; From 7f2937efe18630832c8eae7a74e8c19fc1e7936e Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Thu, 8 Sep 2022 12:14:27 +0530 Subject: [PATCH 10/76] dt-bindings: mtd: spi-nor: Add reset-gpios property SPI-NOR flashes have RESET pin which can be toggled using GPIO controller, for those platforms reset-gpios property can be used to reset the flash device. Signed-off-by: Sai Krishna Potthuri Signed-off-by: Tudor Ambarus Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220908064428.2962-2-sai.krishna.potthuri@amd.com --- Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml index 7149784a36ac7..8a843b9b86731 100644 --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml @@ -70,6 +70,12 @@ properties: be used on such systems, to denote the absence of a reliable reset mechanism. + reset-gpios: + description: + A GPIO line connected to the RESET (active low) signal of the device. + If "broken-flash-reset" is present then having this property does not + make any difference. + partitions: type: object @@ -88,6 +94,7 @@ unevaluatedProperties: false examples: - | + #include spi { #address-cells = <1>; #size-cells = <0>; @@ -97,6 +104,7 @@ examples: reg = <0>; spi-max-frequency = <40000000>; m25p,fast-read; + reset-gpios = <&gpio 12 GPIO_ACTIVE_LOW>; }; }; ... From 8f1ee9ef71d0c0b185d2afc800e68d6addf29fe5 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Thu, 8 Sep 2022 12:14:28 +0530 Subject: [PATCH 11/76] mtd: spi-nor: Add support for flash reset Add support for spi-nor flash reset via GPIO controller by reading the reset-gpio property. If there is a valid GPIO specifier then reset will be performed by asserting and deasserting the GPIO using gpiod APIs otherwise it will not perform any operation. Signed-off-by: Sai Krishna Potthuri Signed-off-by: Tudor Ambarus Reviewed-by: Michael Walle Link: https://lore.kernel.org/r/20220908064428.2962-3-sai.krishna.potthuri@amd.com --- drivers/mtd/spi-nor/core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index f2c64006f8d75..a78ab9bae2be7 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2933,6 +2933,27 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor) mtd->_put_device = spi_nor_put_device; } +static int spi_nor_hw_reset(struct spi_nor *nor) +{ + struct gpio_desc *reset; + + reset = devm_gpiod_get_optional(nor->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR_OR_NULL(reset)) + return PTR_ERR_OR_ZERO(reset); + + /* + * Experimental delay values by looking at different flash device + * vendors datasheets. + */ + usleep_range(1, 5); + gpiod_set_value_cansleep(reset, 1); + usleep_range(100, 150); + gpiod_set_value_cansleep(reset, 0); + usleep_range(1000, 1200); + + return 0; +} + int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { @@ -2965,6 +2986,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (!nor->bouncebuf) return -ENOMEM; + ret = spi_nor_hw_reset(nor); + if (ret) + return ret; + info = spi_nor_get_flash_info(nor, name); if (IS_ERR(info)) return PTR_ERR(info); From d189614f24799ce150eaf3ecca8483c0a3697e9b Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 31 Aug 2022 13:59:03 +0900 Subject: [PATCH 12/76] mtd: spi-nor: sfdp: Update params->hwcaps.mask at xSPI profile 1.0 table parse Existece of xSPI profile 1.0 table implies that the flash supports read and program in 8D-8D-8D mode. Update the params->hwcaps.mask in spi_nor_parase_profile1(). Signed-off-by: Takahiro Kuwano Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/1b449bae6978f11f7636f2b5acb6435723963f59.1661915569.git.Takahiro.Kuwano@infineon.com --- drivers/mtd/spi-nor/sfdp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 2257f1b4c2e2d..15fb7f661ae9f 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -1183,10 +1183,17 @@ static int spi_nor_parse_profile1(struct spi_nor *nor, dummy = round_up(dummy, 2); /* Update the fast read settings. */ + nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR; spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR], 0, dummy, opcode, SNOR_PROTO_8_8_8_DTR); + /* + * Page Program is "Required Command" in the xSPI Profile 1.0. Update + * the params->hwcaps.mask here. + */ + nor->params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR; + out: kfree(dwords); return ret; From db391efe765cc6cfc0ffc8d8ef146dc8e6816a7e Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 31 Aug 2022 13:59:04 +0900 Subject: [PATCH 13/76] mtd: spi-nor: spansion: Remove NO_SFDP_FLAGS from s28hs512t info Read, Page Program, and Sector Erase settings are done in SFDP so we can remove NO_SFDP_FLAGS from s28hs512t info. Since the default_init() is no longer called after removing NO_SFDP_FLAGS, the initialization in the default_init() is moved to late_init(). Signed-off-by: Takahiro Kuwano Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/12e468992f5d0cbd474abff3203100cc8163d4e5.1661915569.git.Takahiro.Kuwano@infineon.com --- drivers/mtd/spi-nor/spansion.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 0150049007be1..a14308422ee6d 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -275,12 +275,6 @@ static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) cypress_nor_octal_dtr_dis(nor); } -static void s28hs512t_default_init(struct spi_nor *nor) -{ - nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; - nor->params->writesize = 16; -} - static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor) { /* @@ -316,10 +310,16 @@ static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, return cypress_nor_set_page_size(nor); } +static void s28hs512t_late_init(struct spi_nor *nor) +{ + nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; + nor->params->writesize = 16; +} + static const struct spi_nor_fixups s28hs512t_fixups = { - .default_init = s28hs512t_default_init, .post_sfdp = s28hs512t_post_sfdp_fixup, .post_bfpt = s28hs512t_post_bfpt_fixup, + .late_init = s28hs512t_late_init, }; static int @@ -454,8 +454,7 @@ static const struct flash_info spansion_nor_parts[] = { { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1) FLAGS(SPI_NOR_NO_ERASE) }, { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_DTR_READ | - SPI_NOR_OCTAL_DTR_PP) + PARSE_SFDP .fixups = &s28hs512t_fixups, }, }; From 06051322704bf38cbd721e14bdbd6e43c8e6d7e1 Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 31 Aug 2022 13:59:05 +0900 Subject: [PATCH 14/76] mtd: spi-nor: spansion: Rename s28hs512t prefix Change prefix to support all other devices in SEMPER S28 family. Signed-off-by: Takahiro Kuwano Signed-off-by: Tudor Ambarus Reviewed-by: Michael Walle Link: https://lore.kernel.org/r/8cf6bc9bffd50e486867c0817de1fa56c5d308ec.1661915569.git.Takahiro.Kuwano@infineon.com --- drivers/mtd/spi-nor/spansion.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index a14308422ee6d..4278d3ad6343a 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -275,7 +275,7 @@ static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable) cypress_nor_octal_dtr_dis(nor); } -static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor) +static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor) { /* * On older versions of the flash the xSPI Profile 1.0 table has the @@ -303,23 +303,23 @@ static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor) nor->params->rdsr_addr_nbytes = 4; } -static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt) +static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt) { return cypress_nor_set_page_size(nor); } -static void s28hs512t_late_init(struct spi_nor *nor) +static void s28hx_t_late_init(struct spi_nor *nor) { nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable; nor->params->writesize = 16; } -static const struct spi_nor_fixups s28hs512t_fixups = { - .post_sfdp = s28hs512t_post_sfdp_fixup, - .post_bfpt = s28hs512t_post_bfpt_fixup, - .late_init = s28hs512t_late_init, +static const struct spi_nor_fixups s28hx_t_fixups = { + .post_sfdp = s28hx_t_post_sfdp_fixup, + .post_bfpt = s28hx_t_post_bfpt_fixup, + .late_init = s28hx_t_late_init, }; static int @@ -455,7 +455,7 @@ static const struct flash_info spansion_nor_parts[] = { FLAGS(SPI_NOR_NO_ERASE) }, { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256) PARSE_SFDP - .fixups = &s28hs512t_fixups, + .fixups = &s28hx_t_fixups, }, }; From aff1fa414a85f63f4ef5af75a9d1dc7e8f840e86 Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 31 Aug 2022 13:59:06 +0900 Subject: [PATCH 15/76] mtd: spi-nor: spansion: Add s28hl512t, s28hl01gt, and s28hs01gt info Add flash info table entries for s28hl512gt, s28hl01gt, and s28hs01gt. These devices have the same functionality as s28hs512t. Signed-off-by: Takahiro Kuwano Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/6350ac204c58b94b30d70c529bf194d953085ac6.1661915569.git.Takahiro.Kuwano@infineon.com --- drivers/mtd/spi-nor/spansion.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 4278d3ad6343a..bd9edfd3cd3c5 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -453,10 +453,22 @@ static const struct flash_info spansion_nor_parts[] = { .fixups = &s25hx_t_fixups }, { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1) FLAGS(SPI_NOR_NO_ERASE) }, + { "s28hl512t", INFO(0x345a1a, 0, 256 * 1024, 256) + PARSE_SFDP + .fixups = &s28hx_t_fixups, + }, + { "s28hl01gt", INFO(0x345a1b, 0, 256 * 1024, 512) + PARSE_SFDP + .fixups = &s28hx_t_fixups, + }, { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256) PARSE_SFDP .fixups = &s28hx_t_fixups, }, + { "s28hs01gt", INFO(0x345b1b, 0, 256 * 1024, 512) + PARSE_SFDP + .fixups = &s28hx_t_fixups, + }, }; /** From 05ebc1ccb8affcbaaa9f8b8fe56839cbfc9b9144 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 28 Jul 2022 07:14:50 +0300 Subject: [PATCH 16/76] mtd: spi-nor: spansion: Replace hardcoded values for addr_nbytes/addr_mode_nbytes We track in the core the internal address mode of the flash. Stop using hardcoded values for the number of bytes of address and use nor->addr_nbytes and nor->params->addr_mode_nbytes instead. Signed-off-by: Tudor Ambarus Tested-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220728041451.85559-2-tudor.ambarus@microchip.com --- drivers/mtd/spi-nor/spansion.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index bd9edfd3cd3c5..b621cdfd506fd 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -49,11 +49,13 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) struct spi_mem_op op; u8 *buf = nor->bouncebuf; int ret; + u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; /* Use 24 dummy cycles for memory array reads. */ *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24; op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR2V, 1, buf); + CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, + SPINOR_REG_CYPRESS_CFR2V, 1, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); if (ret) @@ -64,14 +66,16 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) /* Set the octal and DTR enable bits. */ buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN; op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR5V, 1, buf); + CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, + SPINOR_REG_CYPRESS_CFR5V, 1, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); if (ret) return ret; /* Read flash ID to make sure the switch was successful. */ - ret = spi_nor_read_id(nor, 4, 3, buf, SNOR_PROTO_8_8_8_DTR); + ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf, + SNOR_PROTO_8_8_8_DTR); if (ret) { dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret); return ret; @@ -97,7 +101,8 @@ static int cypress_nor_octal_dtr_dis(struct spi_nor *nor) buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS; buf[1] = 0; op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(4, SPINOR_REG_CYPRESS_CFR5V, 2, buf); + CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, + SPINOR_REG_CYPRESS_CFR5V, 2, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); if (ret) return ret; @@ -191,7 +196,8 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor) static int cypress_nor_set_page_size(struct spi_nor *nor) { struct spi_mem_op op = - CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR3V, + CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes, + SPINOR_REG_CYPRESS_CFR3V, nor->bouncebuf); int ret; From 2fe99a867050bc3506a4595acc01375a48a1b87e Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 28 Jul 2022 07:14:51 +0300 Subject: [PATCH 17/76] mtd: spi-nor: micron-st.c: Replace hardcoded values for addr_nbytes/addr_mode_nbytes We track in the core the internal address mode of the flash. Stop using hardcoded values for the number of bytes of address and use nor->addr_nbytes and nor->params->addr_mode_nbytes instead. Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20220728041451.85559-3-tudor.ambarus@microchip.com --- drivers/mtd/spi-nor/micron-st.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 3c9681a3f7a33..3c8a90b39c8c6 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -52,18 +52,21 @@ static int micron_st_nor_octal_dtr_en(struct spi_nor *nor) struct spi_mem_op op; u8 *buf = nor->bouncebuf; int ret; + u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; /* Use 20 dummy cycles for memory array reads. */ *buf = 20; op = (struct spi_mem_op) - MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR1V, 1, buf); + MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, + SPINOR_REG_MT_CFR1V, 1, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); if (ret) return ret; buf[0] = SPINOR_MT_OCT_DTR; op = (struct spi_mem_op) - MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR0V, 1, buf); + MICRON_ST_NOR_WR_ANY_REG_OP(addr_mode_nbytes, + SPINOR_REG_MT_CFR0V, 1, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); if (ret) return ret; @@ -98,7 +101,8 @@ static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor) buf[0] = SPINOR_MT_EXSPI; buf[1] = SPINOR_REG_MT_CFR1V_DEF; op = (struct spi_mem_op) - MICRON_ST_NOR_WR_ANY_REG_OP(4, SPINOR_REG_MT_CFR0V, 2, buf); + MICRON_ST_NOR_WR_ANY_REG_OP(nor->addr_nbytes, + SPINOR_REG_MT_CFR0V, 2, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); if (ret) return ret; From bb0e9c600ce23a308b31e73d10b56e70a5721088 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 28 Jul 2022 06:01:59 +0300 Subject: [PATCH 18/76] mtd: spi-nor: core: Add an error message when failing to exit the 4-byte address mode Add an error message when failing to exit the 4-byte address mode. Do not stop the execution and go through the spi_nor_soft_reset() method if used, in the hope that the flash will default to 3-byte address mode after the reset. Suggested-by: Pratyush Yadav Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20220728030159.68680-1-tudor.ambarus@microchip.com --- drivers/mtd/spi-nor/core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index a78ab9bae2be7..aa05443c44c2f 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2838,10 +2838,20 @@ static void spi_nor_put_device(struct mtd_info *mtd) void spi_nor_restore(struct spi_nor *nor) { + int ret; + /* restore the addressing mode */ if (nor->addr_nbytes == 4 && !(nor->flags & SNOR_F_4B_OPCODES) && - nor->flags & SNOR_F_BROKEN_RESET) - nor->params->set_4byte_addr_mode(nor, false); + nor->flags & SNOR_F_BROKEN_RESET) { + ret = nor->params->set_4byte_addr_mode(nor, false); + if (ret) + /* + * Do not stop the execution in the hope that the flash + * will default to the 3-byte address mode after the + * software reset. + */ + dev_err(nor->dev, "Failed to exit 4-byte address mode, err = %d\n", ret); + } if (nor->flags & SNOR_F_SOFT_RESET) spi_nor_soft_reset(nor); From c5f5d0cd40e3bc2d6d397af788a7c0241b1c6b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 4 Oct 2022 10:37:09 +0200 Subject: [PATCH 19/76] mtd: core: simplify (a bit) code find partition-matching dynamic OF node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Don't hardcode "partition-" string twice 2. Use simpler logic & use ->name to avoid of_property_read_string() 3. Use mtd_get_of_node() helper Cc: Christian Marangi Signed-off-by: Rafał Miłecki Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com --- drivers/mtd/mtdcore.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 0b4ca0aa41321..6ad62ff7be23d 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -551,18 +551,17 @@ static void mtd_check_of_node(struct mtd_info *mtd) struct device_node *partitions, *parent_dn, *mtd_dn = NULL; const char *pname, *prefix = "partition-"; int plen, mtd_name_len, offset, prefix_len; - struct mtd_info *parent; bool found = false; /* Check if MTD already has a device node */ - if (dev_of_node(&mtd->dev)) + if (mtd_get_of_node(mtd)) return; /* Check if a partitions node exist */ if (!mtd_is_partition(mtd)) return; - parent = mtd->parent; - parent_dn = of_node_get(dev_of_node(&parent->dev)); + + parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); if (!parent_dn) return; @@ -575,15 +574,15 @@ static void mtd_check_of_node(struct mtd_info *mtd) /* Search if a partition is defined with the same name */ for_each_child_of_node(partitions, mtd_dn) { - offset = 0; - /* Skip partition with no/wrong prefix */ - if (!of_node_name_prefix(mtd_dn, "partition-")) + if (!of_node_name_prefix(mtd_dn, prefix)) continue; /* Label have priority. Check that first */ - if (of_property_read_string(mtd_dn, "label", &pname)) { - of_property_read_string(mtd_dn, "name", &pname); + if (!of_property_read_string(mtd_dn, "label", &pname)) { + offset = 0; + } else { + pname = mtd_dn->name; offset = prefix_len; } From 2df11f00100d7278185a9dbefa20ba3f5d32401d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 4 Oct 2022 10:37:10 +0200 Subject: [PATCH 20/76] mtd: core: try to find OF node for every MTD partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far this feature was limited to the top-level "nvmem-cells" node. There are multiple parsers creating partitions and subpartitions dynamically. Extend that code to handle them too. This allows finding partition-* node for every MTD (sub)partition. Random example: partitions { compatible = "brcm,bcm947xx-cfe-partitions"; partition-firmware { compatible = "brcm,trx"; partition-loader { }; }; }; Cc: Christian Marangi Signed-off-by: Rafał Miłecki Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com --- drivers/mtd/mtdcore.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 6ad62ff7be23d..20fcedc3021e3 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -551,13 +551,11 @@ static void mtd_check_of_node(struct mtd_info *mtd) struct device_node *partitions, *parent_dn, *mtd_dn = NULL; const char *pname, *prefix = "partition-"; int plen, mtd_name_len, offset, prefix_len; - bool found = false; /* Check if MTD already has a device node */ if (mtd_get_of_node(mtd)) return; - /* Check if a partitions node exist */ if (!mtd_is_partition(mtd)) return; @@ -565,7 +563,10 @@ static void mtd_check_of_node(struct mtd_info *mtd) if (!parent_dn) return; - partitions = of_get_child_by_name(parent_dn, "partitions"); + if (mtd_is_partition(mtd->parent)) + partitions = of_node_get(parent_dn); + else + partitions = of_get_child_by_name(parent_dn, "partitions"); if (!partitions) goto exit_parent; @@ -589,19 +590,11 @@ static void mtd_check_of_node(struct mtd_info *mtd) plen = strlen(pname) - offset; if (plen == mtd_name_len && !strncmp(mtd->name, pname + offset, plen)) { - found = true; + mtd_set_of_node(mtd, mtd_dn); break; } } - if (!found) - goto exit_partitions; - - /* Set of_node only for nvmem */ - if (of_device_is_compatible(mtd_dn, "nvmem-cells")) - mtd_set_of_node(mtd, mtd_dn); - -exit_partitions: of_node_put(partitions); exit_parent: of_node_put(parent_dn); From 43cfba56d312f0a45e0b3eaa63606e05ae7fac14 Mon Sep 17 00:00:00 2001 From: Ray Zhang Date: Mon, 10 Oct 2022 04:55:47 +0000 Subject: [PATCH 21/76] mtd: mtdoops: change printk() to counterpart pr_ functions To comply with latest kernel code requirement, change printk() to counterpart pr_ functions in mtdoops driver: - change printk(INFO) to pr_info() - change printk(DEBUG) to pr_debug() - change printk(WARNING) to pr_warn() - change printk(ERR) to pr_err() Note that only if dynamic debugging is enabled or DEBUG is defined, printk(KERN_DEBUG) and pr_debug() are equivalent; Otherwise pr_debug() is no-op, causing different behavior. Signed-off-by: Ray Zhang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221010045549.2221965-2-sgzhang@google.com --- drivers/mtd/mtdoops.c | 52 ++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 3d4a2ffb5b01f..6b70331da3b62 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -7,6 +7,8 @@ * Author: Richard Purdie */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -93,9 +95,9 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset) ret = mtd_erase(mtd, &erase); if (ret) { - printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", - (unsigned long long)erase.addr, - (unsigned long long)erase.len, mtddev); + pr_warn("erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", + (unsigned long long)erase.addr, + (unsigned long long)erase.len, mtddev); return ret; } @@ -120,8 +122,8 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) return; } - printk(KERN_DEBUG "mtdoops: ready %d, %d (no erase)\n", - cxt->nextpage, cxt->nextcount); + pr_debug("ready %d, %d (no erase)\n", + cxt->nextpage, cxt->nextcount); } /* Scheduled work - when we can't proceed without erasing a block */ @@ -145,20 +147,20 @@ static void mtdoops_workfunc_erase(struct work_struct *work) while ((ret = mtd_block_isbad(mtd, cxt->nextpage * record_size)) > 0) { badblock: - printk(KERN_WARNING "mtdoops: bad block at %08lx\n", - cxt->nextpage * record_size); + pr_warn("bad block at %08lx\n", + cxt->nextpage * record_size); i++; cxt->nextpage = cxt->nextpage + (mtd->erasesize / record_size); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; if (i == cxt->oops_pages / (mtd->erasesize / record_size)) { - printk(KERN_ERR "mtdoops: all blocks bad!\n"); + pr_err("all blocks bad!\n"); return; } } if (ret < 0) { - printk(KERN_ERR "mtdoops: mtd_block_isbad failed, aborting\n"); + pr_err("mtd_block_isbad failed, aborting\n"); return; } @@ -166,15 +168,15 @@ static void mtdoops_workfunc_erase(struct work_struct *work) ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size); if (ret >= 0) { - printk(KERN_DEBUG "mtdoops: ready %d, %d\n", - cxt->nextpage, cxt->nextcount); + pr_debug("ready %d, %d\n", + cxt->nextpage, cxt->nextcount); return; } if (ret == -EIO) { ret = mtd_block_markbad(mtd, cxt->nextpage * record_size); if (ret < 0 && ret != -EOPNOTSUPP) { - printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); + pr_err("block_markbad failed, aborting\n"); return; } } @@ -201,7 +203,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) ret = mtd_panic_write(mtd, cxt->nextpage * record_size, record_size, &retlen, cxt->oops_buf); if (ret == -EOPNOTSUPP) { - printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n"); + pr_err("Cannot write from panic without panic_write\n"); goto out; } } else @@ -209,7 +211,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) record_size, &retlen, cxt->oops_buf); if (retlen != record_size || ret < 0) - printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n", + pr_err("write failure at %ld (%td of %ld written), error %d\n", cxt->nextpage * record_size, retlen, record_size, ret); mark_page_used(cxt, cxt->nextpage); memset(cxt->oops_buf, 0xff, record_size); @@ -244,7 +246,7 @@ static void find_next_position(struct mtdoops_context *cxt) &retlen, (u_char *)&hdr); if (retlen != sizeof(hdr) || (ret < 0 && !mtd_is_bitflip(ret))) { - printk(KERN_ERR "mtdoops: read failure at %ld (%zu of %zu read), err %d\n", + pr_err("read failure at %ld (%zu of %zu read), err %d\n", page * record_size, retlen, sizeof(hdr), ret); continue; } @@ -324,17 +326,17 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; if (mtd->size < mtd->erasesize * 2) { - printk(KERN_ERR "mtdoops: MTD partition %d not big enough for mtdoops\n", + pr_err("MTD partition %d not big enough for mtdoops\n", mtd->index); return; } if (mtd->erasesize < record_size) { - printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n", + pr_err("eraseblock size of MTD partition %d too small\n", mtd->index); return; } if (mtd->size > MTDOOPS_MAX_MTD_SIZE) { - printk(KERN_ERR "mtdoops: mtd%d is too large (limit is %d MiB)\n", + pr_err("mtd%d is too large (limit is %d MiB)\n", mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024); return; } @@ -345,7 +347,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) DIV_ROUND_UP(mtdoops_pages, BITS_PER_LONG))); if (!cxt->oops_page_used) { - printk(KERN_ERR "mtdoops: could not allocate page array\n"); + pr_err("could not allocate page array\n"); return; } @@ -353,7 +355,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { - printk(KERN_ERR "mtdoops: registering kmsg dumper failed, error %d\n", err); + pr_err("registering kmsg dumper failed, error %d\n", err); vfree(cxt->oops_page_used); cxt->oops_page_used = NULL; return; @@ -362,7 +364,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) cxt->mtd = mtd; cxt->oops_pages = (int)mtd->size / record_size; find_next_position(cxt); - printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index); + pr_info("Attached to MTD device %d\n", mtd->index); } static void mtdoops_notify_remove(struct mtd_info *mtd) @@ -373,7 +375,7 @@ static void mtdoops_notify_remove(struct mtd_info *mtd) return; if (kmsg_dump_unregister(&cxt->dump) < 0) - printk(KERN_WARNING "mtdoops: could not unregister kmsg_dumper\n"); + pr_warn("could not unregister kmsg_dumper\n"); cxt->mtd = NULL; flush_work(&cxt->work_erase); @@ -393,15 +395,15 @@ static int __init mtdoops_init(void) char *endp; if (strlen(mtddev) == 0) { - printk(KERN_ERR "mtdoops: mtd device (mtddev=name/number) must be supplied\n"); + pr_err("mtd device (mtddev=name/number) must be supplied\n"); return -EINVAL; } if ((record_size & 4095) != 0) { - printk(KERN_ERR "mtdoops: record_size must be a multiple of 4096\n"); + pr_err("record_size must be a multiple of 4096\n"); return -EINVAL; } if (record_size < 4096) { - printk(KERN_ERR "mtdoops: record_size must be over 4096 bytes\n"); + pr_err("record_size must be over 4096 bytes\n"); return -EINVAL; } From 340193e079a899f5527cddccff2b5de2c98bc31b Mon Sep 17 00:00:00 2001 From: Ray Zhang Date: Mon, 10 Oct 2022 04:55:48 +0000 Subject: [PATCH 22/76] mtd: mtdoops: add mtdoops_erase function and move mtdoops_inc_counter to after it Preparing for next patch with minimal code difference, add mtdoops_erase function and move mtdoops_inc_counter to after it, with no functional change. Signed-off-by: Ray Zhang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221010045549.2221965-3-sgzhang@google.com --- drivers/mtd/mtdoops.c | 49 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 6b70331da3b62..0226b9e9ea8f4 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -108,29 +108,8 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset) return 0; } -static void mtdoops_inc_counter(struct mtdoops_context *cxt) -{ - cxt->nextpage++; - if (cxt->nextpage >= cxt->oops_pages) - cxt->nextpage = 0; - cxt->nextcount++; - if (cxt->nextcount == 0xffffffff) - cxt->nextcount = 0; - - if (page_is_used(cxt, cxt->nextpage)) { - schedule_work(&cxt->work_erase); - return; - } - - pr_debug("ready %d, %d (no erase)\n", - cxt->nextpage, cxt->nextcount); -} - -/* Scheduled work - when we can't proceed without erasing a block */ -static void mtdoops_workfunc_erase(struct work_struct *work) +static void mtdoops_erase(struct mtdoops_context *cxt) { - struct mtdoops_context *cxt = - container_of(work, struct mtdoops_context, work_erase); struct mtd_info *mtd = cxt->mtd; int i = 0, j, ret, mod; @@ -183,6 +162,32 @@ static void mtdoops_workfunc_erase(struct work_struct *work) goto badblock; } +/* Scheduled work - when we can't proceed without erasing a block */ +static void mtdoops_workfunc_erase(struct work_struct *work) +{ + struct mtdoops_context *cxt = + container_of(work, struct mtdoops_context, work_erase); + mtdoops_erase(cxt); +} + +static void mtdoops_inc_counter(struct mtdoops_context *cxt) +{ + cxt->nextpage++; + if (cxt->nextpage >= cxt->oops_pages) + cxt->nextpage = 0; + cxt->nextcount++; + if (cxt->nextcount == 0xffffffff) + cxt->nextcount = 0; + + if (page_is_used(cxt, cxt->nextpage)) { + schedule_work(&cxt->work_erase); + return; + } + + pr_debug("ready %d, %d (no erase)\n", + cxt->nextpage, cxt->nextcount); +} + static void mtdoops_write(struct mtdoops_context *cxt, int panic) { struct mtd_info *mtd = cxt->mtd; From 7cc84e0e07d063c246809ea78f51607f858766bf Mon Sep 17 00:00:00 2001 From: Ray Zhang Date: Mon, 10 Oct 2022 04:55:49 +0000 Subject: [PATCH 23/76] mtd: mtdoops: panic caused mtdoops to call mtdoops_erase function immediately The panic function disables the local interrupts, preemption, and all other processors. When the invoked mtdoops needs to erase a used page, calling schedule_work() to do it will not work. Instead, just call mtdoops_erase function immediately. Tested: ~# echo c > /proc/sysrq-trigger [ 171.654759] sysrq: Trigger a crash [ 171.658325] Kernel panic - not syncing: sysrq triggered crash ...... [ 172.406423] mtdoops: not ready 34, 35 (erase immediately) [ 172.432285] mtdoops: ready 34, 35 [ 172.435633] Rebooting in 10 seconds.. Signed-off-by: Ray Zhang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221010045549.2221965-4-sgzhang@google.com --- drivers/mtd/mtdoops.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 0226b9e9ea8f4..2f11585b5613e 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -170,7 +170,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work) mtdoops_erase(cxt); } -static void mtdoops_inc_counter(struct mtdoops_context *cxt) +static void mtdoops_inc_counter(struct mtdoops_context *cxt, int panic) { cxt->nextpage++; if (cxt->nextpage >= cxt->oops_pages) @@ -180,12 +180,20 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) cxt->nextcount = 0; if (page_is_used(cxt, cxt->nextpage)) { - schedule_work(&cxt->work_erase); - return; + pr_debug("not ready %d, %d (erase %s)\n", + cxt->nextpage, cxt->nextcount, + panic ? "immediately" : "scheduled"); + if (panic) { + /* In case of panic, erase immediately */ + mtdoops_erase(cxt); + } else { + /* Otherwise, schedule work to erase it "nicely" */ + schedule_work(&cxt->work_erase); + } + } else { + pr_debug("ready %d, %d (no erase)\n", + cxt->nextpage, cxt->nextcount); } - - pr_debug("ready %d, %d (no erase)\n", - cxt->nextpage, cxt->nextcount); } static void mtdoops_write(struct mtdoops_context *cxt, int panic) @@ -221,7 +229,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) mark_page_used(cxt, cxt->nextpage); memset(cxt->oops_buf, 0xff, record_size); - mtdoops_inc_counter(cxt); + mtdoops_inc_counter(cxt, panic); out: clear_bit(0, &cxt->oops_buf_busy); } @@ -286,7 +294,7 @@ static void find_next_position(struct mtdoops_context *cxt) cxt->nextcount = maxcount; } - mtdoops_inc_counter(cxt); + mtdoops_inc_counter(cxt, 0); } static void mtdoops_do_dump(struct kmsg_dumper *dumper, From 132c57b4898755ae5d5f190f77d10b788d971b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 15 Oct 2022 11:29:49 +0200 Subject: [PATCH 24/76] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most TP-Link home routers use the same partitioning system based on a custom ASCII table. It doesn't seem to have any official name. GPL sources contain tool named simply "make_flash" and Makefile target "FlashMaker". This partitions table format was first found in devices with a custom SafeLoader bootloader so it was called SafeLoader by a community. Later it was ported to other bootloaders but it seems the name sticked. Add binding for describing flashes with SafeLoader partitions table. It allows operating systems to parse it properly and register proper flash layout. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-1-zajec5@gmail.com --- .../tplink,safeloader-partitions.yaml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml diff --git a/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml new file mode 100644 index 0000000000000..63e596aa0ca3d --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/tplink,safeloader-partitions.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TP-Link SafeLoader partitions + +description: | + TP-Link home routers store various data on flash (e.g. bootloader, + flash layout, firmware, product info, configuration, calibration + data). That requires flash partitioning. + + Flash space layout of TP-Link devices is stored on flash itself using + a custom ASCII-based format. That format was first found in TP-Link + devices with a custom SafeLoader bootloader. Later it was adapted to + CFE and U-Boot bootloaders. + + Partitions specified in partitions table cover whole flash space. Some + contain static data that shouldn't get modified (device's MAC or WiFi + calibration data). Others are semi-static (like kernel). Finally some + partitions contain fully changeable content (like rootfs). + + This binding describes partitioning method and defines offset of ASCII + based partitions table. That offset is picked at manufacturing process + and doesn't change. + +maintainers: + - Rafał Miłecki + +properties: + compatible: + const: tplink,safeloader-partitions + + partitions-table-offset: + description: Flash offset of partitions table + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - partitions-table-offset + +additionalProperties: false + +examples: + - | + partitions { + compatible = "tplink,safeloader-partitions"; + partitions-table-offset = <0x100000>; + }; From 00a3588084bee6f37bb2b1d343f96900cfe049bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 15 Oct 2022 11:29:50 +0200 Subject: [PATCH 25/76] mtd: parsers: add TP-Link SafeLoader partitions table parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This parser deals with most TP-Link home routers. It reads info about partitions and registers them in the MTD subsystem. Example from TP-Link Archer C5 V2: spi-nor spi0.0: s25fl128s1 (16384 Kbytes) 15 tplink-safeloader partitions found on MTD device spi0.0 Creating 15 MTD partitions on "spi0.0": 0x000000000000-0x000000040000 : "fs-uboot" 0x000000040000-0x000000440000 : "os-image" 0x000000440000-0x000000e40000 : "rootfs" 0x000000e40000-0x000000e40200 : "default-mac" 0x000000e40200-0x000000e40400 : "pin" 0x000000e40400-0x000000e40600 : "product-info" 0x000000e50000-0x000000e60000 : "partition-table" 0x000000e60000-0x000000e60200 : "soft-version" 0x000000e61000-0x000000e70000 : "support-list" 0x000000e70000-0x000000e80000 : "profile" 0x000000e80000-0x000000e90000 : "default-config" 0x000000e90000-0x000000ee0000 : "user-config" 0x000000ee0000-0x000000fe0000 : "log" 0x000000fe0000-0x000000ff0000 : "radio_bk" 0x000000ff0000-0x000001000000 : "radio" Signed-off-by: Rafał Miłecki Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com --- drivers/mtd/parsers/Kconfig | 15 +++ drivers/mtd/parsers/Makefile | 1 + drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 drivers/mtd/parsers/tplink_safeloader.c diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index aaa06050c9bc9..c258ba2a3a6f4 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -123,6 +123,21 @@ config MTD_AFS_PARTS for your particular device. It won't happen automatically. The 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. +config MTD_PARSER_TPLINK_SAFELOADER + tristate "TP-Link Safeloader partitions parser" + depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) + help + TP-Link home routers use flash partitions to store various data. Info + about flash space layout is stored in a partitions table using a + custom ASCII-based format. + + That format was first found in devices with SafeLoader bootloader and + was named after it. Later it was adapted to CFE and U-Boot + bootloaders. + + This driver reads partitions table, parses it and creates MTD + partitions. + config MTD_PARSER_TRX tristate "Parser for TRX format partitions" depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile index 23fa4de4016f1..0e70b621a1d84 100644 --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile @@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o diff --git a/drivers/mtd/parsers/tplink_safeloader.c b/drivers/mtd/parsers/tplink_safeloader.c new file mode 100644 index 0000000000000..23584a4773912 --- /dev/null +++ b/drivers/mtd/parsers/tplink_safeloader.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright © 2022 Rafał Miłecki + */ + +#include +#include +#include +#include +#include +#include + +#define TPLINK_SAFELOADER_DATA_OFFSET 4 +#define TPLINK_SAFELOADER_MAX_PARTS 32 + +struct safeloader_cmn_header { + __be32 size; + uint32_t unused; +} __packed; + +static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) +{ + struct safeloader_cmn_header hdr; + struct device_node *np; + size_t bytes_read; + size_t offset; + size_t size; + char *buf; + int err; + + np = mtd_get_of_node(mtd); + if (mtd_is_partition(mtd)) + of_node_get(np); + else + np = of_get_child_by_name(np, "partitions"); + + if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { + pr_err("Failed to get partitions table offset\n"); + goto err_put; + } + + err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); + if (err && !mtd_is_bitflip(err)) { + pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); + goto err_put; + } + + size = be32_to_cpu(hdr.size); + + buf = kmalloc(size + 1, GFP_KERNEL); + if (!buf) + goto err_put; + + err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); + goto err_kfree; + } + + buf[size] = '\0'; + + of_node_put(np); + + return buf; + +err_kfree: + kfree(buf); +err_put: + of_node_put(np); + return NULL; +} + +static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct mtd_partition *parts; + char name[65]; + size_t offset; + size_t bytes; + char *buf; + int idx; + int err; + + parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); + if (!parts) { + err = -ENOMEM; + goto err_out; + } + + buf = mtd_parser_tplink_safeloader_read_table(mtd); + if (!buf) { + err = -ENOENT; + goto err_out; + } + + for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; + idx < TPLINK_SAFELOADER_MAX_PARTS && + sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", + name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; + idx++, offset += bytes + 1) { + parts[idx].name = kstrdup(name, GFP_KERNEL); + if (!parts[idx].name) { + err = -ENOMEM; + goto err_free; + } + } + + if (idx == TPLINK_SAFELOADER_MAX_PARTS) + pr_warn("Reached maximum number of partitions!\n"); + + kfree(buf); + + *pparts = parts; + + return idx; + +err_free: + for (idx -= 1; idx >= 0; idx--) + kfree(parts[idx].name); +err_out: + return err; +}; + +static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, + int nr_parts) +{ + int i; + + for (i = 0; i < nr_parts; i++) + kfree(pparts[i].name); + + kfree(pparts); +} + +static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { + { .compatible = "tplink,safeloader-partitions" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); + +static struct mtd_part_parser mtd_parser_tplink_safeloader = { + .parse_fn = mtd_parser_tplink_safeloader_parse, + .cleanup = mtd_parser_tplink_safeloader_cleanup, + .name = "tplink-safeloader", + .of_match_table = mtd_parser_tplink_safeloader_of_match_table, +}; +module_mtd_part_parser(mtd_parser_tplink_safeloader); + +MODULE_LICENSE("GPL"); From 6c0a15a3dc6b45156c5b9568c8308e3f0d802af0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 Oct 2022 18:34:24 +0300 Subject: [PATCH 26/76] mtd: parsers: tplink_safeloader: fix uninitialized variable bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 64 bit systems, the highest 32 bits of the "offset" variable are not initialized. Also the existing code is not endian safe (it will fail on big endian systems). Change the type of "offset" to a u32. Fixes: aec4d5f5ffd0 ("mtd: parsers: add TP-Link SafeLoader partitions table parser") Signed-off-by: Dan Carpenter Acked-by: Rafał Miłecki Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/Y1gCALFWXYYwqV1P@kili --- drivers/mtd/parsers/tplink_safeloader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/parsers/tplink_safeloader.c b/drivers/mtd/parsers/tplink_safeloader.c index 23584a4773912..f601e7bd86279 100644 --- a/drivers/mtd/parsers/tplink_safeloader.c +++ b/drivers/mtd/parsers/tplink_safeloader.c @@ -23,8 +23,8 @@ static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) struct safeloader_cmn_header hdr; struct device_node *np; size_t bytes_read; - size_t offset; size_t size; + u32 offset; char *buf; int err; @@ -34,14 +34,14 @@ static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) else np = of_get_child_by_name(np, "partitions"); - if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { + if (of_property_read_u32(np, "partitions-table-offset", &offset)) { pr_err("Failed to get partitions table offset\n"); goto err_put; } err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); if (err && !mtd_is_bitflip(err)) { - pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); + pr_err("Failed to read from %s at 0x%x\n", mtd->name, offset); goto err_put; } From a6c5f12b0df22574f8eb02b0159bc71ac66c1a64 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 21 Oct 2022 17:49:36 +0200 Subject: [PATCH 27/76] mtd: remove lart flash driver The sa1100 lart platform was removed, so its flash driver is no longer useful. Signed-off-by: Arnd Bergmann Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221021155000.4108406-7-arnd@kernel.org --- drivers/mtd/devices/Kconfig | 8 - drivers/mtd/devices/Makefile | 1 - drivers/mtd/devices/lart.c | 682 ----------------------------------- 3 files changed, 691 deletions(-) delete mode 100644 drivers/mtd/devices/lart.c diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 79cb981ececc9..ff2f9e55ef28f 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -136,14 +136,6 @@ config MTD_PHRAM doesn't have access to, memory beyond the mem=xxx limit, nvram, memory on the video card, etc... -config MTD_LART - tristate "28F160xx flash driver for LART" - depends on SA1100_LART - help - This enables the flash driver for LART. Please note that you do - not need any mapping/chip driver for LART. This one does it all - for you, so go disable all of those if you enabled some of them (: - config MTD_MTDRAM tristate "Test driver using RAM" help diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 0362cf6bdc67f..d11eb2b8b6f85 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_MTD_PHRAM) += phram.o obj-$(CONFIG_MTD_PMC551) += pmc551.o obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o obj-$(CONFIG_MTD_MTDRAM) += mtdram.o -obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_MCHP23K256) += mchp23k256.o diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c deleted file mode 100644 index aecd441e4183c..0000000000000 --- a/drivers/mtd/devices/lart.c +++ /dev/null @@ -1,682 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -/* - * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. - * - * Author: Abraham vd Merwe - * - * Copyright (c) 2001, 2d3D, Inc. - * - * References: - * - * [1] 3 Volt Fast Boot Block Flash Memory" Intel Datasheet - * - Order Number: 290644-005 - * - January 2000 - * - * [2] MTD internal API documentation - * - http://www.linux-mtd.infradead.org/ - * - * Limitations: - * - * Even though this driver is written for 3 Volt Fast Boot - * Block Flash Memory, it is rather specific to LART. With - * Minor modifications, notably the without data/address line - * mangling and different bus settings, etc. it should be - * trivial to adapt to other platforms. - * - * If somebody would sponsor me a different board, I'll - * adapt the driver (: - */ - -/* debugging */ -//#define LART_DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SA1100_LART -#error This is for LART architecture only -#endif - -static char module_name[] = "lart"; - -/* - * These values is specific to 28Fxxxx3 flash memory. - * See section 2.3.1 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet - */ -#define FLASH_BLOCKSIZE_PARAM (4096 * BUSWIDTH) -#define FLASH_NUMBLOCKS_16m_PARAM 8 -#define FLASH_NUMBLOCKS_8m_PARAM 8 - -/* - * These values is specific to 28Fxxxx3 flash memory. - * See section 2.3.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet - */ -#define FLASH_BLOCKSIZE_MAIN (32768 * BUSWIDTH) -#define FLASH_NUMBLOCKS_16m_MAIN 31 -#define FLASH_NUMBLOCKS_8m_MAIN 15 - -/* - * These values are specific to LART - */ - -/* general */ -#define BUSWIDTH 4 /* don't change this - a lot of the code _will_ break if you change this */ -#define FLASH_OFFSET 0xe8000000 /* see linux/arch/arm/mach-sa1100/lart.c */ - -/* blob */ -#define NUM_BLOB_BLOCKS FLASH_NUMBLOCKS_16m_PARAM -#define PART_BLOB_START 0x00000000 -#define PART_BLOB_LEN (NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM) - -/* kernel */ -#define NUM_KERNEL_BLOCKS 7 -#define PART_KERNEL_START (PART_BLOB_START + PART_BLOB_LEN) -#define PART_KERNEL_LEN (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN) - -/* initial ramdisk */ -#define NUM_INITRD_BLOCKS 24 -#define PART_INITRD_START (PART_KERNEL_START + PART_KERNEL_LEN) -#define PART_INITRD_LEN (NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN) - -/* - * See section 4.0 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet - */ -#define READ_ARRAY 0x00FF00FF /* Read Array/Reset */ -#define READ_ID_CODES 0x00900090 /* Read Identifier Codes */ -#define ERASE_SETUP 0x00200020 /* Block Erase */ -#define ERASE_CONFIRM 0x00D000D0 /* Block Erase and Program Resume */ -#define PGM_SETUP 0x00400040 /* Program */ -#define STATUS_READ 0x00700070 /* Read Status Register */ -#define STATUS_CLEAR 0x00500050 /* Clear Status Register */ -#define STATUS_BUSY 0x00800080 /* Write State Machine Status (WSMS) */ -#define STATUS_ERASE_ERR 0x00200020 /* Erase Status (ES) */ -#define STATUS_PGM_ERR 0x00100010 /* Program Status (PS) */ - -/* - * See section 4.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet - */ -#define FLASH_MANUFACTURER 0x00890089 -#define FLASH_DEVICE_8mbit_TOP 0x88f188f1 -#define FLASH_DEVICE_8mbit_BOTTOM 0x88f288f2 -#define FLASH_DEVICE_16mbit_TOP 0x88f388f3 -#define FLASH_DEVICE_16mbit_BOTTOM 0x88f488f4 - -/***************************************************************************************************/ - -/* - * The data line mapping on LART is as follows: - * - * U2 CPU | U3 CPU - * ------------------- - * 0 20 | 0 12 - * 1 22 | 1 14 - * 2 19 | 2 11 - * 3 17 | 3 9 - * 4 24 | 4 0 - * 5 26 | 5 2 - * 6 31 | 6 7 - * 7 29 | 7 5 - * 8 21 | 8 13 - * 9 23 | 9 15 - * 10 18 | 10 10 - * 11 16 | 11 8 - * 12 25 | 12 1 - * 13 27 | 13 3 - * 14 30 | 14 6 - * 15 28 | 15 4 - */ - -/* Mangle data (x) */ -#define DATA_TO_FLASH(x) \ - ( \ - (((x) & 0x08009000) >> 11) + \ - (((x) & 0x00002000) >> 10) + \ - (((x) & 0x04004000) >> 8) + \ - (((x) & 0x00000010) >> 4) + \ - (((x) & 0x91000820) >> 3) + \ - (((x) & 0x22080080) >> 2) + \ - ((x) & 0x40000400) + \ - (((x) & 0x00040040) << 1) + \ - (((x) & 0x00110000) << 4) + \ - (((x) & 0x00220100) << 5) + \ - (((x) & 0x00800208) << 6) + \ - (((x) & 0x00400004) << 9) + \ - (((x) & 0x00000001) << 12) + \ - (((x) & 0x00000002) << 13) \ - ) - -/* Unmangle data (x) */ -#define FLASH_TO_DATA(x) \ - ( \ - (((x) & 0x00010012) << 11) + \ - (((x) & 0x00000008) << 10) + \ - (((x) & 0x00040040) << 8) + \ - (((x) & 0x00000001) << 4) + \ - (((x) & 0x12200104) << 3) + \ - (((x) & 0x08820020) << 2) + \ - ((x) & 0x40000400) + \ - (((x) & 0x00080080) >> 1) + \ - (((x) & 0x01100000) >> 4) + \ - (((x) & 0x04402000) >> 5) + \ - (((x) & 0x20008200) >> 6) + \ - (((x) & 0x80000800) >> 9) + \ - (((x) & 0x00001000) >> 12) + \ - (((x) & 0x00004000) >> 13) \ - ) - -/* - * The address line mapping on LART is as follows: - * - * U3 CPU | U2 CPU - * ------------------- - * 0 2 | 0 2 - * 1 3 | 1 3 - * 2 9 | 2 9 - * 3 13 | 3 8 - * 4 8 | 4 7 - * 5 12 | 5 6 - * 6 11 | 6 5 - * 7 10 | 7 4 - * 8 4 | 8 10 - * 9 5 | 9 11 - * 10 6 | 10 12 - * 11 7 | 11 13 - * - * BOOT BLOCK BOUNDARY - * - * 12 15 | 12 15 - * 13 14 | 13 14 - * 14 16 | 14 16 - * - * MAIN BLOCK BOUNDARY - * - * 15 17 | 15 18 - * 16 18 | 16 17 - * 17 20 | 17 20 - * 18 19 | 18 19 - * 19 21 | 19 21 - * - * As we can see from above, the addresses aren't mangled across - * block boundaries, so we don't need to worry about address - * translations except for sending/reading commands during - * initialization - */ - -/* Mangle address (x) on chip U2 */ -#define ADDR_TO_FLASH_U2(x) \ - ( \ - (((x) & 0x00000f00) >> 4) + \ - (((x) & 0x00042000) << 1) + \ - (((x) & 0x0009c003) << 2) + \ - (((x) & 0x00021080) << 3) + \ - (((x) & 0x00000010) << 4) + \ - (((x) & 0x00000040) << 5) + \ - (((x) & 0x00000024) << 7) + \ - (((x) & 0x00000008) << 10) \ - ) - -/* Unmangle address (x) on chip U2 */ -#define FLASH_U2_TO_ADDR(x) \ - ( \ - (((x) << 4) & 0x00000f00) + \ - (((x) >> 1) & 0x00042000) + \ - (((x) >> 2) & 0x0009c003) + \ - (((x) >> 3) & 0x00021080) + \ - (((x) >> 4) & 0x00000010) + \ - (((x) >> 5) & 0x00000040) + \ - (((x) >> 7) & 0x00000024) + \ - (((x) >> 10) & 0x00000008) \ - ) - -/* Mangle address (x) on chip U3 */ -#define ADDR_TO_FLASH_U3(x) \ - ( \ - (((x) & 0x00000080) >> 3) + \ - (((x) & 0x00000040) >> 1) + \ - (((x) & 0x00052020) << 1) + \ - (((x) & 0x00084f03) << 2) + \ - (((x) & 0x00029010) << 3) + \ - (((x) & 0x00000008) << 5) + \ - (((x) & 0x00000004) << 7) \ - ) - -/* Unmangle address (x) on chip U3 */ -#define FLASH_U3_TO_ADDR(x) \ - ( \ - (((x) << 3) & 0x00000080) + \ - (((x) << 1) & 0x00000040) + \ - (((x) >> 1) & 0x00052020) + \ - (((x) >> 2) & 0x00084f03) + \ - (((x) >> 3) & 0x00029010) + \ - (((x) >> 5) & 0x00000008) + \ - (((x) >> 7) & 0x00000004) \ - ) - -/***************************************************************************************************/ - -static __u8 read8 (__u32 offset) -{ - volatile __u8 *data = (__u8 *) (FLASH_OFFSET + offset); -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n", __func__, offset, *data); -#endif - return (*data); -} - -static __u32 read32 (__u32 offset) -{ - volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n", __func__, offset, *data); -#endif - return (*data); -} - -static void write32 (__u32 x,__u32 offset) -{ - volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset); - *data = x; -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, *data); -#endif -} - -/***************************************************************************************************/ - -/* - * Probe for 16mbit flash memory on a LART board without doing - * too much damage. Since we need to write 1 dword to memory, - * we're f**cked if this happens to be DRAM since we can't - * restore the memory (otherwise we might exit Read Array mode). - * - * Returns 1 if we found 16mbit flash memory on LART, 0 otherwise. - */ -static int flash_probe (void) -{ - __u32 manufacturer,devtype; - - /* setup "Read Identifier Codes" mode */ - write32 (DATA_TO_FLASH (READ_ID_CODES),0x00000000); - - /* probe U2. U2/U3 returns the same data since the first 3 - * address lines is mangled in the same way */ - manufacturer = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000000))); - devtype = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000001))); - - /* put the flash back into command mode */ - write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000); - - return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || devtype == FLASH_DEVICE_16mbit_BOTTOM)); -} - -/* - * Erase one block of flash memory at offset ``offset'' which is any - * address within the block which should be erased. - * - * Returns 1 if successful, 0 otherwise. - */ -static inline int erase_block (__u32 offset) -{ - __u32 status; - -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x\n", __func__, offset); -#endif - - /* erase and confirm */ - write32 (DATA_TO_FLASH (ERASE_SETUP),offset); - write32 (DATA_TO_FLASH (ERASE_CONFIRM),offset); - - /* wait for block erase to finish */ - do - { - write32 (DATA_TO_FLASH (STATUS_READ),offset); - status = FLASH_TO_DATA (read32 (offset)); - } - while ((~status & STATUS_BUSY) != 0); - - /* put the flash back into command mode */ - write32 (DATA_TO_FLASH (READ_ARRAY),offset); - - /* was the erase successful? */ - if ((status & STATUS_ERASE_ERR)) - { - printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",module_name,offset); - return (0); - } - - return (1); -} - -static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) -{ - __u32 addr,len; - int i,first; - -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); -#endif - - /* - * check that both start and end of the requested erase are - * aligned with the erasesize at the appropriate addresses. - * - * skip all erase regions which are ended before the start of - * the requested erase. Actually, to save on the calculations, - * we skip to the first erase region which starts after the - * start of the requested erase, and then go back one. - */ - for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ; - i--; - - /* - * ok, now i is pointing at the erase region in which this - * erase request starts. Check the start of the requested - * erase range is aligned with the erase size which is in - * effect here. - */ - if (i < 0 || (instr->addr & (mtd->eraseregions[i].erasesize - 1))) - return -EINVAL; - - /* Remember the erase region we start on */ - first = i; - - /* - * next, check that the end of the requested erase is aligned - * with the erase region at that address. - * - * as before, drop back one to point at the region in which - * the address actually falls - */ - for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ; - i--; - - /* is the end aligned on a block boundary? */ - if (i < 0 || ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1))) - return -EINVAL; - - addr = instr->addr; - len = instr->len; - - i = first; - - /* now erase those blocks */ - while (len) - { - if (!erase_block (addr)) - return (-EIO); - - addr += mtd->eraseregions[i].erasesize; - len -= mtd->eraseregions[i].erasesize; - - if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++; - } - - return (0); -} - -static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf) -{ -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); -#endif - - /* we always read len bytes */ - *retlen = len; - - /* first, we read bytes until we reach a dword boundary */ - if (from & (BUSWIDTH - 1)) - { - int gap = BUSWIDTH - (from & (BUSWIDTH - 1)); - - while (len && gap--) { - *buf++ = read8 (from++); - len--; - } - } - - /* now we read dwords until we reach a non-dword boundary */ - while (len >= BUSWIDTH) - { - *((__u32 *) buf) = read32 (from); - - buf += BUSWIDTH; - from += BUSWIDTH; - len -= BUSWIDTH; - } - - /* top up the last unaligned bytes */ - if (len & (BUSWIDTH - 1)) - while (len--) *buf++ = read8 (from++); - - return (0); -} - -/* - * Write one dword ``x'' to flash memory at offset ``offset''. ``offset'' - * must be 32 bits, i.e. it must be on a dword boundary. - * - * Returns 1 if successful, 0 otherwise. - */ -static inline int write_dword (__u32 offset,__u32 x) -{ - __u32 status; - -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n", __func__, offset, x); -#endif - - /* setup writing */ - write32 (DATA_TO_FLASH (PGM_SETUP),offset); - - /* write the data */ - write32 (x,offset); - - /* wait for the write to finish */ - do - { - write32 (DATA_TO_FLASH (STATUS_READ),offset); - status = FLASH_TO_DATA (read32 (offset)); - } - while ((~status & STATUS_BUSY) != 0); - - /* put the flash back into command mode */ - write32 (DATA_TO_FLASH (READ_ARRAY),offset); - - /* was the write successful? */ - if ((status & STATUS_PGM_ERR) || read32 (offset) != x) - { - printk (KERN_WARNING "%s: write error at address 0x%.8x.\n",module_name,offset); - return (0); - } - - return (1); -} - -static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf) -{ - __u8 tmp[4]; - int i,n; - -#ifdef LART_DEBUG - printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); -#endif - - /* sanity checks */ - if (!len) return (0); - - /* first, we write a 0xFF.... padded byte until we reach a dword boundary */ - if (to & (BUSWIDTH - 1)) - { - __u32 aligned = to & ~(BUSWIDTH - 1); - int gap = to - aligned; - - i = n = 0; - - while (gap--) tmp[i++] = 0xFF; - while (len && i < BUSWIDTH) { - tmp[i++] = buf[n++]; - len--; - } - while (i < BUSWIDTH) tmp[i++] = 0xFF; - - if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO); - - to += n; - buf += n; - *retlen += n; - } - - /* now we write dwords until we reach a non-dword boundary */ - while (len >= BUSWIDTH) - { - if (!write_dword (to,*((__u32 *) buf))) return (-EIO); - - to += BUSWIDTH; - buf += BUSWIDTH; - *retlen += BUSWIDTH; - len -= BUSWIDTH; - } - - /* top up the last unaligned bytes, padded with 0xFF.... */ - if (len & (BUSWIDTH - 1)) - { - i = n = 0; - - while (len--) tmp[i++] = buf[n++]; - while (i < BUSWIDTH) tmp[i++] = 0xFF; - - if (!write_dword (to,*((__u32 *) tmp))) return (-EIO); - - *retlen += n; - } - - return (0); -} - -/***************************************************************************************************/ - -static struct mtd_info mtd; - -static struct mtd_erase_region_info erase_regions[] = { - /* parameter blocks */ - { - .offset = 0x00000000, - .erasesize = FLASH_BLOCKSIZE_PARAM, - .numblocks = FLASH_NUMBLOCKS_16m_PARAM, - }, - /* main blocks */ - { - .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, - .erasesize = FLASH_BLOCKSIZE_MAIN, - .numblocks = FLASH_NUMBLOCKS_16m_MAIN, - } -}; - -static const struct mtd_partition lart_partitions[] = { - /* blob */ - { - .name = "blob", - .offset = PART_BLOB_START, - .size = PART_BLOB_LEN, - }, - /* kernel */ - { - .name = "kernel", - .offset = PART_KERNEL_START, /* MTDPART_OFS_APPEND */ - .size = PART_KERNEL_LEN, - }, - /* initial ramdisk / file system */ - { - .name = "file system", - .offset = PART_INITRD_START, /* MTDPART_OFS_APPEND */ - .size = PART_INITRD_LEN, /* MTDPART_SIZ_FULL */ - } -}; -#define NUM_PARTITIONS ARRAY_SIZE(lart_partitions) - -static int __init lart_flash_init (void) -{ - int result; - memset (&mtd,0,sizeof (mtd)); - printk ("MTD driver for LART. Written by Abraham vd Merwe \n"); - printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name); - if (!flash_probe ()) - { - printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name); - return (-ENXIO); - } - printk ("%s: This looks like a LART board to me.\n",module_name); - mtd.name = module_name; - mtd.type = MTD_NORFLASH; - mtd.writesize = 1; - mtd.writebufsize = 4; - mtd.flags = MTD_CAP_NORFLASH; - mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; - mtd.erasesize = FLASH_BLOCKSIZE_MAIN; - mtd.numeraseregions = ARRAY_SIZE(erase_regions); - mtd.eraseregions = erase_regions; - mtd._erase = flash_erase; - mtd._read = flash_read; - mtd._write = flash_write; - mtd.owner = THIS_MODULE; - -#ifdef LART_DEBUG - printk (KERN_DEBUG - "mtd.name = %s\n" - "mtd.size = 0x%.8x (%uM)\n" - "mtd.erasesize = 0x%.8x (%uK)\n" - "mtd.numeraseregions = %d\n", - mtd.name, - mtd.size,mtd.size / (1024*1024), - mtd.erasesize,mtd.erasesize / 1024, - mtd.numeraseregions); - - if (mtd.numeraseregions) - for (result = 0; result < mtd.numeraseregions; result++) - printk (KERN_DEBUG - "\n\n" - "mtd.eraseregions[%d].offset = 0x%.8x\n" - "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n" - "mtd.eraseregions[%d].numblocks = %d\n", - result,mtd.eraseregions[result].offset, - result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024, - result,mtd.eraseregions[result].numblocks); - - printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); - - for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) - printk (KERN_DEBUG - "\n\n" - "lart_partitions[%d].name = %s\n" - "lart_partitions[%d].offset = 0x%.8x\n" - "lart_partitions[%d].size = 0x%.8x (%uK)\n", - result,lart_partitions[result].name, - result,lart_partitions[result].offset, - result,lart_partitions[result].size,lart_partitions[result].size / 1024); -#endif - - result = mtd_device_register(&mtd, lart_partitions, - ARRAY_SIZE(lart_partitions)); - - return (result); -} - -static void __exit lart_flash_exit (void) -{ - mtd_device_unregister(&mtd); -} - -module_init (lart_flash_init); -module_exit (lart_flash_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Abraham vd Merwe "); -MODULE_DESCRIPTION("MTD driver for Intel 28F160F3 on LART board"); From 895d68a39481a75c680aa421546931fb11942fa6 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Sat, 22 Oct 2022 20:13:52 +0800 Subject: [PATCH 28/76] mtd: Fix device name leak when register device failed in add_mtd_device() There is a kmemleak when register device failed: unreferenced object 0xffff888101aab550 (size 8): comm "insmod", pid 3922, jiffies 4295277753 (age 925.408s) hex dump (first 8 bytes): 6d 74 64 30 00 88 ff ff mtd0.... backtrace: [<00000000bde26724>] __kmalloc_node_track_caller+0x4e/0x150 [<000000003c32b416>] kvasprintf+0xb0/0x130 [<000000001f7a8f15>] kobject_set_name_vargs+0x2f/0xb0 [<000000006e781163>] dev_set_name+0xab/0xe0 [<00000000e30d0c78>] add_mtd_device+0x4bb/0x700 [<00000000f3d34de7>] mtd_device_parse_register+0x2ac/0x3f0 [<00000000c0d88488>] 0xffffffffa0238457 [<00000000b40d0922>] 0xffffffffa02a008f [<0000000023d17b9d>] do_one_initcall+0x87/0x2a0 [<00000000770f6ca6>] do_init_module+0xdf/0x320 [<000000007b6768fe>] load_module+0x2f98/0x3330 [<00000000346bed5a>] __do_sys_finit_module+0x113/0x1b0 [<00000000674c2290>] do_syscall_64+0x35/0x80 [<000000004c6a8d97>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 If register device failed, should call put_device() to give up the reference. Fixes: 1f24b5a8ecbb ("[MTD] driver model updates") Signed-off-by: Zhang Xiaoxu Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221022121352.2534682-1-zhangxiaoxu5@huawei.com --- drivers/mtd/mtdcore.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 20fcedc3021e3..756fd27f4cfee 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -715,8 +715,10 @@ int add_mtd_device(struct mtd_info *mtd) mtd_check_of_node(mtd); of_node_get(mtd_get_of_node(mtd)); error = device_register(&mtd->dev); - if (error) + if (error) { + put_device(&mtd->dev); goto fail_added; + } /* Add the nvmem provider */ error = mtd_nvmem_add(mtd); From 2b9a31d762f0441ab87cb76524c005adf54d6719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 22 Oct 2022 23:13:17 +0200 Subject: [PATCH 29/76] dt-bindings: mtd: partitions: support marking rootfs partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux needs to know what to use as root device. On embedded devices with flash the only common way to specify that is cmdline & root= parameter. That solution works with U-Boot which is Linux & cmdline aware but isn't available with all market bootloaders. Also that method is fragile: 1. Requires specific probing order on multi-flash devices 2. Uses hardcoded partitions indexes A lot of devices use different partitioning methods. It may be "fixed-partitions" or some dynamic partitioning (e.g. based on parts table). For such cases allow "linux,rootfs" property to mark correct flash partition. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-1-zajec5@gmail.com --- .../devicetree/bindings/mtd/partitions/fixed-partitions.yaml | 1 + .../devicetree/bindings/mtd/partitions/partition.yaml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml index ad3ccd250802b..d66a6e3bcb560 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml @@ -84,6 +84,7 @@ examples: partition@0 { label = "filesystem"; reg = <0x00000000 0x1 0x00000000>; + linux,rootfs; }; }; diff --git a/Documentation/devicetree/bindings/mtd/partitions/partition.yaml b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml index f1a02d840b123..a25cd23a34c0b 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/partition.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml @@ -52,6 +52,10 @@ properties: immune to paired-pages corruptions type: boolean + linux,rootfs: + description: Marks partition that contains root filesystem to mount and boot + user space from + if: not: required: [ reg ] From 26422ac78e9d8767bd4aabfbae616b15edbf6a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 22 Oct 2022 23:13:18 +0200 Subject: [PATCH 30/76] mtd: core: set ROOT_DEV for partitions marked as rootfs in DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for "linux,rootfs" binding that is used to mark flash partition containing rootfs. It's useful for devices using device tree that don't have bootloader passing root info in cmdline. Signed-off-by: Rafał Miłecki Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com --- drivers/mtd/mtdcore.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 756fd27f4cfee..e0193054f8d9f 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -737,6 +738,17 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); mutex_unlock(&mtd_table_mutex); + + if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { + if (IS_BUILTIN(CONFIG_MTD)) { + pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); + } else { + pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", + mtd->index, mtd->name); + } + } + /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it From 1aadf01e5076b9ab6bf294b9622335c651314895 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Mon, 24 Oct 2022 14:51:09 +0800 Subject: [PATCH 31/76] mtd: core: fix possible resource leak in init_mtd() I got the error report while inject fault in init_mtd(): sysfs: cannot create duplicate filename '/devices/virtual/bdi/mtd-0' Call Trace: dump_stack_lvl+0x67/0x83 sysfs_warn_dup+0x60/0x70 sysfs_create_dir_ns+0x109/0x120 kobject_add_internal+0xce/0x2f0 kobject_add+0x98/0x110 device_add+0x179/0xc00 device_create_groups_vargs+0xf4/0x100 device_create+0x7b/0xb0 bdi_register_va.part.13+0x58/0x2d0 bdi_register+0x9b/0xb0 init_mtd+0x62/0x171 [mtd] do_one_initcall+0x6c/0x3c0 do_init_module+0x58/0x222 load_module+0x268e/0x27d0 __do_sys_finit_module+0xd5/0x140 do_syscall_64+0x37/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd kobject_add_internal failed for mtd-0 with -EEXIST, don't try to register things with the same name in the same directory. Error registering mtd class or bdi: -17 If init_mtdchar() fails in init_mtd(), mtd_bdi will not be unregistered, as a result, we can't load the mtd module again, to fix this by calling bdi_unregister(mtd_bdi) after out_procfs label. Fixes: 445caaa20c4d ("mtd: Allocate bdi objects dynamically") Signed-off-by: Gaosheng Cui Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221024065109.2050705-1-cuigaosheng1@huawei.com --- drivers/mtd/mtdcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index e0193054f8d9f..6c4683a5e5316 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -2489,6 +2489,7 @@ static int __init init_mtd(void) out_procfs: if (proc_mtd) remove_proc_entry("mtd", NULL); + bdi_unregister(mtd_bdi); bdi_put(mtd_bdi); err_bdi: class_unregister(&mtd_class); From 077dc37db1e1da1f0e6a745328e4caa6d414e501 Mon Sep 17 00:00:00 2001 From: Jilin Yuan Date: Fri, 28 Oct 2022 21:40:36 +0800 Subject: [PATCH 32/76] mtd: inftlcore: fix repeated words in comments Delete the redundant word 'it'. Signed-off-by: Jilin Yuan Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221028134036.63000-1-yuanjilin@cdjrlc.com --- drivers/mtd/inftlcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 58ca1c21ebe67..9739387cff8c9 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -356,7 +356,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned * Newest unit in chain now contains data from _all_ older units. * So go through and erase each unit in chain, oldest first. (This * is important, by doing oldest first if we crash/reboot then it - * it is relatively simple to clean up the mess). + * is relatively simple to clean up the mess). */ pr_debug("INFTL: want to erase virtual chain %d\n", thisVUC); From a50ae8c98e5766a4fcb78e76f13cc658b784eac1 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Tue, 18 Oct 2022 19:02:05 +0200 Subject: [PATCH 33/76] mtd: nand: drop EXPORT_SYMBOL_GPL for nanddev_erase() This function is only used within this module, so it is no longer necessary to use EXPORT_SYMBOL_GPL(). Signed-off-by: Dario Binacchi Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221018170205.1733958-1-dario.binacchi@amarulasolutions.com --- drivers/mtd/nand/core.c | 3 +-- include/linux/mtd/nand.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index dbd7b06524b37..7737b1a4a177b 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -126,7 +126,7 @@ EXPORT_SYMBOL_GPL(nanddev_isreserved); * * Return: 0 in case of success, a negative error code otherwise. */ -int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) +static int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) { if (nanddev_isbad(nand, pos) || nanddev_isreserved(nand, pos)) { pr_warn("attempt to erase a bad/reserved block @%llx\n", @@ -136,7 +136,6 @@ int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) return nand->ops->erase(nand, pos); } -EXPORT_SYMBOL_GPL(nanddev_erase); /** * nanddev_mtd_erase() - Generic mtd->_erase() implementation for NAND devices diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index c3693bb87b4c9..b2996dc987ff8 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -999,7 +999,6 @@ static inline bool nanddev_io_iter_end(struct nand_device *nand, bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos); bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos); -int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos); int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos); /* ECC related functions */ From 991cc42a276f1d9303674a04a351942e47c29a3f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 27 Oct 2022 15:10:27 +0200 Subject: [PATCH 34/76] mtd: rawnand: lpc32xx_mlc: Switch to using pm_ptr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The switch to using the gpiod API removed the last user of lpc32xx_wp_disable() outside #ifdef CONFIG_PM, causing build failures if CONFIG_PM=n: drivers/mtd/nand/raw/lpc32xx_mlc.c:380:13: error: ‘lpc32xx_wp_disable’ defined but not used [-Werror=unused-function] 380 | static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) | ^~~~~~~~~~~~~~~~~~ Fix this by switching from #ifdef CONFIG_PM to pm_ptr(), increasing compile-coverage as a side-effect. Reported-by: noreply@ellerman.id.au Fixes: 782e32a990d9d702 ("mtd: rawnand: lpc32xx_mlc: switch to using gpiod API") Signed-off-by: Geert Uytterhoeven Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221027131028.3838303-1-geert@linux-m68k.org --- drivers/mtd/nand/raw/lpc32xx_mlc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c index 306e2c2165011..ae7f6429a5f64 100644 --- a/drivers/mtd/nand/raw/lpc32xx_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c @@ -850,7 +850,6 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static int lpc32xx_nand_resume(struct platform_device *pdev) { struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); @@ -882,11 +881,6 @@ static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm) return 0; } -#else -#define lpc32xx_nand_resume NULL -#define lpc32xx_nand_suspend NULL -#endif - static const struct of_device_id lpc32xx_nand_match[] = { { .compatible = "nxp,lpc3220-mlc" }, { /* sentinel */ }, @@ -896,8 +890,8 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); static struct platform_driver lpc32xx_nand_driver = { .probe = lpc32xx_nand_probe, .remove = lpc32xx_nand_remove, - .resume = lpc32xx_nand_resume, - .suspend = lpc32xx_nand_suspend, + .resume = pm_ptr(lpc32xx_nand_resume), + .suspend = pm_ptr(lpc32xx_nand_suspend), .driver = { .name = DRV_NAME, .of_match_table = lpc32xx_nand_match, From bb144c285bd5585be101aaf5464ad8949ba1305d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 27 Oct 2022 15:10:28 +0200 Subject: [PATCH 35/76] mtd: rawnand: lpc32xx_slc: Switch to using pm_ptr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The switch to using the gpiod API removed the last user of lpc32xx_wp_disable() outside #ifdef CONFIG_PM, causing build failures if CONFIG_PM=n: drivers/mtd/nand/raw/lpc32xx_slc.c:318:13: error: ‘lpc32xx_wp_disable’ defined but not used [-Werror=unused-function] 318 | static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host) | ^~~~~~~~~~~~~~~~~~ Fix this by switching from #ifdef CONFIG_PM to pm_ptr(), increasing compile-coverage as a side-effect. Reported-by: noreply@ellerman.id.au Fixes: 6b923db2867cb5e1 ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") Signed-off-by: Geert Uytterhoeven Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221027131028.3838303-2-geert@linux-m68k.org --- drivers/mtd/nand/raw/lpc32xx_slc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c index 4702577f74e5d..6918737346c95 100644 --- a/drivers/mtd/nand/raw/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c @@ -969,7 +969,6 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static int lpc32xx_nand_resume(struct platform_device *pdev) { struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); @@ -1008,11 +1007,6 @@ static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm) return 0; } -#else -#define lpc32xx_nand_resume NULL -#define lpc32xx_nand_suspend NULL -#endif - static const struct of_device_id lpc32xx_nand_match[] = { { .compatible = "nxp,lpc3220-slc" }, { /* sentinel */ }, @@ -1022,8 +1016,8 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); static struct platform_driver lpc32xx_nand_driver = { .probe = lpc32xx_nand_probe, .remove = lpc32xx_nand_remove, - .resume = lpc32xx_nand_resume, - .suspend = lpc32xx_nand_suspend, + .resume = pm_ptr(lpc32xx_nand_resume), + .suspend = pm_ptr(lpc32xx_nand_suspend), .driver = { .name = LPC32XX_MODNAME, .of_match_table = lpc32xx_nand_match, From 075e181fba721d7af83dd1f2b65aed64703f5a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 4 Nov 2022 09:53:16 +0100 Subject: [PATCH 36/76] dt-bindings: mtd: brcm,brcmnand: update interrupts description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. DMA and EDU are mutually exclusive: don't allow both at the same time 2. Require interrupt-names for 2+ interrupts to avoid /guessing/ Reported-by: Florian Fainelli Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221104085316.24499-1-zajec5@gmail.com --- .../devicetree/bindings/mtd/brcm,brcmnand.yaml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml index dd5a64969e378..cd606a21b53b5 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml @@ -86,15 +86,15 @@ properties: minItems: 1 items: - description: NAND CTLRDY interrupt - - description: FLASH_DMA_DONE if flash DMA is available - - description: FLASH_EDU_DONE if EDU is available + - description: FLASH_DMA_DONE (if flash DMA is available) or FLASH_EDU_DONE (if EDU is available) interrupt-names: minItems: 1 items: - const: nand_ctlrdy - - const: flash_dma_done - - const: flash_edu_done + - enum: + - flash_dma_done + - flash_edu_done clocks: maxItems: 1 @@ -173,6 +173,13 @@ allOf: - const: nand - const: iproc-idm - const: iproc-ext + - if: + properties: + interrupts: + minItems: 2 + then: + required: + - interrupt-names unevaluatedProperties: false @@ -190,6 +197,7 @@ examples: reg-names = "nand", "flash-dma"; interrupt-parent = <&hif_intr2_intc>; interrupts = <24>, <4>; + interrupt-names = "nand_ctlrdy", "flash_dma_done"; #address-cells = <1>; #size-cells = <0>; From 9b533a6e41df8315422575764a7f9a72bda2d995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 8 Nov 2022 10:31:02 +0100 Subject: [PATCH 37/76] dt-bindings: mtd: partitions: allow SafeLoader dynamic subpartitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TP-Link SafeLoader partitioning means flash contains multiple partitions defined in the on-flash table. Some of those partitions may have a special meaning and may require describing additionally. Allow that. Signed-off-by: Rafał Miłecki Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221108093102.8360-1-zajec5@gmail.com --- .../mtd/partitions/tplink,safeloader-partitions.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml index 63e596aa0ca3d..a24bbaac3a906 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml @@ -36,6 +36,10 @@ properties: description: Flash offset of partitions table $ref: /schemas/types.yaml#/definitions/uint32 +patternProperties: + "^partition-.*$": + $ref: partition.yaml# + required: - partitions-table-offset @@ -46,4 +50,8 @@ examples: partitions { compatible = "tplink,safeloader-partitions"; partitions-table-offset = <0x100000>; + + partition-file-system { + linux,rootfs; + }; }; From 6bdd45d795adf9e73b38ced5e7f750cd199499ff Mon Sep 17 00:00:00 2001 From: Hui Tang Date: Mon, 14 Nov 2022 17:02:40 +0800 Subject: [PATCH 38/76] mtd: lpddr2_nvm: Fix possible null-ptr-deref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will cause null-ptr-deref when resource_size(add_range) invoked, if platform_get_resource() returns NULL. Fixes: 96ba9dd65788 ("mtd: lpddr: add driver for LPDDR2-NVM PCM memories") Signed-off-by: Hui Tang Acked-by: Uwe Kleine-König Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221114090240.244172-1-tanghui20@huawei.com --- drivers/mtd/lpddr/lpddr2_nvm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c index 367e2d906de02..e71af4c490969 100644 --- a/drivers/mtd/lpddr/lpddr2_nvm.c +++ b/drivers/mtd/lpddr/lpddr2_nvm.c @@ -433,6 +433,8 @@ static int lpddr2_nvm_probe(struct platform_device *pdev) /* lpddr2_nvm address range */ add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!add_range) + return -ENODEV; /* Populate map_info data structure */ *map = (struct map_info) { From 5d96ea42eb63da72ed2eb4c1769d3181706d8cf3 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:02:59 +0100 Subject: [PATCH 39/76] dt-bindings: mtd: Clarify all partition subnodes Over time the various ways to define MTD partitions has evolved. Most of the controllers support several different bindings. Let's define all possible choices in one file and mark the legacy ones deprecated. This way, we can just reference this file and avoid dupplicating these definitions. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-2-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/mtd.yaml | 17 ++++++++++ .../bindings/mtd/partitions/partitions.yaml | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/partitions/partitions.yaml diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml index 3498e485679b1..a6b498bbdbb6b 100644 --- a/Documentation/devicetree/bindings/mtd/mtd.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml @@ -21,7 +21,24 @@ properties: based name) in order to ease flash device identification and/or describe what they are used for. + '#address-cells': + deprecated: true + + '#size-cells': + deprecated: true + + partitions: + $ref: /schemas/mtd/partitions/partitions.yaml + patternProperties: + "@[0-9a-f]+$": + $ref: partitions/partition.yaml + deprecated: true + + "^partition@[0-9a-f]+": + $ref: partitions/partition.yaml + deprecated: true + "^otp(-[0-9]+)?$": type: object $ref: ../nvmem/nvmem.yaml# diff --git a/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml new file mode 100644 index 0000000000000..ff65795de2854 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/partitions.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Partitions + +description: | + This binding is generic and describes the content of the partitions container + node. All partition parsers must be referenced here. + +maintainers: + - Miquel Raynal + +properties: + compatible: true + + '#address-cells': + enum: [1, 2] + + '#size-cells': + enum: [1, 2] + +patternProperties: + "partition(-.+|@[0-9a-f]+)": + $ref: partition.yaml + +required: + - compatible + +# Temporary value, should be set to false when constraining the parsers list +additionalProperties: true From f902baa917b6c1f2d70d008b2ebbe5acf79ba392 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:00 +0100 Subject: [PATCH 40/76] dt-bindings: mtd: Remove useless file about partitions There is already a real partitions.yaml file, so assuming everybody knows hot to read yaml schema now, this text file is no longer needed, so drop it. Depending on the situation, the lines referring to this file are either dropped or edited to point to mtd.yaml which includes partition{,s}.yaml. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-3-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/atmel-nand.txt | 6 ++-- .../devicetree/bindings/mtd/ingenic,nand.yaml | 1 - .../devicetree/bindings/mtd/lpc32xx-mlc.txt | 2 +- .../devicetree/bindings/mtd/lpc32xx-slc.txt | 2 +- .../devicetree/bindings/mtd/mtk-nand.txt | 2 +- .../devicetree/bindings/mtd/partition.txt | 33 ------------------- drivers/mtd/parsers/Kconfig | 2 +- 7 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/partition.txt diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt index 3aa297c97ab61..50645828ac20a 100644 --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt @@ -45,10 +45,8 @@ Optional properties: - atmel,rb: an integer identifying the native Ready/Busy pin. Only meaningful on sama5 SoCs. -All generic properties described in -Documentation/devicetree/bindings/mtd/{common,nand}.txt also apply to the NAND -device node, and NAND partitions should be defined under the NAND node as -described in Documentation/devicetree/bindings/mtd/partition.txt. +All generic properties are described in the generic yaml files under +Documentation/devicetree/bindings/mtd/. * ECC engine (PMECC) bindings: diff --git a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml index 8c272c842bfd3..87b2944d0d1b5 100644 --- a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml +++ b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml @@ -34,7 +34,6 @@ properties: type: object description: Node containing description of fixed partitions. - See Documentation/devicetree/bindings/mtd/partition.txt patternProperties: "^nand@[a-f0-9]$": diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt index 6d60bc3063f51..64c06aa05ac71 100644 --- a/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt +++ b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt @@ -19,7 +19,7 @@ accuracy:) - nxp,wr_low: WR_LOW Optional subnodes: -- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt +- Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml Example: diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt index d94edc0fc554b..39f17630a3011 100644 --- a/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt +++ b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt @@ -20,7 +20,7 @@ clock speed:) - nxp,rsetup: Read setup time (R_SETUP) Optional subnodes: -- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt +- Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml Example: diff --git a/Documentation/devicetree/bindings/mtd/mtk-nand.txt b/Documentation/devicetree/bindings/mtd/mtk-nand.txt index 4d3ec5e4ff8a3..839ea2f93d043 100644 --- a/Documentation/devicetree/bindings/mtd/mtk-nand.txt +++ b/Documentation/devicetree/bindings/mtd/mtk-nand.txt @@ -131,7 +131,7 @@ Example: }; NAND chip optional subnodes: -- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt +- Partitions, see Documentation/devicetree/bindings/mtd/mtd.yaml Example: nand@0 { diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt deleted file mode 100644 index ead90e8274d6c..0000000000000 --- a/Documentation/devicetree/bindings/mtd/partition.txt +++ /dev/null @@ -1,33 +0,0 @@ -Flash partitions in device tree -=============================== - -Flash devices can be partitioned into one or more functional ranges (e.g. "boot -code", "nvram", "kernel"). - -Different devices may be partitioned in a different ways. Some may use a fixed -flash layout set at production time. Some may use on-flash table that describes -the geometry and naming/purpose of each functional region. It is also possible -to see these methods mixed. - -To assist system software in locating partitions, we allow describing which -method is used for a given flash device. To describe the method there should be -a subnode of the flash device that is named 'partitions'. It must have a -'compatible' property, which is used to identify the method to use. - -When a single partition is represented with a DT node (it depends on a used -format) it may also be described using above rules ('compatible' and optionally -some extra properties / subnodes). It allows describing more complex, -hierarchical (multi-level) layouts and should be used if there is some -significant relation between partitions or some partition internally uses -another partitioning method. - -Available bindings are listed in the "partitions" subdirectory. - - -Deprecated: partitions defined in flash node -============================================ - -For backwards compatibility partitions as direct subnodes of the flash device are -supported. This use is discouraged. -NOTE: also for backwards compatibility, direct subnodes that have a compatible -string are not considered partitions, as they may be used for other bindings. diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index c258ba2a3a6f4..00dfdc934ac89 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -75,7 +75,7 @@ config MTD_OF_PARTS This provides a open firmware device tree partition parser which derives the partition map from the children of the flash memory node, as described in - Documentation/devicetree/bindings/mtd/partition.txt. + Documentation/devicetree/bindings/mtd/mtd.yaml. config MTD_OF_PARTS_BCM4908 bool "BCM4908 partitioning support" From 71a2026a66511d3296cd657bd3066dbf2f5ab11e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:01 +0100 Subject: [PATCH 41/76] dt-bindings: mtd: nand-chip: Reference mtd.yaml A NAND chip is an MTD device. mtd.yaml already defines many useful and relevant properties, let's reference this file here to get access to these additional property definitions. Signed-off-by: Miquel Raynal Acked-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-4-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/nand-chip.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/nand-chip.yaml b/Documentation/devicetree/bindings/mtd/nand-chip.yaml index 97ac3a3fbb52c..8d5d2d3ef56bd 100644 --- a/Documentation/devicetree/bindings/mtd/nand-chip.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-chip.yaml @@ -9,6 +9,9 @@ title: NAND Chip and NAND Controller Generic Binding maintainers: - Miquel Raynal +allOf: + - $ref: "mtd.yaml#" + description: | This file covers the generic description of a NAND chip. It implies that the bus interface should not be taken into account: both raw NAND devices and From e598511b0bfe7d9fd5165d53f1afb94e1a9be62d Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:02 +0100 Subject: [PATCH 42/76] dt-bindings: mtd: nand: Drop common properties already defined in generic files generic files, so let's drop these properties from the individual NAND controller bindings when no additional information is provided rather than the possible presence of the property. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-5-miquel.raynal@bootlin.com --- .../bindings/mtd/allwinner,sun4i-a10-nand.yaml | 9 +-------- .../bindings/mtd/arasan,nand-controller.yaml | 5 +---- .../devicetree/bindings/mtd/intel,lgm-ebunand.yaml | 10 +--------- Documentation/devicetree/bindings/mtd/qcom,nandc.yaml | 3 --- 4 files changed, 3 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 4741864da48ee..65521924ee1ca 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -14,9 +14,6 @@ maintainers: - Maxime Ripard properties: - "#address-cells": true - "#size-cells": true - compatible: enum: - allwinner,sun4i-a10-nand @@ -49,11 +46,7 @@ properties: dma-names: const: rxtx - pinctrl-names: true - patternProperties: - "^pinctrl-[0-9]+$": true - "^nand@[a-f0-9]+$": type: object properties: @@ -91,6 +84,6 @@ required: - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false ... diff --git a/Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml index f013fb976d95c..d028269cdbaa1 100644 --- a/Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml @@ -35,9 +35,6 @@ properties: interrupts: maxItems: 1 - "#address-cells": true - "#size-cells": true - required: - compatible - reg @@ -45,7 +42,7 @@ required: - clock-names - interrupts -additionalProperties: true +unevaluatedProperties: true examples: - | diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml index 741c66ee06c37..7c83a328845e3 100644 --- a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +++ b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml @@ -39,12 +39,6 @@ properties: - const: tx - const: rx - "#address-cells": - const: 1 - - "#size-cells": - const: 0 - patternProperties: "^nand@[a-f0-9]+$": type: object @@ -67,10 +61,8 @@ required: - clocks - dmas - dma-names - - "#address-cells" - - "#size-cells" -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml index 482a2c068740f..3cc90c64e974a 100644 --- a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml +++ b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml @@ -31,9 +31,6 @@ properties: - const: core - const: aon - "#address-cells": true - "#size-cells": true - patternProperties: "^nand@[a-f0-9]$": type: object From 488f19adf040329cbc0f9d3bea4829ccd0ebb57b Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:03 +0100 Subject: [PATCH 43/76] dt-bindings: mtd: nand: Standardize the child node name In almost all the schema mentioning a NAND chip child node, the name of the subnode contains a single index number. In practice there are currently no controller supporting more than 8 cs so even the [a-f] numbers are not needed. But let's be safe and limit the number of touched files by just allow a single number everywhere, so in practice up to 16 CS at most. This value can anyway be limited in each schema. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-6-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml | 2 +- Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 65521924ee1ca..465aa69f0f10c 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -47,7 +47,7 @@ properties: const: rxtx patternProperties: - "^nand@[a-f0-9]+$": + "^nand@[a-f0-9]$": type: object properties: reg: diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml index 7c83a328845e3..d455b75a0b0b3 100644 --- a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +++ b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml @@ -40,7 +40,7 @@ properties: - const: rx patternProperties: - "^nand@[a-f0-9]+$": + "^nand@[a-f0-9]$": type: object properties: reg: From 73fc6320651ab13da88ee3f4a4bb7499f0b21e20 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:04 +0100 Subject: [PATCH 44/76] dt-bindings: mtd: ingenic: Mark partitions in the controller node as deprecated Defining partitions as subnodes of the controller has been deprecated long time ago, but unlike having partitions within the controller node, having an enveloppe named "partitions" (which is not itself within a chip subnode) is not that common, so keep this deprecated definition in this file. Signed-off-by: Miquel Raynal Acked-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-7-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/ingenic,nand.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml index 87b2944d0d1b5..90dbc5eba1e7e 100644 --- a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml +++ b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml @@ -32,6 +32,7 @@ properties: partitions: type: object + deprecated: true description: Node containing description of fixed partitions. From eb6fa33657da9526a9e5f43088d80b99a5c0315e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:05 +0100 Subject: [PATCH 45/76] dt-bindings: mtd: onenand: Mention the expected node name The chip node name in this driver is expected to be different and should be prefixed with onenand instead of the regular "flash" string, so mention it. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-8-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml index a953f7397c40a..8a79ad300216d 100644 --- a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml @@ -15,6 +15,9 @@ description: as child nodes of the GPMC controller. properties: + $nodename: + pattern: "^onenand@[0-9],[0,9]$" + compatible: const: ti,omap2-onenand From c68fc5ed9529987d69d34b367cb390b2285c3ac9 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:06 +0100 Subject: [PATCH 46/76] dt-bindings: mtd: sunxi-nand: Add an example to validate the bindings Copy-paste an existing DT node to ensure the dt_binding_check target would catch any unforeseen difference. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-9-miquel.raynal@bootlin.com --- .../mtd/allwinner,sun4i-a10-nand.yaml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml index 465aa69f0f10c..e7ec0c59bca6b 100644 --- a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml @@ -86,4 +86,27 @@ required: unevaluatedProperties: false +examples: + - | + #include + #include + #include + #include + + nand-controller@1c03000 { + compatible = "allwinner,sun8i-a23-nand-controller"; + reg = <0x01c03000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_NAND>, <&ccu CLK_NAND>; + clock-names = "ahb", "mod"; + resets = <&ccu RST_BUS_NAND>; + reset-names = "ahb"; + dmas = <&dma 5>; + dma-names = "rxtx"; + pinctrl-names = "default"; + pinctrl-0 = <&nand_pins &nand_cs0_pin &nand_rb0_pin>; + #address-cells = <1>; + #size-cells = <0>; + }; + ... From e9a399caf0314a69593b653ddf0efadbb11ffb9a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:07 +0100 Subject: [PATCH 47/76] dt-bindings: mtd: spi-nor: Drop common properties When redefining common properties does not bring any additional information, just drop them from the SPI-NOR bindings because these properties already are definied in mtd.yaml. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-10-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/jedec,spi-nor.yaml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml index 7149784a36ac7..6cc491083650a 100644 --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml @@ -70,20 +70,6 @@ properties: be used on such systems, to denote the absence of a reliable reset mechanism. - partitions: - type: object - - '#address-cells': true - '#size-cells': true - -patternProperties: - # Note: use 'partitions' node for new users - '^partition@': - type: object - - "^otp(-[0-9]+)?$": - type: object - unevaluatedProperties: false examples: From 7bdc671822e9099dd5328431867e4cf718b107f5 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:08 +0100 Subject: [PATCH 48/76] dt-bindings: mtd: physmap: Reuse the generic definitions The memory mapped MTD devices also share a lot with all the other MTD devices, so let's share the properties by referencing mtd.yaml. We can then drop mentioning the properties, to the cost of mentioning the possible "sram" node name prefix. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-11-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/mtd-physmap.yaml | 7 +++---- Documentation/devicetree/bindings/mtd/mtd.yaml | 2 +- Documentation/devicetree/bindings/mtd/nand-controller.yaml | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml index 82eb4e0f453b9..5df94953c34ee 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml @@ -13,6 +13,9 @@ description: | Flash chips (Memory Technology Devices) are often used for solid state file systems on embedded devices. +allOf: + - $ref: "mtd.yaml#" + properties: compatible: oneOf: @@ -121,10 +124,6 @@ properties: big-endian: true little-endian: true -patternProperties: - '@[0-9a-f]+$': - $ref: partitions/partition.yaml - required: - compatible - reg diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml index a6b498bbdbb6b..2fbd0a2ff5488 100644 --- a/Documentation/devicetree/bindings/mtd/mtd.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml @@ -12,7 +12,7 @@ maintainers: properties: $nodename: - pattern: "^flash(@.*)?$" + pattern: "^(flash|.*sram)(@.*)?$" label: description: diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index 359a015d4e5ad..3f2a1480e1ebc 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -51,7 +51,6 @@ properties: patternProperties: "^nand@[a-f0-9]$": - type: object $ref: "nand-chip.yaml#" properties: From 991088a637c54377b395520631bd1e8f068d524a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:09 +0100 Subject: [PATCH 49/76] dt-bindings: mtd: partitions: Constrain the list of parsers Parser compatibles cannot be used anywhere, and the list is limited. In order to constrain this list, enumerate them all under the top "partitions" subnode. New parsers will have to add their own compatible here as well. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-12-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/mtd.yaml | 3 +++ .../mtd/partitions/arm,arm-firmware-suite.yaml | 2 ++ .../mtd/partitions/brcm,bcm4908-partitions.yaml | 2 ++ .../mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml | 2 ++ .../mtd/partitions/linksys,ns-partitions.yaml | 2 ++ .../bindings/mtd/partitions/partitions.yaml | 12 ++++++++++-- .../bindings/mtd/partitions/qcom,smem-part.yaml | 2 ++ .../bindings/mtd/partitions/redboot-fis.yaml | 6 ++++++ 8 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml index 2fbd0a2ff5488..2494ec2d80e30 100644 --- a/Documentation/devicetree/bindings/mtd/mtd.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml @@ -30,6 +30,9 @@ properties: partitions: $ref: /schemas/mtd/partitions/partitions.yaml + required: + - compatible + patternProperties: "@[0-9a-f]+$": $ref: partitions/partition.yaml diff --git a/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml index 76c88027b6d28..97618847ee354 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.yaml @@ -9,6 +9,8 @@ title: ARM Firmware Suite (AFS) Partitions maintainers: - Linus Walleij +select: false + description: | The ARM Firmware Suite is a flash partitioning system found on the ARM reference designs: Integrator AP, Integrator CP, Versatile AB, diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml index 7b113e5e3421f..5bbb1c01ddee9 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml @@ -17,6 +17,8 @@ description: | maintainers: - Rafał Miłecki +select: false + properties: compatible: const: brcm,bcm4908-partitions diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml index 3484e06d6bcb8..939e7b50db222 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.yaml @@ -35,6 +35,8 @@ description: | maintainers: - Rafał Miłecki +select: false + properties: compatible: const: brcm,bcm947xx-cfe-partitions diff --git a/Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml index 99249cdfbfb31..213858f603754 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml @@ -18,6 +18,8 @@ description: | maintainers: - Rafał Miłecki +select: false + properties: compatible: const: linksys,ns-partitions diff --git a/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml index ff65795de2854..9aca4e6c6047a 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/partitions.yaml @@ -13,6 +13,15 @@ description: | maintainers: - Miquel Raynal +oneOf: + - $ref: arm,arm-firmware-suite.yaml + - $ref: brcm,bcm4908-partitions.yaml + - $ref: brcm,bcm947xx-cfe-partitions.yaml + - $ref: fixed-partitions.yaml + - $ref: linksys,ns-partitions.yaml + - $ref: qcom,smem-part.yaml + - $ref: redboot-fis.yaml + properties: compatible: true @@ -29,5 +38,4 @@ patternProperties: required: - compatible -# Temporary value, should be set to false when constraining the parsers list -additionalProperties: true +unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml index dc07909af0234..805eabece7c86 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml @@ -15,6 +15,8 @@ description: | varies between partition table revisions. V3 supports maximum 16 partitions and V4 supports 48 partitions. +select: false + properties: compatible: const: qcom,smem-part diff --git a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml index fee8d81b5276f..ba7445cd69e8f 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml @@ -16,6 +16,8 @@ description: The FLASH Image System (FIS) directory is a flash description maintainers: - Linus Walleij +select: false + properties: compatible: const: redboot-fis @@ -26,6 +28,10 @@ properties: device. On a flash memory with 32KB eraseblocks, 0 means the first eraseblock at 0x00000000, 1 means the second eraseblock at 0x00008000 and so on. + '#address-cells': false + + '#size-cells': false + required: - compatible - fis-index-block From e141ee8234d02727b421058df56f5959b7dc0ed0 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:10 +0100 Subject: [PATCH 50/76] dt-bindings: mtd: partitions: Change qcom,smem-part partition type As described in dd638202dfb6 ("dt-bindings: mtd: partitions: add additional example for qcom,smem-part"), the aim of documenting the subnodes was to be able to declare nvmem cells. Hence, the partition property does not really apply directly here, let's instead reference nvmem-cells.yaml first. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-13-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/partitions/qcom,smem-part.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml index 805eabece7c86..681a51f5257cc 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml @@ -23,7 +23,7 @@ properties: patternProperties: "^partition-[0-9a-z]+$": - $ref: partition.yaml# + $ref: nvmem-cells.yaml required: - compatible From c0fc45f7d305688f727fb44a66554233b1624ab9 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:11 +0100 Subject: [PATCH 51/76] dt-bindings: mtd: nvmem-cells: Drop range property from example Memory mapped devices such as parallel NOR flash could make use of the 'ranges' property to translate a nvmem 'reg' cell address to a CPU address but in practice there is no upstream user nor any declaration of this property being valid in this case yet, leading to a warning when constraining a bit more the schema: .../mtd/partitions/nvmem-cells.example.dtb: calibration@f00000: Unevaluated properties are not allowed ('ranges' was unexpected) So let's drop the property from the example, knowing that someone might actually properly define it some day. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-14-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/partitions/nvmem-cells.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml b/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml index 5cdd2efa9132d..ca18892eacc73 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml @@ -84,7 +84,6 @@ examples: compatible = "nvmem-cells"; label = "calibration"; reg = <0xf00000 0x100000>; - ranges = <0 0xf00000 0x100000>; #address-cells = <1>; #size-cells = <1>; From f4b37577a431fe1e79b859f6ad3890e29cfcf747 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:12 +0100 Subject: [PATCH 52/76] dt-bindings: mtd: nvmem-cells: Inherit from MTD partitions The aim of MTD nvmem-cells is to treat MTD partitions as NVMEM providers. Hence, MTD partition properties are valid here. Let's reference mtd/partition.yaml which gives us a chance to drop "additionalProperties: true" in favor of "unevaluatedProperties: false". Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-15-miquel.raynal@bootlin.com --- .../devicetree/bindings/mtd/partitions/nvmem-cells.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml b/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml index ca18892eacc73..5474d63268dc5 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml @@ -17,6 +17,7 @@ maintainers: - Ansuel Smith allOf: + - $ref: /schemas/mtd/partitions/partition.yaml# - $ref: /schemas/nvmem/nvmem.yaml# properties: @@ -26,7 +27,7 @@ properties: required: - compatible -additionalProperties: true +unevaluatedProperties: false examples: - | From d85cebfbc6f97b38a23527649758521a04b577e1 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:13 +0100 Subject: [PATCH 53/76] dt-bindings: mtd: Argue in favor of keeping additionalProperties set to true In most cases we try to avoid it but in some cases this is needed. Clarify why by adding a small comment. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-16-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/mtd.yaml | 1 + Documentation/devicetree/bindings/mtd/nand-chip.yaml | 1 + Documentation/devicetree/bindings/mtd/nand-controller.yaml | 1 + Documentation/devicetree/bindings/mtd/partitions/partition.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml index 2494ec2d80e30..9ee285b7d1623 100644 --- a/Documentation/devicetree/bindings/mtd/mtd.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml @@ -60,6 +60,7 @@ patternProperties: required: - compatible +# This is a generic file other binding inherit from additionalProperties: true examples: diff --git a/Documentation/devicetree/bindings/mtd/nand-chip.yaml b/Documentation/devicetree/bindings/mtd/nand-chip.yaml index 8d5d2d3ef56bd..6e2dc025d694d 100644 --- a/Documentation/devicetree/bindings/mtd/nand-chip.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-chip.yaml @@ -70,4 +70,5 @@ properties: required: - reg +# This file can be referenced by more specific devices (like spi-nands) additionalProperties: true diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index 3f2a1480e1ebc..220aa2c8c0b50 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -129,6 +129,7 @@ required: - "#address-cells" - "#size-cells" +# This is a generic file other binding inherit from and extend additionalProperties: true examples: diff --git a/Documentation/devicetree/bindings/mtd/partitions/partition.yaml b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml index a25cd23a34c0b..cdffbb9cedc2d 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/partition.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml @@ -64,4 +64,5 @@ then: $nodename: pattern: '^partition-.*$' +# This is a generic file other binding inherit from and extend additionalProperties: true From d963af0b23ca4a72d913b0ce56ce5e270dcfa00f Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:14 +0100 Subject: [PATCH 54/76] dt-bindings: mtd: Drop object types when referencing other files Setting an object type is redundant when a reference is made, so drop these useless lines. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-17-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/mtd.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml index 9ee285b7d1623..78da129e99852 100644 --- a/Documentation/devicetree/bindings/mtd/mtd.yaml +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml @@ -43,7 +43,6 @@ patternProperties: deprecated: true "^otp(-[0-9]+)?$": - type: object $ref: ../nvmem/nvmem.yaml# description: | From 74f4d7974d2fc88fa39538c0748a2e44ae6c8b9d Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 14 Nov 2022 10:03:15 +0100 Subject: [PATCH 55/76] dt-bindings: mtd: Standardize the style in the examples As recently requested by the binding maintaines, let's use 4 spaces in the examples. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20221114090315.848208-18-miquel.raynal@bootlin.com --- .../bindings/mtd/arm,pl353-nand-r2p1.yaml | 32 ++-- .../bindings/mtd/brcm,brcmnand.yaml | 80 +++++----- .../devicetree/bindings/mtd/denali,nand.yaml | 2 +- .../devicetree/bindings/mtd/ingenic,nand.yaml | 144 +++++++++--------- .../bindings/mtd/intel,lgm-ebunand.yaml | 38 ++--- .../bindings/mtd/microchip,mchp48l640.yaml | 16 +- .../mtd/partitions/qcom,smem-part.yaml | 34 ++--- .../devicetree/bindings/mtd/qcom,nandc.yaml | 128 ++++++++-------- .../bindings/mtd/st,stm32-fmc2-nand.yaml | 47 +++--- .../bindings/mtd/ti,am654-hbmc.yaml | 36 ++--- 10 files changed, 279 insertions(+), 278 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml b/Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml index 023f3ef0fa133..e552875040e24 100644 --- a/Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml +++ b/Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml @@ -34,20 +34,20 @@ unevaluatedProperties: false examples: - | smcc: memory-controller@e000e000 { - compatible = "arm,pl353-smc-r2p1", "arm,primecell"; - reg = <0xe000e000 0x0001000>; - clock-names = "memclk", "apb_pclk"; - clocks = <&clkc 11>, <&clkc 44>; - ranges = <0x0 0x0 0xe1000000 0x1000000 /* Nand CS region */ - 0x1 0x0 0xe2000000 0x2000000 /* SRAM/NOR CS0 region */ - 0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */ - #address-cells = <2>; - #size-cells = <1>; - - nfc0: nand-controller@0,0 { - compatible = "arm,pl353-nand-r2p1"; - reg = <0 0 0x1000000>; - #address-cells = <1>; - #size-cells = <0>; - }; + compatible = "arm,pl353-smc-r2p1", "arm,primecell"; + reg = <0xe000e000 0x0001000>; + clock-names = "memclk", "apb_pclk"; + clocks = <&clkc 11>, <&clkc 44>; + ranges = <0x0 0x0 0xe1000000 0x1000000 /* Nand CS region */ + 0x1 0x0 0xe2000000 0x2000000 /* SRAM/NOR CS0 region */ + 0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */ + #address-cells = <2>; + #size-cells = <1>; + + nfc0: nand-controller@0,0 { + compatible = "arm,pl353-nand-r2p1"; + reg = <0 0 0x1000000>; + #address-cells = <1>; + #size-cells = <0>; + }; }; diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml index dd5a64969e378..f9518d39fbbd5 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml @@ -184,51 +184,51 @@ required: examples: - | nand-controller@f0442800 { - compatible = "brcm,brcmnand-v7.0", "brcm,brcmnand"; - reg = <0xf0442800 0x600>, - <0xf0443000 0x100>; - reg-names = "nand", "flash-dma"; - interrupt-parent = <&hif_intr2_intc>; - interrupts = <24>, <4>; + compatible = "brcm,brcmnand-v7.0", "brcm,brcmnand"; + reg = <0xf0442800 0x600>, + <0xf0443000 0x100>; + reg-names = "nand", "flash-dma"; + interrupt-parent = <&hif_intr2_intc>; + interrupts = <24>, <4>; + + #address-cells = <1>; + #size-cells = <0>; + + nand@1 { + compatible = "brcm,nandcs"; + reg = <1>; // Chip select 1 + nand-on-flash-bbt; + nand-ecc-strength = <12>; + nand-ecc-step-size = <512>; #address-cells = <1>; - #size-cells = <0>; - - nand@1 { - compatible = "brcm,nandcs"; - reg = <1>; // Chip select 1 - nand-on-flash-bbt; - nand-ecc-strength = <12>; - nand-ecc-step-size = <512>; - - #address-cells = <1>; - #size-cells = <1>; - }; + #size-cells = <1>; + }; }; - | nand-controller@10000200 { - compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", - "brcm,brcmnand-v4.0", "brcm,brcmnand"; - reg = <0x10000200 0x180>, - <0x100000b0 0x10>, - <0x10000600 0x200>; - reg-names = "nand", "nand-int-base", "nand-cache"; - interrupt-parent = <&periph_intc>; - interrupts = <50>; - clocks = <&periph_clk 20>; - clock-names = "nand"; + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x100000b0 0x10>, + <0x10000600 0x200>; + reg-names = "nand", "nand-int-base", "nand-cache"; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + clocks = <&periph_clk 20>; + clock-names = "nand"; + + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <1>; + nand-ecc-step-size = <512>; #address-cells = <1>; - #size-cells = <0>; - - nand@0 { - compatible = "brcm,nandcs"; - reg = <0>; - nand-on-flash-bbt; - nand-ecc-strength = <1>; - nand-ecc-step-size = <512>; - - #address-cells = <1>; - #size-cells = <1>; - }; + #size-cells = <1>; + }; }; diff --git a/Documentation/devicetree/bindings/mtd/denali,nand.yaml b/Documentation/devicetree/bindings/mtd/denali,nand.yaml index 1307ed7e7fc69..0be83ad429705 100644 --- a/Documentation/devicetree/bindings/mtd/denali,nand.yaml +++ b/Documentation/devicetree/bindings/mtd/denali,nand.yaml @@ -145,6 +145,6 @@ examples: #size-cells = <0>; nand@0 { - reg = <0>; + reg = <0>; }; }; diff --git a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml index 90dbc5eba1e7e..a811a512ecc50 100644 --- a/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml +++ b/Documentation/devicetree/bindings/mtd/ingenic,nand.yaml @@ -58,78 +58,78 @@ examples: - | #include memory-controller@13410000 { - compatible = "ingenic,jz4780-nemc"; - reg = <0x13410000 0x10000>; - #address-cells = <2>; - #size-cells = <1>; - ranges = <1 0 0x1b000000 0x1000000>, - <2 0 0x1a000000 0x1000000>, - <3 0 0x19000000 0x1000000>, - <4 0 0x18000000 0x1000000>, - <5 0 0x17000000 0x1000000>, - <6 0 0x16000000 0x1000000>; - - clocks = <&cgu JZ4780_CLK_NEMC>; - - nand-controller@1 { - compatible = "ingenic,jz4780-nand"; - reg = <1 0 0x1000000>; - - #address-cells = <1>; - #size-cells = <0>; - - ecc-engine = <&bch>; - - ingenic,nemc-tAS = <10>; - ingenic,nemc-tAH = <5>; - ingenic,nemc-tBP = <10>; - ingenic,nemc-tAW = <15>; - ingenic,nemc-tSTRV = <100>; - - pinctrl-names = "default"; - pinctrl-0 = <&pins_nemc>; - - nand@1 { - reg = <1>; - - nand-ecc-step-size = <1024>; - nand-ecc-strength = <24>; - nand-ecc-mode = "hw"; - nand-on-flash-bbt; - - pinctrl-names = "default"; - pinctrl-0 = <&pins_nemc_cs1>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <2>; - #size-cells = <2>; - - partition@0 { - label = "u-boot-spl"; - reg = <0x0 0x0 0x0 0x800000>; + compatible = "ingenic,jz4780-nemc"; + reg = <0x13410000 0x10000>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0x1b000000 0x1000000>, + <2 0 0x1a000000 0x1000000>, + <3 0 0x19000000 0x1000000>, + <4 0 0x18000000 0x1000000>, + <5 0 0x17000000 0x1000000>, + <6 0 0x16000000 0x1000000>; + + clocks = <&cgu JZ4780_CLK_NEMC>; + + nand-controller@1 { + compatible = "ingenic,jz4780-nand"; + reg = <1 0 0x1000000>; + + #address-cells = <1>; + #size-cells = <0>; + + ecc-engine = <&bch>; + + ingenic,nemc-tAS = <10>; + ingenic,nemc-tAH = <5>; + ingenic,nemc-tBP = <10>; + ingenic,nemc-tAW = <15>; + ingenic,nemc-tSTRV = <100>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_nemc>; + + nand@1 { + reg = <1>; + + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_nemc_cs1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <2>; + #size-cells = <2>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x0 0x0 0x800000>; + }; + + partition@800000 { + label = "u-boot"; + reg = <0x0 0x800000 0x0 0x200000>; + }; + + partition@a00000 { + label = "u-boot-env"; + reg = <0x0 0xa00000 0x0 0x200000>; + }; + + partition@c00000 { + label = "boot"; + reg = <0x0 0xc00000 0x0 0x4000000>; + }; + + partition@4c00000 { + label = "system"; + reg = <0x0 0x4c00000 0x1 0xfb400000>; + }; + }; }; - - partition@800000 { - label = "u-boot"; - reg = <0x0 0x800000 0x0 0x200000>; - }; - - partition@a00000 { - label = "u-boot-env"; - reg = <0x0 0xa00000 0x0 0x200000>; - }; - - partition@c00000 { - label = "boot"; - reg = <0x0 0xc00000 0x0 0x4000000>; - }; - - partition@4c00000 { - label = "system"; - reg = <0x0 0x4c00000 0x1 0xfb400000>; - }; - }; }; - }; }; diff --git a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml index d455b75a0b0b3..8c62c7d3d0cd0 100644 --- a/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml +++ b/Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml @@ -67,25 +67,25 @@ unevaluatedProperties: false examples: - | nand-controller@e0f00000 { - compatible = "intel,lgm-ebunand"; - reg = <0xe0f00000 0x100>, - <0xe1000000 0x300>, - <0xe1400000 0x8000>, - <0xe1c00000 0x1000>, - <0x17400000 0x4>, - <0x17c00000 0x4>; - reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", - "addr_sel0", "addr_sel1"; - clocks = <&cgu0 125>; - dmas = <&dma0 8>, <&dma0 9>; - dma-names = "tx", "rx"; - #address-cells = <1>; - #size-cells = <0>; - - nand@0 { - reg = <0>; - nand-ecc-mode = "hw"; - }; + compatible = "intel,lgm-ebunand"; + reg = <0xe0f00000 0x100>, + <0xe1000000 0x300>, + <0xe1400000 0x8000>, + <0xe1c00000 0x1000>, + <0x17400000 0x4>, + <0x17c00000 0x4>; + reg-names = "ebunand", "hsnand", "nand_cs0", "nand_cs1", + "addr_sel0", "addr_sel1"; + clocks = <&cgu0 125>; + dmas = <&dma0 8>, <&dma0 9>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-ecc-mode = "hw"; + }; }; ... diff --git a/Documentation/devicetree/bindings/mtd/microchip,mchp48l640.yaml b/Documentation/devicetree/bindings/mtd/microchip,mchp48l640.yaml index 8cc2a7ceb5fb4..ea9450fe7c9fd 100644 --- a/Documentation/devicetree/bindings/mtd/microchip,mchp48l640.yaml +++ b/Documentation/devicetree/bindings/mtd/microchip,mchp48l640.yaml @@ -34,13 +34,13 @@ unevaluatedProperties: false examples: - | spi { - #address-cells = <1>; - #size-cells = <0>; - - eeram@0 { - compatible = "microchip,48l640"; - reg = <0>; - spi-max-frequency = <20000000>; - }; + #address-cells = <1>; + #size-cells = <0>; + + eeram@0 { + compatible = "microchip,48l640"; + reg = <0>; + spi-max-frequency = <20000000>; + }; }; ... diff --git a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml index 681a51f5257cc..61d12bda356e6 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/qcom,smem-part.yaml @@ -41,22 +41,22 @@ examples: - | /* Example declaring dynamic partition */ flash { - partitions { - compatible = "qcom,smem-part"; - - partition-art { - compatible = "nvmem-cells"; - #address-cells = <1>; - #size-cells = <1>; - label = "0:art"; - - macaddr_art_0: macaddr@0 { - reg = <0x0 0x6>; - }; - - macaddr_art_6: macaddr@6 { - reg = <0x6 0x6>; - }; + partitions { + compatible = "qcom,smem-part"; + + partition-art { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + label = "0:art"; + + macaddr_art_0: macaddr@0 { + reg = <0x0 0x6>; + }; + + macaddr_art_6: macaddr@6 { + reg = <0x6 0x6>; + }; + }; }; - }; }; diff --git a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml index 3cc90c64e974a..07024ee45951a 100644 --- a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml +++ b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml @@ -136,85 +136,85 @@ examples: - | #include nand-controller@1ac00000 { - compatible = "qcom,ipq806x-nand"; - reg = <0x1ac00000 0x800>; + compatible = "qcom,ipq806x-nand"; + reg = <0x1ac00000 0x800>; - clocks = <&gcc EBI2_CLK>, - <&gcc EBI2_AON_CLK>; - clock-names = "core", "aon"; + clocks = <&gcc EBI2_CLK>, + <&gcc EBI2_AON_CLK>; + clock-names = "core", "aon"; - dmas = <&adm_dma 3>; - dma-names = "rxtx"; - qcom,cmd-crci = <15>; - qcom,data-crci = <3>; + dmas = <&adm_dma 3>; + dma-names = "rxtx"; + qcom,cmd-crci = <15>; + qcom,data-crci = <3>; - #address-cells = <1>; - #size-cells = <0>; + #address-cells = <1>; + #size-cells = <0>; - nand@0 { - reg = <0>; + nand@0 { + reg = <0>; - nand-ecc-strength = <4>; - nand-bus-width = <8>; + nand-ecc-strength = <4>; + nand-bus-width = <8>; - qcom,boot-partitions = <0x0 0x58a0000>; + qcom,boot-partitions = <0x0 0x58a0000>; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; - partition@0 { - label = "boot-nand"; - reg = <0 0x58a0000>; - }; + partition@0 { + label = "boot-nand"; + reg = <0 0x58a0000>; + }; - partition@58a0000 { - label = "fs-nand"; - reg = <0x58a0000 0x4000000>; - }; + partition@58a0000 { + label = "fs-nand"; + reg = <0x58a0000 0x4000000>; + }; + }; }; - }; }; #include nand-controller@79b0000 { - compatible = "qcom,ipq4019-nand"; - reg = <0x79b0000 0x1000>; - - clocks = <&gcc GCC_QPIC_CLK>, - <&gcc GCC_QPIC_AHB_CLK>; - clock-names = "core", "aon"; - - dmas = <&qpicbam 0>, - <&qpicbam 1>, - <&qpicbam 2>; - dma-names = "tx", "rx", "cmd"; - - #address-cells = <1>; - #size-cells = <0>; - - nand@0 { - reg = <0>; - nand-ecc-strength = <4>; - nand-bus-width = <8>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "boot-nand"; - reg = <0 0x58a0000>; - }; - - partition@58a0000 { - label = "fs-nand"; - reg = <0x58a0000 0x4000000>; - }; + compatible = "qcom,ipq4019-nand"; + reg = <0x79b0000 0x1000>; + + clocks = <&gcc GCC_QPIC_CLK>, + <&gcc GCC_QPIC_AHB_CLK>; + clock-names = "core", "aon"; + + dmas = <&qpicbam 0>, + <&qpicbam 1>, + <&qpicbam 2>; + dma-names = "tx", "rx", "cmd"; + + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-ecc-strength = <4>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot-nand"; + reg = <0 0x58a0000>; + }; + + partition@58a0000 { + label = "fs-nand"; + reg = <0x58a0000 0x4000000>; + }; + }; }; - }; }; ... diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml index eab8ea3da1fa8..8cbfa1504a0f1 100644 --- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml @@ -101,31 +101,32 @@ examples: #include #include #include + nand-controller@58002000 { - compatible = "st,stm32mp15-fmc2"; - reg = <0x58002000 0x1000>, - <0x80000000 0x1000>, - <0x88010000 0x1000>, - <0x88020000 0x1000>, - <0x81000000 0x1000>, - <0x89010000 0x1000>, - <0x89020000 0x1000>; - interrupts = ; - dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, - <&mdma1 20 0x2 0x12000a08 0x0 0x0>, - <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; - dma-names = "tx", "rx", "ecc"; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; - #address-cells = <1>; - #size-cells = <0>; - - nand@0 { - reg = <0>; - nand-on-flash-bbt; + compatible = "st,stm32mp15-fmc2"; + reg = <0x58002000 0x1000>, + <0x80000000 0x1000>, + <0x88010000 0x1000>, + <0x88020000 0x1000>, + <0x81000000 0x1000>, + <0x89010000 0x1000>, + <0x89020000 0x1000>; + interrupts = ; + dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, + <&mdma1 20 0x2 0x12000a08 0x0 0x0>, + <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; + dma-names = "tx", "rx", "ecc"; + clocks = <&rcc FMC_K>; + resets = <&rcc FMC_R>; #address-cells = <1>; - #size-cells = <1>; - }; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + #address-cells = <1>; + #size-cells = <1>; + }; }; ... diff --git a/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml b/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml index 30b458c41cac3..4774c92e7fc4d 100644 --- a/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml +++ b/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.yaml @@ -44,26 +44,26 @@ additionalProperties: false examples: - | bus { - #address-cells = <2>; - #size-cells = <2>; - - hbmc: memory-controller@47034000 { - compatible = "ti,am654-hbmc"; - reg = <0x0 0x47034000 0x0 0x100>, - <0x5 0x00000000 0x1 0x0000000>; - ranges = <0x0 0x0 0x5 0x00000000 0x4000000>, /* CS0 - 64MB */ - <0x1 0x0 0x5 0x04000000 0x4000000>; /* CS1 - 64MB */ - clocks = <&k3_clks 102 0>; #address-cells = <2>; - #size-cells = <1>; - power-domains = <&k3_pds 55>; - mux-controls = <&hbmc_mux 0>; + #size-cells = <2>; - flash@0,0 { - compatible = "cypress,hyperflash", "cfi-flash"; - reg = <0x0 0x0 0x4000000>; - #address-cells = <1>; + hbmc: memory-controller@47034000 { + compatible = "ti,am654-hbmc"; + reg = <0x0 0x47034000 0x0 0x100>, + <0x5 0x00000000 0x1 0x0000000>; + ranges = <0x0 0x0 0x5 0x00000000 0x4000000>, /* CS0 - 64MB */ + <0x1 0x0 0x5 0x04000000 0x4000000>; /* CS1 - 64MB */ + clocks = <&k3_clks 102 0>; + #address-cells = <2>; #size-cells = <1>; + power-domains = <&k3_pds 55>; + mux-controls = <&hbmc_mux 0>; + + flash@0,0 { + compatible = "cypress,hyperflash", "cfi-flash"; + reg = <0x0 0x0 0x4000000>; + #address-cells = <1>; + #size-cells = <1>; + }; }; - }; }; From 2f05bff26c9e847ac5f68370eaf3e5f5d3bc58ce Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 11 Nov 2022 15:28:24 -0600 Subject: [PATCH 56/76] dt-bindings: mtd: fixed-partitions: Fix 'sercomm,scpart-id' schema The schema for 'sercomm,scpart-id' is broken. The 'if' condition is never true because 'compatible' is in the parent node, not the child node the sub-schema applies to. The example passes as there are no constraints on additional/unevaluated properties. That's a secondary issue which is complicated due to nested partitions. Drop the if/then schema and the unnecessary 'allOf' so that the 'sercomm,scpart-id' property is at least defined. Cc: Mikhail Zhilkin Signed-off-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221111212824.4103514-1-robh@kernel.org --- .../mtd/partitions/fixed-partitions.yaml | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml index d66a6e3bcb560..331e564f29dce 100644 --- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml +++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml @@ -31,24 +31,17 @@ properties: patternProperties: "@[0-9a-f]+$": - allOf: - - $ref: "partition.yaml#" - - if: - properties: - compatible: - contains: - const: sercomm,sc-partitions - then: - properties: - sercomm,scpart-id: - description: Partition id in Sercomm partition map. Mtd - parser uses this id to find a record in the partition map - containing offset and size of the current partition. The - values from partition map overrides partition offset and - size defined in reg property of the dts. Frequently these - values are the same, but may differ if device has bad - eraseblocks on a flash. - $ref: /schemas/types.yaml#/definitions/uint32 + $ref: partition.yaml# + + properties: + sercomm,scpart-id: + description: Partition id in Sercomm partition map. Mtd parser + uses this id to find a record in the partition map containing + offset and size of the current partition. The values from + partition map overrides partition offset and size defined in + reg property of the dts. Frequently these values are the same, + but may differ if device has bad eraseblocks on a flash. + $ref: /schemas/types.yaml#/definitions/uint32 required: - "#address-cells" From 085679b15b5af65f9610f619afde41da0f966194 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 16 Nov 2022 13:49:32 +0100 Subject: [PATCH 57/76] mtd: parsers: refer to ARCH_BCMBCA instead of ARCH_BCM4908 Commit dd5c672d7ca9 ("arm64: bcmbca: Merge ARCH_BCM4908 to ARCH_BCMBCA") removes config ARCH_BCM4908 as config ARCH_BCMBCA has the same intent. Probably due to concurrent development, commit 002181f5b150 ("mtd: parsers: add Broadcom's U-Boot parser") introduces 'Broadcom's U-Boot partition parser' that depends on ARCH_BCM4908, but this use was not visible during the config refactoring from the commit above. Hence, these two changes create a reference to a non-existing config symbol. Adjust the MTD_BRCM_U_BOOT definition to refer to ARCH_BCMBCA instead of ARCH_BCM4908 to remove the reference to the non-existing config symbol ARCH_BCM4908. Signed-off-by: Lukas Bulwahn Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221116124932.4748-1-lukas.bulwahn@gmail.com --- drivers/mtd/parsers/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index 00dfdc934ac89..b20e0c38b517d 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -22,7 +22,7 @@ config MTD_BCM63XX_PARTS config MTD_BRCM_U_BOOT tristate "Broadcom's U-Boot partition parser" - depends on ARCH_BCM4908 || COMPILE_TEST + depends on ARCH_BCMBCA || COMPILE_TEST help Broadcom uses a custom way of storing U-Boot environment variables. They are placed inside U-Boot partition itself at unspecified offset. From c13bf589e5cff0d05ce63c4832de3fab2a19c62d Mon Sep 17 00:00:00 2001 From: Hamish Martin Date: Thu, 10 Nov 2022 12:13:25 +1300 Subject: [PATCH 58/76] mtd: rawnand: marvell: Enable NFC/DEVBUS arbiter The CN9130 SoC (an ARMADA 8K type) has both a NAND Flash Controller and a generic local bus controller (Device Bus Controller) that share common pins. With a board design that incorporates both a NAND flash and uses the Device Bus (in our case for an SRAM) accessing the Device Bus device fails unless the NfArbiterEn bit is set. Setting the bit enables arbitration between the Device Bus and the NAND flash. Since there is no obvious downside in enabling this for designs that don't require arbitration, we always enable it. Signed-off-by: Hamish Martin Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221109231325.7714-1-hamish.martin@alliedtelesis.co.nz --- drivers/mtd/nand/raw/marvell_nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index d9f2f1d0b5efc..71e3751262b8a 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -114,6 +114,7 @@ #define GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST BIT(20) #define GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST BIT(21) #define GENCONF_SOC_DEVICE_MUX_NFC_INT_EN BIT(25) +#define GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN BIT(27) #define GENCONF_CLK_GATING_CTRL 0x220 #define GENCONF_CLK_GATING_CTRL_ND_GATE BIT(2) #define GENCONF_ND_CLK_CTRL 0x700 @@ -2880,7 +2881,8 @@ static int marvell_nfc_init(struct marvell_nfc *nfc) GENCONF_SOC_DEVICE_MUX_NFC_EN | GENCONF_SOC_DEVICE_MUX_ECC_CLK_RST | GENCONF_SOC_DEVICE_MUX_ECC_CORE_RST | - GENCONF_SOC_DEVICE_MUX_NFC_INT_EN); + GENCONF_SOC_DEVICE_MUX_NFC_INT_EN | + GENCONF_SOC_DEVICE_MUX_NFC_DEVBUS_ARB_EN); regmap_update_bits(sysctrl_base, GENCONF_CLK_GATING_CTRL, GENCONF_CLK_GATING_CTRL_ND_GATE, From 2ebc336be08160debfe27f87660cf550d710f3e9 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 19 Nov 2021 09:14:12 +0100 Subject: [PATCH 59/76] mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type() Erase can be zeroed in spi_nor_parse_4bait() or spi_nor_init_non_uniform_erase_map(). In practice it happened with mt25qu256a, which supports 4K, 32K, 64K erases with 3b address commands, but only 4K and 64K erase with 4b address commands. Fixes: dc92843159a7 ("mtd: spi-nor: fix erase_type array to indicate current map conf") Signed-off-by: Alexander Sverdlin Signed-off-by: Tudor Ambarus Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211119081412.29732-1-alexander.sverdlin@nokia.com --- drivers/mtd/spi-nor/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index aa05443c44c2f..0079758b36aa1 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1184,6 +1184,8 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map, continue; erase = &map->erase_type[i]; + if (!erase->size) + continue; /* Alignment is not mandatory for overlaid regions */ if (region->offset & SNOR_OVERLAID_REGION && From 7d388551b6888f3725e6c957f472526b35161a5b Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:48 +0200 Subject: [PATCH 60/76] mtd: spi-nor: hide jedec_id sysfs attribute if not present Some non-jedec compliant flashes (like the Everspin flashes) don't have an ID at all. Hide the attribute in this case. Fixes: 36ac02286265 ("mtd: spi-nor: add initial sysfs support") Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-2-michael@walle.cc --- .../ABI/testing/sysfs-bus-spi-devices-spi-nor | 3 +++ drivers/mtd/spi-nor/sysfs.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor index d76cd3946434d..e9ef69aef20b1 100644 --- a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor +++ b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor @@ -5,6 +5,9 @@ Contact: linux-mtd@lists.infradead.org Description: (RO) The JEDEC ID of the SPI NOR flash as reported by the flash device. + The attribute is not present if the flash doesn't support + the "Read JEDEC ID" command (9Fh). This is the case for + non-JEDEC compliant flashes. What: /sys/bus/spi/devices/.../spi-nor/manufacturer Date: April 2021 diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c index 9aec9d8a98ada..4c3b351aef245 100644 --- a/drivers/mtd/spi-nor/sysfs.c +++ b/drivers/mtd/spi-nor/sysfs.c @@ -67,6 +67,19 @@ static struct bin_attribute *spi_nor_sysfs_bin_entries[] = { NULL }; +static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct spi_device *spi = to_spi_device(kobj_to_dev(kobj)); + struct spi_mem *spimem = spi_get_drvdata(spi); + struct spi_nor *nor = spi_mem_get_drvdata(spimem); + + if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len) + return 0; + + return 0444; +} + static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj, struct bin_attribute *attr, int n) { @@ -82,6 +95,7 @@ static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj, static const struct attribute_group spi_nor_sysfs_group = { .name = "spi-nor", + .is_visible = spi_nor_sysfs_is_visible, .is_bin_visible = spi_nor_sysfs_is_bin_visible, .attrs = spi_nor_sysfs_entries, .bin_attrs = spi_nor_sysfs_bin_entries, From 0d9270f2762b8a2bd0df7c4a2e7e651703783793 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:49 +0200 Subject: [PATCH 61/76] mtd: spi-nor: sysfs: hide manufacturer if it is not set The manufacturer may be optional when pure SFDP flashes are supported. Hide the sysfs property if no manufacturer is set. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-3-michael@walle.cc --- Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor | 3 +++ drivers/mtd/spi-nor/sysfs.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor index e9ef69aef20b1..c800621eff95f 100644 --- a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor +++ b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor @@ -15,6 +15,9 @@ KernelVersion: 5.14 Contact: linux-mtd@lists.infradead.org Description: (RO) Manufacturer of the SPI NOR flash. + The attribute is not present if the flash device isn't + known to the kernel and is only probed by its SFDP + tables. What: /sys/bus/spi/devices/.../spi-nor/partname Date: April 2021 diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c index 4c3b351aef245..20563c1926f47 100644 --- a/drivers/mtd/spi-nor/sysfs.c +++ b/drivers/mtd/spi-nor/sysfs.c @@ -74,6 +74,8 @@ static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj, struct spi_mem *spimem = spi_get_drvdata(spi); struct spi_nor *nor = spi_mem_get_drvdata(spimem); + if (attr == &dev_attr_manufacturer.attr && !nor->manufacturer) + return 0; if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len) return 0; From 28ef7670414e309d8bbee41f9389b7e21a58572c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:50 +0200 Subject: [PATCH 62/76] mtd: spi-nor: remember full JEDEC flash ID At the moment, we print the JEDEC ID that is stored in our database. The generic flash support won't have such an entry in our database. To find out the JEDEC ID later we will have to cache it. There is also another advantage: If the flash is found in the database, the ID could be truncated because the ID of the entry is used which can be shorter. Some flashes still holds valuable information in the bytes after the JEDEC ID and come in handy during debugging of when coping with INFO6() entries. These are not accessible for now. Save a copy of the ID bytes after reading and display it via debugfs. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-4-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 5 +++++ drivers/mtd/spi-nor/debugfs.c | 2 +- include/linux/mtd/spi-nor.h | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0079758b36aa1..1358f3c45d164 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1666,6 +1666,11 @@ static const struct flash_info *spi_nor_detect(struct spi_nor *nor) return ERR_PTR(ret); } + /* Cache the complete flash ID. */ + nor->id = devm_kmemdup(nor->dev, id, SPI_NOR_MAX_ID_LEN, GFP_KERNEL); + if (!nor->id) + return ERR_PTR(-ENOMEM); + info = spi_nor_match_id(nor, id); if (!info) { dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c index df76cb5de3f93..ff895f6758ea1 100644 --- a/drivers/mtd/spi-nor/debugfs.c +++ b/drivers/mtd/spi-nor/debugfs.c @@ -81,7 +81,7 @@ static int spi_nor_params_show(struct seq_file *s, void *data) int i; seq_printf(s, "name\t\t%s\n", info->name); - seq_printf(s, "id\t\t%*ph\n", info->id_len, info->id); + seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id); string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf)); seq_printf(s, "size\t\t%s\n", buf); seq_printf(s, "write size\t%u\n", params->writesize); diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 42218a1164f6d..25765556223a1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -349,6 +349,8 @@ struct spi_nor_flash_parameter; * @bouncebuf: bounce buffer used when the buffer passed by the MTD * layer is not DMA-able * @bouncebuf_size: size of the bounce buffer + * @id: The flash's ID bytes. Always contains + * SPI_NOR_MAX_ID_LEN bytes. * @info: SPI NOR part JEDEC MFR ID and other info * @manufacturer: SPI NOR manufacturer * @addr_nbytes: number of address bytes @@ -379,6 +381,7 @@ struct spi_nor { struct spi_mem *spimem; u8 *bouncebuf; size_t bouncebuf_size; + u8 *id; const struct flash_info *info; const struct spi_nor_manufacturer *manufacturer; u8 addr_nbytes; From fa06bb26a40ca08fa0d653b04d8ce92d243aa2ce Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:51 +0200 Subject: [PATCH 63/76] mtd: spi-nor: move function declaration out of sfdp.h sfdp.h should only contain constants related to the JEDEC SFDP specification(s). Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-5-michael@walle.cc --- drivers/mtd/spi-nor/core.h | 2 ++ drivers/mtd/spi-nor/sfdp.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 85b0cf254e974..68aaccaa12d88 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -701,6 +701,8 @@ int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, size_t len); +int spi_nor_parse_sfdp(struct spi_nor *nor); + static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) { return container_of(mtd, struct spi_nor, mtd); diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h index bbf80d2990ab6..c1969f0a2f46f 100644 --- a/drivers/mtd/spi-nor/sfdp.h +++ b/drivers/mtd/spi-nor/sfdp.h @@ -107,6 +107,4 @@ struct sfdp_parameter_header { u8 id_msb; }; -int spi_nor_parse_sfdp(struct spi_nor *nor); - #endif /* __LINUX_MTD_SFDP_H */ From 39eece67a3cf027aa5b39d7da5feadc4711504e6 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:52 +0200 Subject: [PATCH 64/76] mtd: spi-nor: fix select_uniform_erase to skip 0 erase size 4bait will set the erase size to 0 if there is no corresponding opcode for the 4byte erase. Fix spi_nor_select_uniform_erase to skip the 0 erase size to avoid mtd device registration failure cases. Reported-by: Jae Hyun Yoo Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20220810220654.1297699-6-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 1358f3c45d164..2bdc5b50d8da1 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2120,6 +2120,10 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map, tested_erase = &map->erase_type[i]; + /* Skip masked erase types. */ + if (!tested_erase->size) + continue; + /* * If the current erase size is the one, stop here: * we have found the right uniform Sector Erase command. From 773bbe10449731c9525457873e0c2342e5cf883b Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:53 +0200 Subject: [PATCH 65/76] mtd: spi-nor: add generic flash driver Our SFDP parsing is everything we need to support all basic operations of a flash device. If the flash isn't found in our in-kernel flash database, gracefully fall back to a driver described solely by its SFDP tables. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Tested-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-7-michael@walle.cc --- drivers/mtd/spi-nor/core.c | 26 ++++++++++++++++++++++++-- drivers/mtd/spi-nor/core.h | 1 + drivers/mtd/spi-nor/sfdp.c | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 2bdc5b50d8da1..71b9bcd8991db 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1634,6 +1634,16 @@ static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_xmc, }; +static const struct flash_info spi_nor_generic_flash = { + .name = "spi-nor-generic", + /* + * JESD216 rev A doesn't specify the page size, therefore we need a + * sane default. + */ + .page_size = 256, + .parse_sfdp = true, +}; + static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, const u8 *id) { @@ -1672,6 +1682,14 @@ static const struct flash_info *spi_nor_detect(struct spi_nor *nor) return ERR_PTR(-ENOMEM); info = spi_nor_match_id(nor, id); + + /* Fallback to a generic flash described only by its SFDP data. */ + if (!info) { + ret = spi_nor_check_sfdp_signature(nor); + if (!ret) + info = &spi_nor_generic_flash; + } + if (!info) { dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", SPI_NOR_MAX_ID_LEN, id); @@ -2098,8 +2116,12 @@ static int spi_nor_select_pp(struct spi_nor *nor, * spi_nor_select_uniform_erase() - select optimum uniform erase type * @map: the erase map of the SPI NOR * @wanted_size: the erase type size to search for. Contains the value of - * info->sector_size or of the "small sector" size in case - * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined. + * info->sector_size, the "small sector" size in case + * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if + * there is no information about the sector size. The + * latter is the case if the flash parameters are parsed + * solely by SFDP, then the largest supported erase type + * is selected. * * Once the optimum uniform sector erase command is found, disable all the * other. diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 68aaccaa12d88..ef0a73dbf348e 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -701,6 +701,7 @@ int spi_nor_controller_ops_read_reg(struct spi_nor *nor, u8 opcode, int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, size_t len); +int spi_nor_check_sfdp_signature(struct spi_nor *nor); int spi_nor_parse_sfdp(struct spi_nor *nor); static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 15fb7f661ae9f..c88628e8ee4e8 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -1256,6 +1256,33 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor) nor->info->fixups->post_sfdp(nor); } +/** + * spi_nor_check_sfdp_signature() - check for a valid SFDP signature + * @nor: pointer to a 'struct spi_nor' + * + * Used to detect if the flash supports the RDSFDP command as well as the + * presence of a valid SFDP table. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_check_sfdp_signature(struct spi_nor *nor) +{ + u32 signature; + int err; + + /* Get the SFDP header. */ + err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(signature), + &signature); + if (err < 0) + return err; + + /* Check the SFDP signature. */ + if (le32_to_cpu(signature) != SFDP_SIGNATURE) + return -EINVAL; + + return 0; +} + /** * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. * @nor: pointer to a 'struct spi_nor' From 0a92de16b61b5d7a52d2910f81325f0506b2fc3b Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 11 Aug 2022 00:06:54 +0200 Subject: [PATCH 66/76] mtd: spi-nor: sysfs: print JEDEC ID for generic flash driver We don't have a database entry for the generic SPI-NOR flash driver and thus we don't have a JEDEC ID to print. Print the (cached) JEDEC ID instead. Signed-off-by: Michael Walle Signed-off-by: Tudor Ambarus Reviewed-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20220810220654.1297699-8-michael@walle.cc --- drivers/mtd/spi-nor/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c index 20563c1926f47..c09bb832b3b9e 100644 --- a/drivers/mtd/spi-nor/sysfs.c +++ b/drivers/mtd/spi-nor/sysfs.c @@ -35,8 +35,10 @@ static ssize_t jedec_id_show(struct device *dev, struct spi_device *spi = to_spi_device(dev); struct spi_mem *spimem = spi_get_drvdata(spi); struct spi_nor *nor = spi_mem_get_drvdata(spimem); + const u8 *id = nor->info->id_len ? nor->info->id : nor->id; + u8 id_len = nor->info->id_len ?: SPI_NOR_MAX_ID_LEN; - return sysfs_emit(buf, "%*phN\n", nor->info->id_len, nor->info->id); + return sysfs_emit(buf, "%*phN\n", id_len, id); } static DEVICE_ATTR_RO(jedec_id); @@ -76,7 +78,7 @@ static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj, if (attr == &dev_attr_manufacturer.attr && !nor->manufacturer) return 0; - if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len) + if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len && !nor->id) return 0; return 0444; From 270450a1b6d8bef423cfe619ab8bb99b2f874cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Tue, 1 Nov 2022 17:29:06 +0100 Subject: [PATCH 67/76] mtd: spi-nor: Fix formatting in spi_nor_read_raw() kerneldoc comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn't make sense to put "set" on its own line like that. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Tudor Ambarus Acked-by: Pratyush Yadav Link: https://lore.kernel.org/r/20221101162906.990125-1-j.neuschaefer@gmx.net --- drivers/mtd/spi-nor/sfdp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index c88628e8ee4e8..8434f654eca1e 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -135,8 +135,7 @@ struct sfdp_4bait { /** * spi_nor_read_raw() - raw read of serial flash memory. read_opcode, * addr_nbytes and read_dummy members of the struct spi_nor - * should be previously - * set. + * should be previously set. * @nor: pointer to a 'struct spi_nor' * @addr: offset in the serial flash memory * @len: number of bytes to read From 4dc49062a7e9c0c7261807fb855df1c611eb78c3 Mon Sep 17 00:00:00 2001 From: Yaliang Wang Date: Mon, 17 Oct 2022 01:19:01 +0800 Subject: [PATCH 68/76] mtd: spi-nor: gigadevice: gd25q256: replace gd25q256_default_init with gd25q256_post_bfpt When utilizing PARSE_SFDP to initialize the flash parameter, the deprecated initializing method spi_nor_init_params_deprecated() and the function spi_nor_manufacturer_init_params() within it will never be executed, which results in the default_init hook function will also never be executed. This is okay for 'D' generation of GD25Q256, because 'D' generation is implementing the JESD216B standards, it has QER field defined in BFPT, parsing the SFDP can properly set the quad_enable function. The 'E' generation also implements the JESD216B standards, and it has the same status register definitions as 'D' generation, parsing the SFDP to set the quad_enable function should also work for 'E' generation. However, the same thing can't apply to 'C' generation. 'C' generation 'GD25Q256C' implements the JESD216 standards, and it doesn't have the QER field defined in BFPT, since it does have QE bit in status register 1, the quad_enable hook needs to be tweaked to properly set the quad_enable function, this can be done in post_bfpt fixup hook. Fixes: 047275f7de18 ("mtd: spi-nor: gigadevice: gd25q256: Init flash based on SFDP") Reported-by: kernel test robot Signed-off-by: Yaliang Wang [tudor.ambarus@microchip.com: Update comment in gd25q256_post_bfpt] Signed-off-by: Tudor Ambarus Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20221016171901.1483542-2-yaliang.wang@windriver.com --- drivers/mtd/spi-nor/gigadevice.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c index 119b38e6fc2a3..d57ddaf1525b3 100644 --- a/drivers/mtd/spi-nor/gigadevice.c +++ b/drivers/mtd/spi-nor/gigadevice.c @@ -8,19 +8,29 @@ #include "core.h" -static void gd25q256_default_init(struct spi_nor *nor) +static int +gd25q256_post_bfpt(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt) { /* - * Some manufacturer like GigaDevice may use different - * bit to set QE on different memories, so the MFR can't - * indicate the quad_enable method for this case, we need - * to set it in the default_init fixup hook. + * GD25Q256C supports the first version of JESD216 which does not define + * the Quad Enable methods. Overwrite the default Quad Enable method. + * + * GD25Q256 GENERATION | SFDP MAJOR VERSION | SFDP MINOR VERSION + * GD25Q256C | SFDP_JESD216_MAJOR | SFDP_JESD216_MINOR + * GD25Q256D | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR + * GD25Q256E | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR */ - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; + if (bfpt_header->major == SFDP_JESD216_MAJOR && + bfpt_header->minor == SFDP_JESD216_MINOR) + nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; + + return 0; } static const struct spi_nor_fixups gd25q256_fixups = { - .default_init = gd25q256_default_init, + .post_bfpt = gd25q256_post_bfpt, }; static const struct flash_info gigadevice_nor_parts[] = { From fdc20370d93e8c6d2f448a539d08c2c064af7694 Mon Sep 17 00:00:00 2001 From: Allen-KH Cheng Date: Mon, 31 Oct 2022 20:46:33 +0800 Subject: [PATCH 69/76] mtd: spi-nor: Fix the number of bytes for the dummy cycles The number of bytes used by spi_nor_spimem_check_readop() may be incorrect for the dummy cycles. Since nor->read_dummy is not initialized before spi_nor_spimem_adjust_hwcaps(). We use both mode and wait state clock cycles instead of nor->read_dummy. Fixes: 0e30f47232ab ("mtd: spi-nor: add support for DTR protocol") Co-developed-by: Bayi Cheng Signed-off-by: Bayi Cheng Signed-off-by: Allen-KH Cheng Signed-off-by: Tudor Ambarus Tested-by: Dhruva Gole Tested-by: AngeloGioacchino Del Regno Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/20221031124633.13189-1-allen-kh.cheng@mediatek.com --- drivers/mtd/spi-nor/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 71b9bcd8991db..dd45f286bb4ea 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1939,7 +1939,8 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor, spi_nor_spimem_setup_op(nor, &op, read->proto); /* convert the dummy cycles to the number of bytes */ - op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8; + op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) * + op.dummy.buswidth / 8; if (spi_nor_protocol_is_dtr(nor->read_proto)) op.dummy.nbytes *= 2; From bcc0c61e6134066f4629845691a514ea33465653 Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 20 Oct 2022 09:20:58 +0000 Subject: [PATCH 70/76] mtd: spi-nor: micron-st: Enable locking for mt25qu256a mt25qu256a [1] uses the 4 bit Block Protection scheme and supports Top/Bottom protection via the BP and TB bits of the Status Register. BP3 is located in bit 6 of the Status Register. Tested on MT25QU256ABA8ESF-0SIT. [1] https://www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25q/die-rev-a/mt25q_qljs_u_256_aba_0.pdf Signed-off-by: Eliav Farber Signed-off-by: Tudor Ambarus Reviewed-by: Michael Walle Link: https://lore.kernel.org/r/20221020092058.33844-1-farbere@amazon.com --- drivers/mtd/spi-nor/micron-st.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 3c8a90b39c8c6..7bb86df52f0ba 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -205,6 +205,8 @@ static const struct flash_info st_nor_parts[] = { MFR_FLAGS(USE_FSR) }, { "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512) + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP | + SPI_NOR_BP3_SR_BIT6) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) FIXUP_FLAGS(SPI_NOR_4B_OPCODES) MFR_FLAGS(USE_FSR) From ef434f08b0562069cf431873a052692357d325a1 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Fri, 15 Jul 2022 17:06:43 -0700 Subject: [PATCH 71/76] mtd: spi-nor: winbond: add support for W25Q512NW-IQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for Winbond W25Q512NW-IQ/IN Signed-off-by: Jae Hyun Yoo Signed-off-by: Tudor Ambarus Reviewed-by: Cédric Le Goater Reviewed-by: Michael Walle Link: https://www.winbond.com/resource-files/W25Q512NW%20RevB%2007192021.pdf Link: https://lore.kernel.org/r/20220716000643.3541839-2-quic_jaehyoo@quicinc.com --- drivers/mtd/spi-nor/winbond.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index ffaa240552598..ca39acf4112c8 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -133,6 +133,9 @@ static const struct flash_info winbond_nor_parts[] = { { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, + { "w25q512nwq", INFO(0xef6020, 0, 0, 0) + PARSE_SFDP + OTP_INFO(256, 3, 0x1000, 0x1000) }, { "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 1024) PARSE_SFDP OTP_INFO(256, 3, 0x1000, 0x1000) }, From a30f53d8bc0f9b55b4e8eea0e17b68cfd1f07f34 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 20 Sep 2022 19:48:07 +0100 Subject: [PATCH 72/76] mtd: spi-nor: issi: is25wp256: Init flash based on SFDP The datasheet of is25wp256 says it supports SFDP. Get rid of the static initialization of the flash parameters and init them when parsing SFDP. Testing showed the flash using SPINOR_OP_READ_1_1_4_4B 0x6c, SPINOR_OP_PP_4B 0x12 and SPINOR_OP_BE_4K_4B 0x21 before enabling SFDP. After this patch, it parses the SFDP information and still uses the same opcodes. Set sector_size and n_sectors to zero as they will be discovered when parsing SFDP. Signed-off-by: Sudip Mukherjee [tudor.ambarus@microchip.com: set sector_size and n_sectors to zero] Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20220920184808.44876-1-sudip.mukherjee@sifive.com --- drivers/mtd/spi-nor/issi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index 89a66a19d754f..72dfd5f087adb 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -70,8 +70,8 @@ static const struct flash_info issi_nor_parts[] = { NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) + { "is25wp256", INFO(0x9d7019, 0, 0, 0) + PARSE_SFDP FIXUP_FLAGS(SPI_NOR_4B_OPCODES) .fixups = &is25lp256_fixups }, From 1799cd8540b67b88514c82f5fae1c75b986bcbd8 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 20 Sep 2022 19:48:08 +0100 Subject: [PATCH 73/76] mtd: spi-nor: add SFDP fixups for Quad Page Program SFDP table of some flash chips do not advertise support of Quad Input Page Program even though it has support. Use flags and add hardware cap for these chips. Signed-off-by: Sudip Mukherjee [tudor.ambarus@microchip.com: move pp setting in spi_nor_init_default_params] Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20220920184808.44876-2-sudip.mukherjee@sifive.com --- drivers/mtd/spi-nor/core.c | 6 ++++++ drivers/mtd/spi-nor/core.h | 2 ++ drivers/mtd/spi-nor/issi.c | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index dd45f286bb4ea..694a555defdc3 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2599,6 +2599,12 @@ static void spi_nor_init_default_params(struct spi_nor *nor) params->hwcaps.mask |= SNOR_HWCAPS_PP; spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP], SPINOR_OP_PP, SNOR_PROTO_1_1_1); + + if (info->flags & SPI_NOR_QUAD_PP) { + params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4; + spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP_1_1_4], + SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4); + } } /** diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index ef0a73dbf348e..f03b55cf7e6fe 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -458,6 +458,7 @@ struct spi_nor_fixups { * SPI_NOR_NO_ERASE: no erase command needed. * NO_CHIP_ERASE: chip does not support chip erase. * SPI_NOR_NO_FR: can't do fastread. + * SPI_NOR_QUAD_PP: flash supports Quad Input Page Program. * * @no_sfdp_flags: flags that indicate support that can be discovered via SFDP. * Used when SFDP tables are not defined in the flash. These @@ -507,6 +508,7 @@ struct flash_info { #define SPI_NOR_NO_ERASE BIT(6) #define NO_CHIP_ERASE BIT(7) #define SPI_NOR_NO_FR BIT(8) +#define SPI_NOR_QUAD_PP BIT(9) u8 no_sfdp_flags; #define SPI_NOR_SKIP_SFDP BIT(0) diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index 72dfd5f087adb..a0ddad2afffc2 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -73,6 +73,7 @@ static const struct flash_info issi_nor_parts[] = { { "is25wp256", INFO(0x9d7019, 0, 0, 0) PARSE_SFDP FIXUP_FLAGS(SPI_NOR_4B_OPCODES) + FLAGS(SPI_NOR_QUAD_PP) .fixups = &is25lp256_fixups }, /* PMC */ From 56570bdad5e31c5c538cd6efff5c4510256e1bb4 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Sat, 19 Nov 2022 14:39:15 +0800 Subject: [PATCH 74/76] mtd: core: Fix refcount error in del_mtd_device() del_mtd_device() will call of_node_put() to mtd_get_of_node(mtd), which is mtd->dev.of_node. However, memset(&mtd->dev, 0) is called before of_node_put(). As the result, of_node_put() won't do anything in del_mtd_device(), and causes the refcount leak. del_mtd_device() memset(&mtd->dev, 0, sizeof(mtd->dev) # clear mtd->dev of_node_put() mtd_get_of_node(mtd) # mtd->dev is cleared, can't locate of_node # of_node_put(NULL) won't do anything Fix the error by caching the pointer of the device_node. OF: ERROR: memory leak, expected refcount 1 instead of 2, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node /spi/spi-sram@0 CPU: 3 PID: 275 Comm: python3 Tainted: G N 6.1.0-rc3+ #54 0d8a1edddf51f172ff5226989a7565c6313b08e2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack_lvl+0x67/0x83 kobject_get+0x155/0x160 of_node_get+0x1f/0x30 of_fwnode_get+0x43/0x70 fwnode_handle_get+0x54/0x80 fwnode_get_nth_parent+0xc9/0xe0 fwnode_full_name_string+0x3f/0xa0 device_node_string+0x30f/0x750 pointer+0x598/0x7a0 vsnprintf+0x62d/0x9b0 ... cfs_overlay_release+0x30/0x90 config_item_release+0xbe/0x1a0 config_item_put+0x5e/0x80 configfs_rmdir+0x3bd/0x540 vfs_rmdir+0x18c/0x320 do_rmdir+0x198/0x330 __x64_sys_rmdir+0x2c/0x40 do_syscall_64+0x37/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: 00596576a051 ("mtd: core: clear out unregistered devices a bit more") Signed-off-by: Shang XiaoJing [: Light reword of the commit log] Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221119063915.11108-1-shangxiaojing@huawei.com --- drivers/mtd/mtdcore.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 6c4683a5e5316..0feacb9fbdac5 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -780,6 +780,7 @@ int del_mtd_device(struct mtd_info *mtd) { int ret; struct mtd_notifier *not; + struct device_node *mtd_of_node; mutex_lock(&mtd_table_mutex); @@ -798,6 +799,7 @@ int del_mtd_device(struct mtd_info *mtd) mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { + mtd_of_node = mtd_get_of_node(mtd); debugfs_remove_recursive(mtd->dbg.dfs_dir); /* Try to remove the NVMEM provider */ @@ -809,7 +811,7 @@ int del_mtd_device(struct mtd_info *mtd) memset(&mtd->dev, 0, sizeof(mtd->dev)); idr_remove(&mtd_idr, mtd->index); - of_node_put(mtd_get_of_node(mtd)); + of_node_put(mtd_of_node); module_put(THIS_MODULE); ret = 0; From 2399401feee27c639addc5b7e6ba519d3ca341bf Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Sat, 19 Nov 2022 07:33:07 +0000 Subject: [PATCH 75/76] mtd: maps: pxa2xx-flash: fix memory leak in probe Free 'info' upon remapping error to avoid a memory leak. Fixes: e644f7d62894 ("[MTD] MAPS: Merge Lubbock and Mainstone drivers into common PXA2xx driver") Signed-off-by: Zheng Yongjun [: Reword the commit log] Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221119073307.22929-1-zhengyongjun3@huawei.com --- drivers/mtd/maps/pxa2xx-flash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 1749dbbacc135..62a5bf41a6d72 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -64,6 +64,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) if (!info->map.virt) { printk(KERN_WARNING "Failed to ioremap %s\n", info->map.name); + kfree(info); return -ENOMEM; } info->map.cached = ioremap_cache(info->map.phys, info->map.size); @@ -85,6 +86,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) iounmap((void *)info->map.virt); if (info->map.cached) iounmap(info->map.cached); + kfree(info); return -EIO; } info->mtd->dev.parent = &pdev->dev; From 6408cc05a50aaf88074a5a31d065e5af87a456f5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 24 Nov 2022 11:59:46 +0100 Subject: [PATCH 76/76] mtd: rawnand: Drop obsolete dependencies on COMPILE_TEST Since commit 0166dc11be91 ("of: make CONFIG_OF user selectable"), it is possible to test-build any driver which depends on OF on any architecture by explicitly selecting OF. Therefore depending on COMPILE_TEST as an alternative is no longer needed. It is actually better to always build such drivers with OF enabled, so that the test builds are closer to how each driver will actually be built on its intended target. Building them without OF may not test much as the compiler will optimize out potentially large parts of the code. In the worst case, this could even pop false positive warnings. Dropping COMPILE_TEST here improves the quality of our testing and avoids wasting time on non-existent issues. Signed-off-by: Jean Delvare Cc: Miquel Raynal Cc: Richard Weinberger Cc: Vignesh Raghavendra Cc: Naga Sureshkumar Relli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221124115946.5edb771c@endymion.delvare --- drivers/mtd/nand/raw/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 4cd40af362de2..98ea1c9e65c8e 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -415,7 +415,7 @@ config MTD_NAND_PLATFORM config MTD_NAND_CADENCE tristate "Support Cadence NAND (HPNFC) controller" - depends on (OF || COMPILE_TEST) && HAS_IOMEM + depends on OF && HAS_IOMEM help Enable the driver for NAND flash on platforms using a Cadence NAND controller. @@ -430,7 +430,7 @@ config MTD_NAND_ARASAN config MTD_NAND_INTEL_LGM tristate "Support for NAND controller on Intel LGM SoC" - depends on OF || COMPILE_TEST + depends on OF depends on HAS_IOMEM help Enables support for NAND Flash chips on Intel's LGM SoC. @@ -450,7 +450,7 @@ config MTD_NAND_ROCKCHIP config MTD_NAND_PL35X tristate "ARM PL35X NAND controller" - depends on OF || COMPILE_TEST + depends on OF depends on PL353_SMC help Enables support for PrimeCell SMC PL351 and PL353 NAND