get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/217/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 217,
    "url": "http://patchwork.ozlabs.org/api/patches/217/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-mtd/patch/48C62D1E.7020906@renesas.com/",
    "project": {
        "id": 3,
        "url": "http://patchwork.ozlabs.org/api/projects/3/?format=api",
        "name": "Linux MTD development",
        "link_name": "linux-mtd",
        "list_id": "linux-mtd.lists.infradead.org",
        "list_email": "linux-mtd@lists.infradead.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<48C62D1E.7020906@renesas.com>",
    "list_archive_url": null,
    "date": "2008-09-09T08:00:30",
    "name": "mtd: sh_flctl: add support for Renesas SuperH FLCTL",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "e64e309998f5b2ca353bce59f5224d1803709261",
    "submitter": {
        "id": 122,
        "url": "http://patchwork.ozlabs.org/api/people/122/?format=api",
        "name": "Yoshihiro Shimoda",
        "email": "shimoda.yoshihiro@renesas.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-mtd/patch/48C62D1E.7020906@renesas.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/217/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/217/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-mtd-bounces+patchwork=ozlabs.org@lists.infradead.org>",
        "X-Original-To": "patchwork@ozlabs.org",
        "Delivered-To": "patchwork@ozlabs.org",
        "Received": [
            "from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(Client did not present a certificate)\n\tby ozlabs.org (Postfix) with ESMTPS id C7D1CDDF01\n\tfor <patchwork@ozlabs.org>; Tue,  9 Sep 2008 18:01:00 +1000 (EST)",
            "from localhost ([127.0.0.1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1Kcy9P-0001MG-2l; Tue, 09 Sep 2008 08:00:39 +0000",
            "from mail.renesas.com ([202.234.163.13]\n\thelo=mail01.idc.renesas.com)\n\tby bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1Kcy9L-000191-KW; Tue, 09 Sep 2008 08:00:37 +0000",
            "from guardian01.idc.renesas.com ([172.20.8.200])\n\tby mail01.idc.renesas.com (sendmail) with ESMTP id m8980Ugm028373;\n\tTue, 9 Sep 2008 17:00:30 +0900 (JST)",
            "(from root@localhost)\n\tby guardian01.idc.renesas.com with  id m8980Vwt016250;\n\tTue, 9 Sep 2008 17:00:31 +0900 (JST)",
            "from mta02.idc.renesas.com (localhost [127.0.0.1])\n\tby mta02.idc.renesas.com with ESMTP id m8980WP1012681;\n\tTue, 9 Sep 2008 17:00:32 +0900 (JST)",
            "from [172.30.8.157] by ims05.idc.renesas.com (Sendmail)\n\twith ESMTPA id <0K6X0045E4WV6F@ims05.idc.renesas.com>; Tue,\n\t09 Sep 2008 17:00:31 +0900 (JST)"
        ],
        "X-AuditID": "ac140384-0000000400000ffd-49-48c62d1f3a1e",
        "Date": "Tue, 09 Sep 2008 17:00:30 +0900",
        "From": "Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>",
        "Subject": "[PATCH] mtd: sh_flctl: add support for Renesas SuperH FLCTL",
        "To": "dwmw2@infradead.org",
        "Message-id": "<48C62D1E.7020906@renesas.com>",
        "MIME-version": "1.0",
        "User-Agent": "Thunderbird 2.0.0.14 (Windows/20080421)",
        "X-Brightmail-Tracker": "AAAAAA==",
        "X-Spam-Score": "0.0 (/)",
        "Cc": "linux-mtd@lists.infradead.org, linux-sh@vger.kernel.org",
        "X-BeenThere": "linux-mtd@lists.infradead.org",
        "X-Mailman-Version": "2.1.9",
        "Precedence": "list",
        "List-Id": "Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>",
        "List-Unsubscribe": "<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.infradead.org/pipermail/linux-mtd>",
        "List-Post": "<mailto:linux-mtd@lists.infradead.org>",
        "List-Help": "<mailto:linux-mtd-request@lists.infradead.org?subject=help>",
        "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "linux-mtd-bounces@lists.infradead.org",
        "Errors-To": "linux-mtd-bounces+patchwork=ozlabs.org@lists.infradead.org"
    },
    "content": "Several Renesas SuperH CPU has FLCTL. The FLCTL support NAND Flash.\nThis driver support SH7723.\n\nSigned-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>",
    "diff": "diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig\nindex 41f361c..c3182de 100644\n--- a/drivers/mtd/nand/Kconfig\n+++ b/drivers/mtd/nand/Kconfig\n@@ -406,4 +406,11 @@ config MTD_NAND_FSL_UPM\n \t  Enables support for NAND Flash chips wired onto Freescale PowerPC\n \t  processor localbus with User-Programmable Machine support.\n\n+config MTD_NAND_SH_FLCTL\n+\ttristate \"Support for NAND on Renesas SuperH FLCTL\"\n+\tdepends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723\n+\thelp\n+\t  Several Renesas SuperH CPU has FLCTL. This option enables support\n+\t  for NAND Flash using FLCTL. This driver support SH7723.\n+\n endif # MTD_NAND\ndiff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile\nindex b786c5d..2cc2d58 100644\n--- a/drivers/mtd/nand/Makefile\n+++ b/drivers/mtd/nand/Makefile\n@@ -34,5 +34,6 @@ obj-$(CONFIG_MTD_NAND_PASEMI)\t\t+= pasemi_nand.o\n obj-$(CONFIG_MTD_NAND_ORION)\t\t+= orion_nand.o\n obj-$(CONFIG_MTD_NAND_FSL_ELBC)\t\t+= fsl_elbc_nand.o\n obj-$(CONFIG_MTD_NAND_FSL_UPM)\t\t+= fsl_upm.o\n+obj-$(CONFIG_MTD_NAND_SH_FLCTL)\t\t+= sh_flctl.o\n\n nand-objs := nand_base.o nand_bbt.o\ndiff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c\nnew file mode 100644\nindex 0000000..326363c\n--- /dev/null\n+++ b/drivers/mtd/nand/sh_flctl.c\n@@ -0,0 +1,878 @@\n+/*\n+ * SuperH FLCTL nand controller\n+ *\n+ * Copyright (C) 2008 Renesas Solutions Corp.\n+ * Copyright (C) 2008 Atom Create Engineering Co., Ltd.\n+ *\n+ * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor\n+ *\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation; version 2 of the License.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * along with this program; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n+ *\n+ */\n+\n+#include <linux/module.h>\n+#include <linux/kernel.h>\n+#include <linux/delay.h>\n+#include <linux/io.h>\n+#include <linux/platform_device.h>\n+\n+#include <linux/mtd/mtd.h>\n+#include <linux/mtd/nand.h>\n+#include <linux/mtd/partitions.h>\n+#include <linux/mtd/sh_flctl.h>\n+\n+static struct nand_ecclayout flctl_4secc_oob_16 = {\n+\t.eccbytes = 10,\n+\t.eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},\n+\t.oobfree = {\n+\t\t{.offset = 12,\n+\t\t. length = 4} },\n+};\n+\n+static struct nand_ecclayout flctl_4secc_oob_64 = {\n+\t.eccbytes = 10,\n+\t.eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},\n+\t.oobfree = {\n+\t\t{.offset = 60,\n+\t\t. length = 4} },\n+};\n+\n+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };\n+\n+static struct nand_bbt_descr flctl_4secc_smallpage = {\n+\t.options = NAND_BBT_SCAN2NDPAGE,\n+\t.offs = 11,\n+\t.len = 1,\n+\t.pattern = scan_ff_pattern,\n+};\n+\n+static struct nand_bbt_descr flctl_4secc_largepage = {\n+\t.options = 0,\n+\t.offs = 58,\n+\t.len = 2,\n+\t.pattern = scan_ff_pattern,\n+};\n+\n+static void empty_fifo(struct sh_flctl *flctl)\n+{\n+\twritel(0x000c0000, FLINTDMACR(flctl));\t/* FIFO Clear */\n+\twritel(0x00000000, FLINTDMACR(flctl));\t/* Clear Error flags */\n+}\n+\n+static void start_translation(struct sh_flctl *flctl)\n+{\n+\twriteb(TRSTRT, FLTRCR(flctl));\n+}\n+\n+static void wait_completion(struct sh_flctl *flctl)\n+{\n+\tu32 timeout = LOOP_TIMEOUT_MAX;\n+\n+\twhile (timeout--) {\n+\t\tif (readb(FLTRCR(flctl)) & TREND) {\n+\t\t\twriteb(0x0, FLTRCR(flctl));\n+\t\t\treturn;\n+\t\t}\n+\t\tudelay(1);\n+\t}\n+\n+\tprintk(KERN_ERR \"wait_completion(): Timeout occured \\n\");\n+\twriteb(0x0, FLTRCR(flctl));\n+}\n+\n+static void set_addr(struct mtd_info *mtd, int column, int page_addr)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tu32 addr = 0;\n+\n+\tif (column == -1) {\n+\t\taddr = page_addr;\t/* ERASE1 */\n+\t} else if (page_addr != -1) {\n+\t\t/* SEQIN, READ0, etc.. */\n+\t\tif (flctl->page_size) {\n+\t\t\taddr = column & 0x0FFF;\n+\t\t\taddr |= (page_addr & 0xff) << 16;\n+\t\t\taddr |= ((page_addr >> 8) & 0xff) << 24;\n+\t\t\t/* big than 128MB */\n+\t\t\tif (flctl->rw_ADRCNT == ADRCNT2_E) {\n+\t\t\t\tu32 \taddr2;\n+\t\t\t\taddr2 = (page_addr >> 16) & 0xff;\n+\t\t\t\twritel(addr2, FLADR2(flctl));\n+\t\t\t}\n+\t\t} else {\n+\t\t\taddr = column;\n+\t\t\taddr |= (page_addr & 0xff) << 8;\n+\t\t\taddr |= ((page_addr >> 8) & 0xff) << 16;\n+\t\t\taddr |= ((page_addr >> 16) & 0xff) << 24;\n+\t\t}\n+\t}\n+\twritel(addr, FLADR(flctl));\n+}\n+\n+static void wait_rfifo_ready(struct sh_flctl *flctl)\n+{\n+\tu32 timeout = LOOP_TIMEOUT_MAX;\n+\n+\twhile (timeout--) {\n+\t\tu32 val;\n+\t\t/* check FIFO */\n+\t\tval = readl(FLDTCNTR(flctl)) >> 16;\n+\t\tif (val & 0xFF)\n+\t\t\treturn;\n+\t\tudelay(1);\n+\t}\n+\tprintk(KERN_ERR \"wait_rfifo_ready(): Timeout occured \\n\");\n+}\n+\n+static void wait_wfifo_ready(struct sh_flctl *flctl)\n+{\n+\tu32 len, timeout = LOOP_TIMEOUT_MAX;\n+\n+\twhile (timeout--) {\n+\t\t/* check FIFO */\n+\t\tlen = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF;\n+\t\tif (len >= 4)\n+\t\t\treturn;\n+\t\tudelay(1);\n+\t}\n+\tprintk(KERN_ERR \"wait_wfifo_ready(): Timeout occured \\n\");\n+}\n+\n+static int wait_recfifo_ready(struct sh_flctl *flctl)\n+{\n+\tu32 timeout = LOOP_TIMEOUT_MAX;\n+\tint checked[4];\n+\tvoid __iomem *ecc_reg[4];\n+\tint i;\n+\tu32 data, size;\n+\n+\tmemset(checked, 0, sizeof(checked));\n+\n+\twhile (timeout--) {\n+\t\tsize = readl(FLDTCNTR(flctl)) >> 24;\n+\t\tif (size & 0xFF)\n+\t\t\treturn 0;\t/* success */\n+\n+\t\tif (readl(FL4ECCCR(flctl)) & _4ECCFA)\n+\t\t\treturn 1;\t/* can't correct */\n+\n+\t\tudelay(1);\n+\t\tif (!(readl(FL4ECCCR(flctl)) & _4ECCEND))\n+\t\t\tcontinue;\n+\n+\t\t/* start error correction */\n+\t\tecc_reg[0] = FL4ECCRESULT0(flctl);\n+\t\tecc_reg[1] = FL4ECCRESULT1(flctl);\n+\t\tecc_reg[2] = FL4ECCRESULT2(flctl);\n+\t\tecc_reg[3] = FL4ECCRESULT3(flctl);\n+\n+\t\tfor (i = 0; i < 3; i++) {\n+\t\t\tdata = readl(ecc_reg[i]);\n+\t\t\tif (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {\n+\t\t\t\tu8 org;\n+\t\t\t\tint index;\n+\n+\t\t\t\tindex = data >> 16;\n+\t\t\t\torg = flctl->done_buff[index];\n+\t\t\t\tflctl->done_buff[index] = org ^ (data & 0xFF);\n+\t\t\t\tchecked[i] = 1;\n+\t\t\t}\n+\t\t}\n+\n+\t\twritel(0, FL4ECCCR(flctl));\n+\t}\n+\n+\tprintk(KERN_ERR \"wait_recfifo_ready(): Timeout occured \\n\");\n+\treturn 1;\t/* timeout */\n+}\n+\n+static void wait_wecfifo_ready(struct sh_flctl *flctl)\n+{\n+\tu32 timeout = LOOP_TIMEOUT_MAX;\n+\tu32 len;\n+\n+\twhile (timeout--) {\n+\t\t/* check FLECFIFO */\n+\t\tlen = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;\n+\t\tif (len >= 4)\n+\t\t\treturn;\n+\t\tudelay(1);\n+\t}\n+\tprintk(KERN_ERR \"wait_wecfifo_ready(): Timeout occured \\n\");\n+}\n+\n+static void read_datareg(struct sh_flctl *flctl, int offset)\n+{\n+\tunsigned long data;\n+\tunsigned long *buf = (unsigned long *)&flctl->done_buff[offset];\n+\n+\twait_completion(flctl);\n+\n+\tdata = readl(FLDATAR(flctl));\n+\t*buf = le32_to_cpu(data);\n+}\n+\n+static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)\n+{\n+\tint i, len_4align;\n+\tunsigned long *buf = (unsigned long *)&flctl->done_buff[offset];\n+\tvoid *fifo_addr = (void *)FLDTFIFO(flctl);\n+\n+\tlen_4align = (rlen + 3) / 4;\n+\n+\tfor (i = 0; i < len_4align; i++) {\n+\t\twait_rfifo_ready(flctl);\n+\t\tbuf[i] = readl(fifo_addr);\n+\t\tbuf[i] = be32_to_cpu(buf[i]);\n+\t}\n+}\n+\n+static int read_ecfiforeg(struct sh_flctl *flctl, u8 *buff)\n+{\n+\tint i;\n+\tunsigned long *ecc_buf = (unsigned long *)buff;\n+\tvoid *fifo_addr = (void *)FLECFIFO(flctl);\n+\n+\tfor (i = 0; i < 4; i++) {\n+\t\tif (wait_recfifo_ready(flctl))\n+\t\t\treturn 1;\n+\t\tecc_buf[i] = readl(fifo_addr);\n+\t\tecc_buf[i] = be32_to_cpu(ecc_buf[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)\n+{\n+\tint i, len_4align;\n+\tunsigned long *data = (unsigned long *)&flctl->done_buff[offset];\n+\tvoid *fifo_addr = (void *)FLDTFIFO(flctl);\n+\n+\tlen_4align = (rlen + 3) / 4;\n+\tfor (i = 0; i < len_4align; i++) {\n+\t\twait_wfifo_ready(flctl);\n+\t\twritel(cpu_to_be32(data[i]), fifo_addr);\n+\t}\n+}\n+\n+static void set_cmd_regs(struct mtd_info *mtd, u32 cmd, u32 flcmcdr_val)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tu32 flcmncr_val = readl(FLCMNCR(flctl));\n+\tu32 flcmdcr_val, addr_len_bytes = 0;\n+\n+\t/* Set SNAND bit if page size is 2048byte */\n+\tif (flctl->page_size)\n+\t\tflcmncr_val |= SNAND_E;\n+\telse\n+\t\tflcmncr_val &= ~SNAND_E;\n+\n+\t/* default FLCMDCR val */\n+\tflcmdcr_val = DOCMD1_E | DOADR_E;\n+\n+\t/* Set for FLCMDCR */\n+\tswitch (cmd) {\n+\tcase NAND_CMD_ERASE1:\n+\t\taddr_len_bytes = flctl->erase_ADRCNT;\n+\t\tflcmdcr_val |= DOCMD2_E;\n+\t\tbreak;\n+\tcase NAND_CMD_READ0:\n+\tcase NAND_CMD_READOOB:\n+\t\taddr_len_bytes = flctl->rw_ADRCNT;\n+\t\tflcmdcr_val |= CDSRC_E;\n+\t\tbreak;\n+\tcase NAND_CMD_SEQIN:\n+\t\t/* This case is that cmd is READ0 or READ1 or READ00 */\n+\t\tflcmdcr_val &= ~DOADR_E;\t/* ONLY execute 1st cmd */\n+\t\tbreak;\n+\tcase NAND_CMD_PAGEPROG:\n+\t\taddr_len_bytes = flctl->rw_ADRCNT;\n+\t\tflcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;\n+\t\tbreak;\n+\tcase NAND_CMD_READID:\n+\t\tflcmncr_val &= ~SNAND_E;\n+\t\taddr_len_bytes = ADRCNT_1;\n+\t\tbreak;\n+\tcase NAND_CMD_STATUS:\n+\tcase NAND_CMD_RESET:\n+\t\tflcmncr_val &= ~SNAND_E;\n+\t\tflcmdcr_val &= ~(DOADR_E | DOSR_E);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\t/* Set address bytes parameter */\n+\tflcmdcr_val |= addr_len_bytes;\n+\n+\t/* Now actually write */\n+\twritel(flcmncr_val, FLCMNCR(flctl));\n+\twritel(flcmdcr_val, FLCMDCR(flctl));\n+\twritel(flcmcdr_val, FLCMCDR(flctl));\n+}\n+\n+static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,\n+\t\t\t\tuint8_t *buf)\n+{\n+\tint i, eccsize = chip->ecc.size;\n+\tint eccbytes = chip->ecc.bytes;\n+\tint eccsteps = chip->ecc.steps;\n+\tuint8_t *p = buf;\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\n+\tfor (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)\n+\t\tchip->read_buf(mtd, p, eccsize);\n+\n+\tfor (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {\n+\t\tif (flctl->hwecc_cant_correct[i])\n+\t\t\tmtd->ecc_stats.failed++;\n+\t\telse\n+\t\t\tmtd->ecc_stats.corrected += 0;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,\n+\t\t\t\t   const uint8_t *buf)\n+{\n+\tint i, eccsize = chip->ecc.size;\n+\tint eccbytes = chip->ecc.bytes;\n+\tint eccsteps = chip->ecc.steps;\n+\tconst uint8_t *p = buf;\n+\n+\tfor (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)\n+\t\tchip->write_buf(mtd, p, eccsize);\n+}\n+\n+static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tint sector, page_sectors;\n+\n+\tif (flctl->page_size)\n+\t\tpage_sectors = 4;\n+\telse\n+\t\tpage_sectors = 1;\n+\n+\twritel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,\n+\t\t FLCMNCR(flctl));\n+\n+\tset_cmd_regs(mtd, NAND_CMD_READ0,\n+\t\t(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);\n+\n+\tfor (sector = 0; sector < page_sectors; sector++) {\n+\t\tint ret;\n+\n+\t\tempty_fifo(flctl);\n+\t\twritel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));\n+\t\twritel(page_addr << 2 | sector, FLADR(flctl));\n+\n+\t\tstart_translation(flctl);\n+\t\tread_fiforeg(flctl, 512, 512 * sector);\n+\n+\t\tret = read_ecfiforeg(flctl,\n+\t\t\t&flctl->done_buff[mtd->writesize + 16 * sector]);\n+\n+\t\tif (ret)\n+\t\t\tflctl->hwecc_cant_correct[sector] = 1;\n+\n+\t\twritel(0x0, FL4ECCCR(flctl));\n+\t\twait_completion(flctl);\n+\t}\n+\twritel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),\n+\t\t\tFLCMNCR(flctl));\n+}\n+\n+static void execmd_read_oob(struct mtd_info *mtd, int page_addr)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\n+\tset_cmd_regs(mtd, NAND_CMD_READ0,\n+\t\t(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);\n+\n+\tempty_fifo(flctl);\n+\tif (flctl->page_size) {\n+\t\tint i;\n+\t\t/* In case that the page size is 2k */\n+\t\tfor (i = 0; i < 16 * 3; i++)\n+\t\t\tflctl->done_buff[i] = 0xFF;\n+\n+\t\tset_addr(mtd, 3 * 528 + 512, page_addr);\n+\t\twritel(16, FLDTCNTR(flctl));\n+\n+\t\tstart_translation(flctl);\n+\t\tread_fiforeg(flctl, 16, 16 * 3);\n+\t\twait_completion(flctl);\n+\t} else {\n+\t\t/* In case that the page size is 512b */\n+\t\tset_addr(mtd, 512, page_addr);\n+\t\twritel(16, FLDTCNTR(flctl));\n+\n+\t\tstart_translation(flctl);\n+\t\tread_fiforeg(flctl, 16, 0);\n+\t\twait_completion(flctl);\n+\t}\n+}\n+\n+static void execmd_write_page_sector(struct mtd_info *mtd)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tint i, page_addr = flctl->seqin_page_addr;\n+\tint sector, page_sectors;\n+\n+\tif (flctl->page_size)\n+\t\tpage_sectors = 4;\n+\telse\n+\t\tpage_sectors = 1;\n+\n+\twritel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));\n+\n+\tset_cmd_regs(mtd, NAND_CMD_PAGEPROG,\n+\t\t\t(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);\n+\n+\tfor (sector = 0; sector < page_sectors; sector++) {\n+\t\tempty_fifo(flctl);\n+\t\twritel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));\n+\t\twritel(page_addr << 2 | sector, FLADR(flctl));\n+\n+\t\tstart_translation(flctl);\n+\t\twrite_fiforeg(flctl, 512, 512 * sector);\n+\n+\t\tfor (i = 0; i < 4; i++) {\n+\t\t\twait_wecfifo_ready(flctl); /* wait for write ready */\n+\t\t\twritel(0xFFFFFFFF, FLECFIFO(flctl));\n+\t\t}\n+\t\twait_completion(flctl);\n+\t}\n+\n+\twritel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));\n+}\n+\n+static void execmd_write_oob(struct mtd_info *mtd)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tint page_addr = flctl->seqin_page_addr;\n+\tint sector, page_sectors;\n+\n+\tif (flctl->page_size) {\n+\t\tsector = 3;\n+\t\tpage_sectors = 4;\n+\t} else {\n+\t\tsector = 0;\n+\t\tpage_sectors = 1;\n+\t}\n+\n+\tset_cmd_regs(mtd, NAND_CMD_PAGEPROG,\n+\t\t\t(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);\n+\n+\tfor (; sector < page_sectors; sector++) {\n+\t\tempty_fifo(flctl);\n+\t\tset_addr(mtd, sector * 528 + 512, page_addr);\n+\t\twritel(16, FLDTCNTR(flctl));\t/* set read size */\n+\n+\t\tstart_translation(flctl);\n+\t\twrite_fiforeg(flctl, 16, 16 * sector);\n+\t\twait_completion(flctl);\n+\t}\n+}\n+\n+static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,\n+\t\t\tint column, int page_addr)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tu32 read_cmd = 0;\n+\n+\tflctl->read_bytes = 0;\n+\tif (command != NAND_CMD_PAGEPROG)\n+\t\tflctl->index = 0;\n+\n+\tswitch (command) {\n+\tcase NAND_CMD_READ1:\n+\tcase NAND_CMD_READ0:\n+\t\tif (flctl->hwecc) {\n+\t\t\t/* read page with hwecc */\n+\t\t\texecmd_read_page_sector(mtd, page_addr);\n+\t\t\tbreak;\n+\t\t}\n+\t\tempty_fifo(flctl);\n+\t\tif (flctl->page_size)\n+\t\t\tset_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)\n+\t\t\t\t| command);\n+\t\telse\n+\t\t\tset_cmd_regs(mtd, command, command);\n+\n+\t\tset_addr(mtd, 0, page_addr);\n+\n+\t\tflctl->read_bytes = mtd->writesize + mtd->oobsize;\n+\t\tflctl->index += column;\n+\t\tgoto read_normal_exit;\n+\n+\tcase NAND_CMD_READOOB:\n+\t\tif (flctl->hwecc) {\n+\t\t\t/* read page with hwecc */\n+\t\t\texecmd_read_oob(mtd, page_addr);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tempty_fifo(flctl);\n+\t\tif (flctl->page_size) {\n+\t\t\tset_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)\n+\t\t\t\t| NAND_CMD_READ0);\n+\t\t\tset_addr(mtd, mtd->writesize, page_addr);\n+\t\t} else {\n+\t\t\tset_cmd_regs(mtd, command, command);\n+\t\t\tset_addr(mtd, 0, page_addr);\n+\t\t}\n+\t\tflctl->read_bytes = mtd->oobsize;\n+\t\tgoto read_normal_exit;\n+\n+\tcase NAND_CMD_READID:\n+\t\tempty_fifo(flctl);\n+\t\tset_cmd_regs(mtd, command, command);\n+\t\tset_addr(mtd, 0, 0);\n+\n+\t\tflctl->read_bytes = 4;\n+\t\twritel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */\n+\t\tstart_translation(flctl);\n+\t\tread_datareg(flctl, 0);\t/* read and end */\n+\t\tbreak;\n+\n+\tcase NAND_CMD_ERASE1:\n+\t\tflctl->erase1_page_addr = page_addr;\n+\t\tbreak;\n+\n+\tcase NAND_CMD_ERASE2:\n+\t\tset_cmd_regs(mtd, NAND_CMD_ERASE1,\n+\t\t\t(command << 8) | NAND_CMD_ERASE1);\n+\t\tset_addr(mtd, -1, flctl->erase1_page_addr);\n+\t\tstart_translation(flctl);\n+\t\twait_completion(flctl);\n+\t\tbreak;\n+\n+\tcase NAND_CMD_SEQIN:\n+\t\tif (!flctl->page_size) {\n+\t\t\t/* output read command */\n+\t\t\tif (column >= mtd->writesize) {\n+\t\t\t\tcolumn -= mtd->writesize;\n+\t\t\t\tread_cmd = NAND_CMD_READOOB;\n+\t\t\t} else if (column < 256) {\n+\t\t\t\tread_cmd = NAND_CMD_READ0;\n+\t\t\t} else {\n+\t\t\t\tcolumn -= 256;\n+\t\t\t\tread_cmd = NAND_CMD_READ1;\n+\t\t\t}\n+\t\t}\n+\t\tflctl->seqin_column = column;\n+\t\tflctl->seqin_page_addr = page_addr;\n+\t\tflctl->seqin_read_cmd = read_cmd;\n+\t\tbreak;\n+\n+\tcase NAND_CMD_PAGEPROG:\n+\t\tempty_fifo(flctl);\n+\t\tif (!flctl->page_size) {\n+\t\t\tset_cmd_regs(mtd, NAND_CMD_SEQIN,\n+\t\t\t\t\tflctl->seqin_read_cmd);\n+\t\t\tset_addr(mtd, -1, -1);\n+\t\t\twritel(0, FLDTCNTR(flctl));\t/* set 0 size */\n+\t\t\tstart_translation(flctl);\n+\t\t\twait_completion(flctl);\n+\t\t}\n+\t\tif (flctl->hwecc) {\n+\t\t\t/* write page with hwecc */\n+\t\t\tif (flctl->seqin_column == mtd->writesize)\n+\t\t\t\texecmd_write_oob(mtd);\n+\t\t\telse if (!flctl->seqin_column)\n+\t\t\t\texecmd_write_page_sector(mtd);\n+\t\t\telse\n+\t\t\t\tprintk(KERN_ERR \"Invalid address !?\\n\");\n+\t\t\tbreak;\n+\t\t}\n+\t\tset_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);\n+\t\tset_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);\n+\t\twritel(flctl->index, FLDTCNTR(flctl));\t/* set write size */\n+\t\tstart_translation(flctl);\n+\t\twrite_fiforeg(flctl, flctl->index, 0);\n+\t\twait_completion(flctl);\n+\t\tbreak;\n+\n+\tcase NAND_CMD_STATUS:\n+\t\tset_cmd_regs(mtd, command, command);\n+\t\tset_addr(mtd, -1, -1);\n+\n+\t\tflctl->read_bytes = 1;\n+\t\twritel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */\n+\t\tstart_translation(flctl);\n+\t\tread_datareg(flctl, 0); /* read and end */\n+\t\tbreak;\n+\n+\tcase NAND_CMD_RESET:\n+\t\tset_cmd_regs(mtd, command, command);\n+\t\tset_addr(mtd, -1, -1);\n+\n+\t\twritel(0, FLDTCNTR(flctl));\t/* set 0 size */\n+\t\tstart_translation(flctl);\n+\t\twait_completion(flctl);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\treturn;\n+\n+read_normal_exit:\n+\twritel(flctl->read_bytes, FLDTCNTR(flctl));\t/* set read size */\n+\tstart_translation(flctl);\n+\tread_fiforeg(flctl, flctl->read_bytes, 0);\n+\twait_completion(flctl);\n+\treturn;\n+}\n+\n+static void flctl_select_chip(struct mtd_info *mtd, int chipnr)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tu32 flcmncr_val = readl(FLCMNCR(flctl));\n+\n+\tswitch (chipnr) {\n+\tcase -1:\n+\t\tflcmncr_val &= ~CE0_ENABLE;\n+\t\twritel(flcmncr_val, FLCMNCR(flctl));\n+\t\tbreak;\n+\tcase 0:\n+\t\tflcmncr_val |= CE0_ENABLE;\n+\t\twritel(flcmncr_val, FLCMNCR(flctl));\n+\t\tbreak;\n+\tdefault:\n+\t\tBUG();\n+\t}\n+}\n+\n+static void flctl_write_buf(struct mtd_info *mtd, const u8 *buf, int len)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tint i, index = flctl->index;\n+\n+\tfor (i = 0; i < len; i++)\n+\t\tflctl->done_buff[index + i] = buf[i];\n+\tflctl->index += len;\n+}\n+\n+static u8 flctl_read_byte(struct mtd_info *mtd)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tint index = flctl->index;\n+\tu8 data;\n+\n+\tdata = flctl->done_buff[index];\n+\tflctl->index++;\n+\treturn data;\n+}\n+\n+static void flctl_read_buf(struct mtd_info *mtd, u8 *buf, int len)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < len; i++)\n+\t\tbuf[i] = flctl_read_byte(mtd);\n+}\n+\n+static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < len; i++)\n+\t\tif (buf[i] != flctl_read_byte(mtd))\n+\t\t\treturn -EFAULT;\n+\treturn 0;\n+}\n+\n+static void flctl_register_init(struct sh_flctl *flctl, unsigned long val)\n+{\n+\twritel(val, FLCMNCR(flctl));\n+}\n+\n+static int flctl_chip_init_tail(struct mtd_info *mtd)\n+{\n+\tstruct sh_flctl *flctl = mtd_to_flctl(mtd);\n+\tstruct nand_chip *chip = &flctl->chip;\n+\n+\tif (mtd->writesize == 512) {\n+\t\tflctl->page_size = 0;\n+\t\tif (chip->chipsize > (32 << 20)) {\n+\t\t\t/* big than 32MB */\n+\t\t\tflctl->rw_ADRCNT = ADRCNT_4;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_3;\n+\t\t} else if (chip->chipsize > (2 << 16)) {\n+\t\t\t/* big than 128KB */\n+\t\t\tflctl->rw_ADRCNT = ADRCNT_3;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_2;\n+\t\t} else {\n+\t\t\tflctl->rw_ADRCNT = ADRCNT_2;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_1;\n+\t\t}\n+\t} else {\n+\t\tflctl->page_size = 1;\n+\t\tif (chip->chipsize > (128 << 20)) {\n+\t\t\t/* big than 128MB */\n+\t\t\tflctl->rw_ADRCNT = ADRCNT2_E;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_3;\n+\t\t} else if (chip->chipsize > (8 << 16)) {\n+\t\t\t/* big than 512KB */\n+\t\t\tflctl->rw_ADRCNT = ADRCNT_4;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_2;\n+\t\t} else {\n+\t\t\tflctl->rw_ADRCNT = ADRCNT_3;\n+\t\t\tflctl->erase_ADRCNT = ADRCNT_1;\n+\t\t}\n+\t}\n+\n+\tif (flctl->hwecc) {\n+\t\tif (mtd->writesize == 512) {\n+\t\t\tchip->ecc.layout = &flctl_4secc_oob_16;\n+\t\t\tchip->badblock_pattern = &flctl_4secc_smallpage;\n+\t\t} else {\n+\t\t\tchip->ecc.layout = &flctl_4secc_oob_64;\n+\t\t\tchip->badblock_pattern = &flctl_4secc_largepage;\n+\t\t}\n+\n+\t\tchip->ecc.size = 512;\n+\t\tchip->ecc.bytes = 10;\n+\t\tchip->ecc.read_page = flctl_read_page_hwecc;\n+\t\tchip->ecc.write_page = flctl_write_page_hwecc;\n+\t\tchip->ecc.mode = NAND_ECC_HW;\n+\n+\t\t/* 4 symbols ECC enabled */\n+\t\twritel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02,\n+\t\t\t\tFLCMNCR(flctl));\n+\t} else {\n+\t\tchip->ecc.mode = NAND_ECC_SOFT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int __init flctl_probe(struct platform_device *pdev)\n+{\n+\tstruct resource *res;\n+\tstruct sh_flctl *flctl;\n+\tstruct mtd_info *flctl_mtd;\n+\tstruct nand_chip *nand;\n+\tstruct sh_flctl_platform_data *pdata;\n+\tint ret;\n+\n+\tpdata = pdev->dev.platform_data;\n+\tif (pdata == NULL) {\n+\t\tprintk(KERN_ERR \"sh_flctl platform_data not found.\\n\");\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tflctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);\n+\tif (!flctl) {\n+\t\tprintk(KERN_ERR \"Unable to allocate NAND MTD dev structure.\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n+\tif (!res) {\n+\t\tprintk(KERN_ERR \"%s: resource not found.\\n\", __func__);\n+\t\tret = -ENODEV;\n+\t\tgoto err;\n+\t}\n+\n+\tflctl->reg = ioremap(res->start, res->end - res->start);\n+\tif (flctl->reg == NULL) {\n+\t\tprintk(KERN_ERR \"%s: ioremap error.\\n\", __func__);\n+\t\tret = -ENOMEM;\n+\t\tgoto err;\n+\t}\n+\n+\tplatform_set_drvdata(pdev, flctl);\n+\tflctl_mtd = &flctl->mtd;\n+\tnand = &flctl->chip;\n+\tflctl_mtd->priv = nand;\n+\tflctl->hwecc = pdata->has_hwecc;\n+\n+\tflctl_register_init(flctl, pdata->flcmncr_val);\n+\n+\tnand->options = NAND_NO_AUTOINCR;\n+\n+\t/* Set address of hardware control function */\n+\t/* 20 us command delay time */\n+\tnand->chip_delay = 20;\n+\n+\tnand->read_byte = flctl_read_byte;\n+\tnand->write_buf = flctl_write_buf;\n+\tnand->read_buf = flctl_read_buf;\n+\tnand->verify_buf = flctl_verify_buf;\n+\tnand->select_chip = flctl_select_chip;\n+\tnand->cmdfunc = flctl_cmdfunc;\n+\n+\tret = nand_scan_ident(flctl_mtd, 1);\n+\tif (ret)\n+\t\tgoto err;\n+\n+\tret = flctl_chip_init_tail(flctl_mtd);\n+\tif (ret)\n+\t\tgoto err;\n+\n+\tret = nand_scan_tail(flctl_mtd);\n+\tif (ret)\n+\t\tgoto err;\n+\n+\tadd_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts);\n+\n+\treturn 0;\n+\n+err:\n+\tkfree(flctl);\n+\treturn ret;\n+}\n+\n+static int __exit flctl_remove(struct platform_device *pdev)\n+{\n+\tstruct sh_flctl *flctl = platform_get_drvdata(pdev);\n+\n+\tnand_release(&flctl->mtd);\n+\tkfree(flctl);\n+\n+\treturn 0;\n+}\n+\n+static struct platform_driver flctl_driver = {\n+\t.probe\t\t= flctl_probe,\n+\t.remove\t\t= flctl_remove,\n+\t.driver = {\n+\t\t.name\t= \"sh_flctl\",\n+\t\t.owner\t= THIS_MODULE,\n+\t},\n+};\n+\n+static int __init flctl_nand_init(void)\n+{\n+\treturn platform_driver_register(&flctl_driver);\n+}\n+\n+static void __exit flctl_nand_cleanup(void)\n+{\n+\tplatform_driver_unregister(&flctl_driver);\n+}\n+\n+module_init(flctl_nand_init);\n+module_exit(flctl_nand_cleanup);\n+\n+MODULE_LICENSE(\"GPL\");\n+MODULE_AUTHOR(\"Yoshihiro Shimoda\");\n+MODULE_DESCRIPTION(\"SuperH FLCTL driver\");\n+MODULE_ALIAS(\"platform:sh_flctl\");\ndiff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h\nnew file mode 100644\nindex 0000000..d0ec3e3\n--- /dev/null\n+++ b/include/linux/mtd/sh_flctl.h\n@@ -0,0 +1,125 @@\n+/*\n+ * SuperH FLCTL nand controller\n+ *\n+ * Copyright (C) 2008 Renesas Solutions Corp.\n+ *\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation; version 2 of the License.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * along with this program; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n+ */\n+\n+#ifndef __SH_FLCTL_H__\n+#define __SH_FLCTL_H__\n+\n+#include <linux/mtd/mtd.h>\n+#include <linux/mtd/nand.h>\n+#include <linux/mtd/partitions.h>\n+\n+/* FLCTL registers */\n+#define FLCMNCR(f)\t\t(f->reg + 0x0)\n+#define FLCMDCR(f)\t\t(f->reg + 0x4)\n+#define FLCMCDR(f)\t\t(f->reg + 0x8)\n+#define FLADR(f)\t\t(f->reg + 0xC)\n+#define FLADR2(f)\t\t(f->reg + 0x3C)\n+#define FLDATAR(f)\t\t(f->reg + 0x10)\n+#define FLDTCNTR(f)\t\t(f->reg + 0x14)\n+#define FLINTDMACR(f)\t\t(f->reg + 0x18)\n+#define FLBSYTMR(f)\t\t(f->reg + 0x1C)\n+#define FLBSYCNT(f)\t\t(f->reg + 0x20)\n+#define FLDTFIFO(f)\t\t(f->reg + 0x24)\n+#define FLECFIFO(f)\t\t(f->reg + 0x28)\n+#define FLTRCR(f)\t\t(f->reg + 0x2C)\n+#define\tFL4ECCRESULT0(f)\t(f->reg + 0x80)\n+#define\tFL4ECCRESULT1(f)\t(f->reg + 0x84)\n+#define\tFL4ECCRESULT2(f)\t(f->reg + 0x88)\n+#define\tFL4ECCRESULT3(f)\t(f->reg + 0x8C)\n+#define\tFL4ECCCR(f)\t\t(f->reg + 0x90)\n+#define\tFL4ECCCNT(f)\t\t(f->reg + 0x94)\n+#define\tFLERRADR(f)\t\t(f->reg + 0x98)\n+\n+/* FLCMNCR control bits */\n+#define ECCPOS2\t\t(0x1 << 25)\n+#define _4ECCCNTEN\t(0x1 << 24)\n+#define _4ECCEN\t\t(0x1 << 23)\n+#define _4ECCCORRECT\t(0x1 << 22)\n+#define SNAND_E\t\t(0x1 << 18)\t/* SNAND (0=512 1=2048)*/\n+#define QTSEL_E\t\t(0x1 << 17)\n+#define ENDIAN\t\t(0x1 << 16)\t/* 1 = little endian */\n+#define FCKSEL_E\t(0x1 << 15)\n+#define ECCPOS_00\t(0x00 << 12)\n+#define ECCPOS_01\t(0x01 << 12)\n+#define ECCPOS_02\t(0x02 << 12)\n+#define ACM_SACCES_MODE\t(0x01 << 10)\n+#define NANWF_E\t\t(0x1 << 9)\n+#define SE_D\t\t(0x1 << 8)\t/* Spare area disable */\n+#define\tCE1_ENABLE\t(0x1 << 4)\t/* Chip Enable 1 */\n+#define\tCE0_ENABLE\t(0x1 << 3)\t/* Chip Enable 0 */\n+#define\tTYPESEL_SET\t(0x1 << 0)\n+\n+/* FLCMDCR control bits */\n+#define ADRCNT2_E\t(0x1 << 31)\t/* 5byte address enable */\n+#define ADRMD_E\t\t(0x1 << 26)\t/* Sector address access */\n+#define CDSRC_E\t\t(0x1 << 25)\t/* Data buffer selection */\n+#define DOSR_E\t\t(0x1 << 24)\t/* Status read check */\n+#define SELRW\t\t(0x1 << 21)\t/*  0:read 1:write */\n+#define DOADR_E\t\t(0x1 << 20)\t/* Address stage execute */\n+#define ADRCNT_1\t(0x00 << 18)\t/* Address data bytes: 1byte */\n+#define ADRCNT_2\t(0x01 << 18)\t/* Address data bytes: 2byte */\n+#define ADRCNT_3\t(0x02 << 18)\t/* Address data bytes: 3byte */\n+#define ADRCNT_4\t(0x03 << 18)\t/* Address data bytes: 4byte */\n+#define DOCMD2_E\t(0x1 << 17)\t/* 2nd cmd stage execute */\n+#define DOCMD1_E\t(0x1 << 16)\t/* 1st cmd stage execute */\n+\n+/* FLTRCR control bits */\n+#define TRSTRT\t\t(0x1 << 0)\t/* translation start */\n+#define TREND\t\t(0x1 << 1)\t/* translation end */\n+\n+/* FL4ECCCR control bits */\n+#define\t_4ECCFA\t\t(0x1 << 2)\t/* 4 symbols correct fault */\n+#define\t_4ECCEND\t(0x1 << 1)\t/* 4 symbols end */\n+#define\t_4ECCEXST\t(0x1 << 0)\t/* 4 symbols exist */\n+\n+#define INIT_FL4ECCRESULT_VAL\t0x03FF03FF\n+#define LOOP_TIMEOUT_MAX\t0x00010000\n+\n+#define mtd_to_flctl(mtd)\tcontainer_of(mtd, struct sh_flctl, mtd)\n+\n+struct sh_flctl {\n+\tstruct mtd_info\t\tmtd;\n+\tstruct nand_chip\tchip;\n+\tvoid __iomem\t\t*reg;\n+\n+\tu8\tdone_buff[2048 + 64];\t/* max size 2048 + 64 */\n+\tint\tread_bytes;\n+\tint\tindex;\n+\tint\tseqin_column;\t\t/* column in SEQIN cmd */\n+\tint\tseqin_page_addr;\t/* page_addr in SEQIN cmd */\n+\tu32\tseqin_read_cmd;\t\t/* read cmd in SEQIN cmd */\n+\tint\terase1_page_addr;\t/* page_addr in ERASE1 cmd */\n+\tu32\terase_ADRCNT;\t\t/* bits of FLCMDCR in ERASE1 cmd */\n+\tu32\trw_ADRCNT;\t/* bits of FLCMDCR in READ WRITE cmd */\n+\n+\tint\thwecc_cant_correct[4];\n+\n+\tunsigned page_size:1;\t/* NAND page size (0 = 512, 1 = 2048) */\n+\tunsigned hwecc:1;\t/* Hardware ECC (0 = disabled, 1 = enabled) */\n+};\n+\n+struct sh_flctl_platform_data {\n+\tstruct mtd_partition\t*parts;\n+\tint\t\t\tnr_parts;\n+\tunsigned long\t\tflcmncr_val;\n+\n+\tunsigned has_hwecc:1;\n+};\n+\n+#endif\t/* __SH_FLCTL_H__ */\n",
    "prefixes": []
}