diff mbox

[OpenWrt-Devel,RCF] A patch for mt7621 nand controller.

Message ID CAOFwh=CEB5jiZo5FtcV2NMPrPQQfztzRLU3k7-_f_YZHSaho1A@mail.gmail.com
State RFC
Headers show

Commit Message

Kirill Berezin Oct. 29, 2015, 8:14 a.m. UTC
Hello.

It seems that a code for a nand controller was added but not tested. This
patch add a lost constant required for successful compilation and a bit of
code that allocates and frees buffers needed by internal structures and a
description for two more nand chips.

By the way I found, that a nand controller in some way interferes with spi
flash and sd. If I initialize a nand before spi flash or sd then nand
controller becomes busy or returns ecc errors on every read. If I
initialize, say load as module, it after spi flash or sd then everything
works. I can't say what happens with sd or spi flash because my board have
neither of it. May be I have an incorrect dts file.

Kirill
diff mbox

Patch

--- a/drivers/mtd/nand/mtk_nand.c	2015-10-22 12:42:37.783545248 +0400
+++ b/drivers/mtd/nand/mtk_nand.c	2015-10-22 12:32:47.000000000 +0400
@@ -110,6 +110,10 @@ 
 int manu_id;
 int dev_id;
 
+/* this constant was taken from linux/nand/nand.h v 3.14
+ * in later versions it seems it was removed in order to save a bit of space
+ */
+#define NAND_MAX_OOBSIZE 774
 static u8 local_oob_buf[NAND_MAX_OOBSIZE];
 
 static u8 nand_badblock_offset = 0;
@@ -2175,6 +2184,25 @@ 
 	nand_chip->pagemask = (nand_chip->chipsize >> nand_chip->page_shift) - 1;
 	nand_chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
 	nand_chip->chip_shift = ffs(nand_chip->chipsize) - 1;//0x1C;//ffs(nand_chip->chipsize) - 1;
+
+	/* this was taken from nand_base.c ##3876 nand_scan_tail */
+       if (!(nand_chip->options & NAND_OWN_BUFFERS)) {
+		struct nand_buffers *nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize + mtd->oobsize * 3, GFP_KERNEL);
+		if (!nbuf) {
+			return -ENOMEM;
+		}
+		nbuf->ecccalc = (uint8_t *)(nbuf + 1);
+		nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
+		nbuf->databuf = nbuf->ecccode + mtd->oobsize;
+
+		nand_chip->buffers = nbuf;
+	} else {
+		if (!nand_chip->buffers) {
+			printk(KERN_NOTICE "mtk_nand_probe: buffer space for nand_chip was not allocated.\n");
+			return -ENOMEM;
+		}
+	}
+
 	nand_chip->oob_poi = nand_chip->buffers->databuf + mtd->writesize;
 	nand_chip->badblockpos = 0;
 
@@ -2251,6 +2279,9 @@ 
 	MSG(INIT, "[NFI] mtk_nand_probe fail, err = %d!\n", err);
 	nand_release(mtd);
 	platform_set_drvdata(pdev, NULL);
+	if ( NULL != nand_chip->buffers) {
+		kfree(nand_chip->buffers);
+	}
 	kfree(host);
 	nand_disable_clock();
 	return err;
@@ -2261,8 +2292,12 @@ 
 {
 	struct mtk_nand_host *host = platform_get_drvdata(pdev);
 	struct mtd_info *mtd = &host->mtd;
+	struct nand_chip *nand_chip = &host->nand_chip;
 
 	nand_release(mtd);
+	if ( NULL != nand_chip->buffers) {
+		kfree(nand_chip->buffers);
+	}
 	kfree(host);
 	nand_disable_clock();
 
--- a/drivers/mtd/nand/nand_device_list.h	2015-10-22 12:42:37.784545248 +0400
+++ b/drivers/mtd/nand/nand_device_list.h	2015-10-22 09:40:33.000000000 +0400
@@ -43,6 +43,8 @@ 
 	{0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0},
     {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0},
     {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0},
+	{0xC8DA, 0x909544, 5, 8, 256, 128, 2048, 64, 0x30C77fff, "F59L2G81A", 0},
+	{0xC8DC, 0x909554, 5, 8, 512, 128, 2048, 64, 0x30C77fff, "F59L4G81A", 0},
 	{0xECD3, 0x519558, 5, 8, 1024, 128, 2048, 64, 0x44333, "K9K8G8000", 0},
     {0xC2F1, 0x801DC2, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "MX30LF1G08AA", 0},
     {0x98D3, 0x902676, 5, 8, 1024, 256, 4096, 224, 0x00C25332, "TC58NVG3S0F", 0},