drivers/mtd/nand/mtk_nand2.c | 2304 +++++++++++++++++++++++++++++++++++
drivers/mtd/nand/mtk_nand2.h | 452 +++++++
drivers/mtd/nand/nand_base.c | 6 +-
- drivers/mtd/nand/nand_bbt.c | 19 +
drivers/mtd/nand/nand_def.h | 123 ++
drivers/mtd/nand/nand_device_list.h | 55 +
drivers/mtd/nand/partition.h | 115 ++
+
--- /dev/null
+++ b/drivers/mtd/nand/mtk_nand2.c
-@@ -0,0 +1,2365 @@
+@@ -0,0 +1,2345 @@
+/******************************************************************************
+* mtk_nand2.c - MTK NAND Flash Device Driver
+ *
+unsigned int CFG_BLOCKSIZE;
+
+static int shift_on_bbt = 0;
-+extern void nand_bbt_set(struct mtd_info *mtd, int page, int flag);
-+extern int nand_bbt_get(struct mtd_info *mtd, int page);
+int mtk_nand_read_oob_hw(struct mtd_info *mtd, struct nand_chip *chip, int page);
+
+static const char * const probe_types[] = { "cmdlinepart", "ofpart", NULL };
+BOOL g_bHwEcc = true;
+
+
-+static u8 *local_buffer_16_align; // 16 byte aligned buffer, for HW issue
-+static u8 local_buffer[4096 + 512];
-+
+extern void nand_release_device(struct mtd_info *mtd);
+extern int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state);
+
+
+static u8 nand_badblock_offset = 0;
+
++static void nand_bbt_set(struct mtd_info *mtd, int page, int flag)
++{
++ struct nand_chip *this = mtd->priv;
++ int block;
++
++ block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
++ this->bbt[block >> 3] &= ~(0x03 << (block & 0x6));
++ this->bbt[block >> 3] |= (flag & 0x3) << (block & 0x6);
++}
++
++static int nand_bbt_get(struct mtd_info *mtd, int page)
++{
++ struct nand_chip *this = mtd->priv;
++ int block;
++
++ block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
++ return (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
++}
++
+void nand_enable_clock(void)
+{
+ //enable_clock(MT65XX_PDN_PERI_NFI, "NAND");
+ struct nand_chip *nand = mtd->priv;
+ u32 u4SecNum = u4PageSize >> 9;
+
-+ if (((u32) pPageBuf % 16) && local_buffer_16_align)
-+ buf = local_buffer_16_align;
-+ else
-+ buf = pPageBuf;
++ buf = pPageBuf;
+ if (mtk_nand_ready_for_read(nand, u4RowAddr, 0, true, buf)) {
+ int j;
+ for (j = 0 ; j < u4SecNum; j++) {
+ mtk_nand_stop_read();
+ }
+
-+ if (buf == local_buffer_16_align)
-+ memcpy(pPageBuf, buf, u4PageSize);
-+
+ return bRet;
+}
+
+
+ MSG(WRITE, "mtk_nand_exec_write_page, page: 0x%x\n", u4RowAddr);
+
-+ if (((u32) pPageBuf % 16) && local_buffer_16_align) {
-+ printk(KERN_INFO "Data buffer not 16 bytes aligned: %p\n", pPageBuf);
-+ memcpy(local_buffer_16_align, pPageBuf, mtd->writesize);
-+ buf = local_buffer_16_align;
-+ } else
-+ buf = pPageBuf;
++ buf = pPageBuf;
+
+ if (mtk_nand_ready_for_write(chip, u4RowAddr, 0, true, buf)) {
+ mtk_nand_write_fdm_data(chip, pFDMBuf, u4SecNum);
+ return -ENOMEM;
+ }
+
-+ /* Allocate memory for 16 byte aligned buffer */
-+ local_buffer_16_align = local_buffer + 16 - ((u32) local_buffer % 16);
-+ printk(KERN_INFO "Allocate 16 byte aligned buffer: %p\n", local_buffer_16_align);
+ host->hw = hw;
+
+ /* init mtd data structure */
+ nand_chip->chip_shift = ffs(nand_chip->chipsize) - 1;//0x1C;//ffs(nand_chip->chipsize) - 1;
+ nand_chip->cmd_ctrl = mtk_nfc_cmd_ctrl;
+
-+ /* allocate buffers or call select_chip here or a bit earlier*/
-+ {
-+ 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;
-+ nand_chip->options |= NAND_OWN_BUFFERS;
-+ }
-+
-+ nand_chip->oob_poi = nand_chip->buffers->databuf + mtd->writesize;
-+ nand_chip->badblockpos = 0;
-+
+ if (devinfo.pagesize == 4096)
+ layout = &nand_oob_128;
+ else if (devinfo.pagesize == 2048)
+ mtd->oobsize = devinfo.sparesize;
+ hw->nfi_cs_num = 1;
+
++ nand_chip->options |= NAND_USE_BOUNCE_BUFFER;
++ nand_chip->buf_align = 16;
++
+ /* Scan to find existance of the device */
+ if (nand_scan(mtd, hw->nfi_cs_num)) {
+ MSG(INIT, "%s : nand_scan fail.\n", MODULE_NAME);
+ 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;
+ 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();
+
nand_get_device(struct mtd_info *mtd, int new_state)
{
struct nand_chip *chip = mtd_to_nand(mtd);
---- a/drivers/mtd/nand/nand_bbt.c
-+++ b/drivers/mtd/nand/nand_bbt.c
-@@ -1215,6 +1215,25 @@ err:
- return res;
- }
-
-+void nand_bbt_set(struct mtd_info *mtd, int page, int flag)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ int block;
-+
-+ block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
-+ this->bbt[block >> 3] &= ~(0x03 << (block & 0x6));
-+ this->bbt[block >> 3] |= (flag & 0x3) << (block & 0x6);
-+}
-+
-+int nand_bbt_get(struct mtd_info *mtd, int page)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ int block;
-+
-+ block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
-+ return (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
-+}
-+
- /**
- * nand_update_bbt - update bad block table(s)
- * @mtd: MTD device structure
--- /dev/null
+++ b/drivers/mtd/nand/nand_def.h
@@ -0,0 +1,123 @@