[PATCH] ath79: rb4xx-nand: fix 512 byte pages compatibility

Sergey Ryazanov ryazanov.s.a at gmail.com
Thu May 27 15:27:06 PDT 2021


MikroTik boards with 512 byte NAND pages require the old YAFFS1 OOB
layout for compatibility with the RouterBoot bootloader. The RB4xx NAND
driver supports such OOB layout, but checks a NAND page size too early
before the flash identification, what effectively preventing the old OOB
layout from being used.

To fix this issue, move the page size check and OOB layout configuration
to the chip attaching hook, which is specially intorduced for ECC and
OOB tweaking.

While at it, copy a comment from the old AR71xx driver to make it clear,
why do we need this OOB layout tweaking.

Run tested with MikroTik RB411U board.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a at gmail.com>
---
 .../files/drivers/mtd/nand/raw/nand_rb4xx.c   | 25 ++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/nand_rb4xx.c b/target/linux/ath79/files/drivers/mtd/nand/raw/nand_rb4xx.c
index 50bd69f6a4..00c65d14ae 100644
--- a/target/linux/ath79/files/drivers/mtd/nand/raw/nand_rb4xx.c
+++ b/target/linux/ath79/files/drivers/mtd/nand/raw/nand_rb4xx.c
@@ -81,6 +81,23 @@ static const struct mtd_ooblayout_ops rb4xx_nand_ecclayout_ops = {
 	.free = rb4xx_ooblayout_free,
 };
 
+static int rb4xx_nand_attach_chip(struct nand_chip *chip)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+
+	/*
+	 * Now we knows flash parameters and can tweak OOB the layout for old
+	 * (usually 64MiB) flashes.
+	 *
+	 * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB
+	 * bootloader will not be able to find the kernel that we load.
+	 */
+	if (mtd->writesize == 512)
+		mtd_set_ooblayout(mtd, &rb4xx_nand_ecclayout_ops);
+
+	return 0;
+}
+
 static u8 rb4xx_nand_read_byte(struct nand_chip *chip)
 {
 	struct rb4xx_nand *nand = chip->priv;
@@ -135,6 +152,10 @@ static int rb4xx_nand_dev_ready(struct nand_chip *chip)
 	return gpiod_get_value_cansleep(nand->rdy);
 }
 
+static const struct nand_controller_ops rb4xx_nand_controller_ops = {
+	.attach_chip = rb4xx_nand_attach_chip,
+};
+
 static int rb4xx_nand_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -185,9 +206,6 @@ static int rb4xx_nand_probe(struct platform_device *pdev)
 	mtd->dev.parent	= dev;
 	mtd_set_of_node(mtd, dev->of_node);
 
-	if (mtd->writesize == 512)
-		mtd_set_ooblayout(mtd, &rb4xx_nand_ecclayout_ops);
-
 	nand->chip.ecc.mode	= NAND_ECC_SOFT;
 	nand->chip.ecc.algo	= NAND_ECC_HAMMING;
 	nand->chip.options	= NAND_NO_SUBPAGE_WRITE;
@@ -199,6 +217,7 @@ static int rb4xx_nand_probe(struct platform_device *pdev)
 	nand->chip.legacy.cmd_ctrl	= rb4xx_nand_cmd_ctrl;
 	nand->chip.legacy.dev_ready	= rb4xx_nand_dev_ready;
 	nand->chip.legacy.chip_delay	= 25;
+	nand->chip.legacy.dummy_controller.ops = &rb4xx_nand_controller_ops;
 
 	ret = nand_scan(&nand->chip, 1);
 	if (ret)
-- 
2.26.3




More information about the openwrt-devel mailing list