@@ -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);
+
+ /*
+ * At this point, we know the flash params and can tweak the OOB layout
+ * for 512-byte page (usually this is a 64MiB flash).
+ *
+ * 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);
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
nand->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
nand->chip.ecc.algo = NAND_ECC_ALGO_HAMMING;
@@ -204,6 +222,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)
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@gmail.com> --- Changes since v1: * rebased on top of latest master * rephrased the comment in the hook function, thanks to Bas for noticing this .../files/drivers/mtd/nand/raw/nand_rb4xx.c | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)