From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:01 +0000
Subject: mtd: fsl-quadspi: Access multiple chips simultaneously
Message-ID: <E1ZWta1-0005HC-Nk@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=392d39cfcaa9bcfa202fb0fd3bc65f3c20de318f
Commit:     392d39cfcaa9bcfa202fb0fd3bc65f3c20de318f
Parent:     0eb8618bd07533f423fed47399a0d6387bfe7cac
Author:     Han Xu <b45815 at freescale.com>
AuthorDate: Wed May 13 14:40:57 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Jun 23 10:46:11 2015 -0700

    mtd: fsl-quadspi: Access multiple chips simultaneously
    
    Add supports for simultaneous access to multiple chips. Need to lock
    the mutex before any quad spi operations and unlock the mutex after
    operations complete.
    
    Signed-off-by: Han Xu <b45815 at freescale.com>
    [Brian: reworked err path in fsl_qspi_prep()]
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 52a872f..4fe13dd 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -26,6 +26,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
+#include <linux/mutex.h>
 
 /* The registers */
 #define QUADSPI_MCR			0x00
@@ -233,6 +234,7 @@ struct fsl_qspi {
 	u32 clk_rate;
 	unsigned int chip_base_addr; /* We may support two chips. */
 	bool has_second_chip;
+	struct mutex lock;
 };
 
 static inline int is_vybrid_qspi(struct fsl_qspi *q)
@@ -761,18 +763,24 @@ static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
 	struct fsl_qspi *q = nor->priv;
 	int ret;
 
+	mutex_lock(&q->lock);
 	ret = clk_enable(q->clk_en);
 	if (ret)
-		return ret;
+		goto err_mutex;
 
 	ret = clk_enable(q->clk);
-	if (ret) {
-		clk_disable(q->clk_en);
-		return ret;
-	}
+	if (ret)
+		goto err_clk;
 
 	fsl_qspi_set_base_addr(q, nor);
 	return 0;
+
+err_clk:
+	clk_disable(q->clk_en);
+err_mutex:
+	mutex_unlock(&q->lock);
+
+	return ret;
 }
 
 static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
@@ -781,6 +789,7 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 
 	clk_disable(q->clk);
 	clk_disable(q->clk_en);
+	mutex_unlock(&q->lock);
 }
 
 static int fsl_qspi_probe(struct platform_device *pdev)
@@ -864,6 +873,8 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
 		q->has_second_chip = true;
 
+	mutex_init(&q->lock);
+
 	/* iterate the subnodes. */
 	for_each_available_child_of_node(dev->of_node, np) {
 		char modalias[40];
@@ -892,24 +903,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 		ret = of_modalias_node(np, modalias, sizeof(modalias));
 		if (ret < 0)
-			goto irq_failed;
+			goto mutex_failed;
 
 		ret = of_property_read_u32(np, "spi-max-frequency",
 				&q->clk_rate);
 		if (ret < 0)
-			goto irq_failed;
+			goto mutex_failed;
 
 		/* set the chip address for READID */
 		fsl_qspi_set_base_addr(q, nor);
 
 		ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
 		if (ret)
-			goto irq_failed;
+			goto mutex_failed;
 
 		ppdata.of_node = np;
 		ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
 		if (ret)
-			goto irq_failed;
+			goto mutex_failed;
 
 		/* Set the correct NOR size now. */
 		if (q->nor_size == 0) {
@@ -950,6 +961,8 @@ last_init_failed:
 			i *= 2;
 		mtd_device_unregister(&q->mtd[i]);
 	}
+mutex_failed:
+	mutex_destroy(&q->lock);
 irq_failed:
 	clk_disable_unprepare(q->clk);
 clk_failed:
@@ -973,6 +986,7 @@ static int fsl_qspi_remove(struct platform_device *pdev)
 	writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
 	writel(0x0, q->iobase + QUADSPI_RSER);
 
+	mutex_destroy(&q->lock);
 	clk_unprepare(q->clk);
 	clk_unprepare(q->clk_en);
 	return 0;


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:01 +0000
Subject: mtd: nandsim: fix free of NULL pointer
Message-ID: <E1ZWta1-0005HZ-PM@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=ec7478fa173f65e5ee5fd2ba42c59ca3e700027b
Commit:     ec7478fa173f65e5ee5fd2ba42c59ca3e700027b
Parent:     83dcf400be7165af938dbd6b8ce6805c754701db
Author:     shengyong <shengyong1 at huawei.com>
AuthorDate: Thu Jun 25 02:23:13 2015 +0000
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 6 15:20:09 2015 -0700

    mtd: nandsim: fix free of NULL pointer
    
    If allocating ns->nand_pages_slab fails, do not try to destroy it when
    cleaning up nandsim resources.
    
    Signed-off-by: Sheng Yong <shengyong1 at huawei.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/nandsim.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 52c0c1a..6a74f62 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -649,7 +649,8 @@ static void free_device(struct nandsim *ns)
 				kmem_cache_free(ns->nand_pages_slab,
 						ns->pages[i].byte);
 		}
-		kmem_cache_destroy(ns->nand_pages_slab);
+		if (ns->nand_pages_slab)
+			kmem_cache_destroy(ns->nand_pages_slab);
 		vfree(ns->pages);
 	}
 }


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:01 +0000
Subject: mtd: nandsim: fix double free
Message-ID: <E1ZWta1-0005Hy-Qx@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=5891a8d11f79b9a45a7334a63d0fa731875bc308
Commit:     5891a8d11f79b9a45a7334a63d0fa731875bc308
Parent:     ec7478fa173f65e5ee5fd2ba42c59ca3e700027b
Author:     shengyong <shengyong1 at huawei.com>
AuthorDate: Thu Jun 25 02:23:14 2015 +0000
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 6 15:20:10 2015 -0700

    mtd: nandsim: fix double free
    
    Do not call free_device() in init_nandsim, the caller - ns_init_module -
    will take care of that if something goes wrong.
    
    Signed-off-by: Sheng Yong <shengyong1 at huawei.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/nandsim.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 6a74f62..95d0cc4 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -730,8 +730,7 @@ static int init_nandsim(struct mtd_info *mtd)
 	/* Fill the partition_info structure */
 	if (parts_num > ARRAY_SIZE(ns->partitions)) {
 		NS_ERR("too many partitions.\n");
-		ret = -EINVAL;
-		goto error;
+		return -EINVAL;
 	}
 	remains = ns->geom.totsz;
 	next_offset = 0;
@@ -740,14 +739,12 @@ static int init_nandsim(struct mtd_info *mtd)
 
 		if (!part_sz || part_sz > remains) {
 			NS_ERR("bad partition size.\n");
-			ret = -EINVAL;
-			goto error;
+			return -EINVAL;
 		}
 		ns->partitions[i].name   = get_partition_name(i);
 		if (!ns->partitions[i].name) {
 			NS_ERR("unable to allocate memory.\n");
-			ret = -ENOMEM;
-			goto error;
+			return -ENOMEM;
 		}
 		ns->partitions[i].offset = next_offset;
 		ns->partitions[i].size   = part_sz;
@@ -758,14 +755,12 @@ static int init_nandsim(struct mtd_info *mtd)
 	if (remains) {
 		if (parts_num + 1 > ARRAY_SIZE(ns->partitions)) {
 			NS_ERR("too many partitions.\n");
-			ret = -EINVAL;
-			goto error;
+			return -EINVAL;
 		}
 		ns->partitions[i].name   = get_partition_name(i);
 		if (!ns->partitions[i].name) {
 			NS_ERR("unable to allocate memory.\n");
-			ret = -ENOMEM;
-			goto error;
+			return -ENOMEM;
 		}
 		ns->partitions[i].offset = next_offset;
 		ns->partitions[i].size   = remains;
@@ -793,24 +788,18 @@ static int init_nandsim(struct mtd_info *mtd)
 	printk("options: %#x\n",                ns->options);
 
 	if ((ret = alloc_device(ns)) != 0)
-		goto error;
+		return ret;
 
 	/* Allocate / initialize the internal buffer */
 	ns->buf.byte = kmalloc(ns->geom.pgszoob, GFP_KERNEL);
 	if (!ns->buf.byte) {
 		NS_ERR("init_nandsim: unable to allocate %u bytes for the internal buffer\n",
 			ns->geom.pgszoob);
-		ret = -ENOMEM;
-		goto error;
+		return -ENOMEM;
 	}
 	memset(ns->buf.byte, 0xFF, ns->geom.pgszoob);
 
 	return 0;
-
-error:
-	free_device(ns);
-
-	return ret;
 }
 
 /*


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:01 +0000
Subject: nand: davinci: add support for 4K page size nand devices
Message-ID: <E1ZWta1-0005IN-Sq@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=a11244c0b25b79d2a3b07df429268d66736e5b45
Commit:     a11244c0b25b79d2a3b07df429268d66736e5b45
Parent:     906b1f536d5b1a26e549c78a07b664f22340b7df
Author:     Sandeep Paulraj <s-paulraj at ti.com>
AuthorDate: Tue Aug 19 15:31:54 2014 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 09:58:15 2015 -0700

    nand: davinci: add support for 4K page size nand devices
    
    It is needed for k2l keystone2 EVM which uses NAND flash with 4K page
    size, hence add support for 4K page size nand devices.
    
    [Brian: similar work submitted by Murali Karicheri <m-karicheri2 at ti.com>
    and Hao Zhang <hzhang at ti.com>]
    
    Signed-off-by: Sandeep Paulraj <s-paulraj at ti.com>
    Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk at ti.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/davinci_nand.c | 42 ++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index feb6d18..b9080130 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -520,6 +520,32 @@ static struct nand_ecclayout hwecc4_2048 = {
 	},
 };
 
+/*
+ * An ECC layout for using 4-bit ECC with large-page (4096bytes) flash,
+ * storing ten ECC bytes plus the manufacturer's bad block marker byte,
+ * and not overlapping the default BBT markers.
+ */
+static struct nand_ecclayout hwecc4_4096 = {
+	.eccbytes = 80,
+	.eccpos = {
+		/* at the end of spare sector */
+		48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+		58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+		68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+		78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+		88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+		98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+		108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+		118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+	},
+	.oobfree = {
+		/* 2 bytes at offset 0 hold manufacturer badblock markers */
+		{.offset = 2, .length = 46, },
+		/* 5 bytes at offset 8 hold BBT markers */
+		/* 8 bytes at offset 16 hold JFFS2 clean markers */
+	},
+};
+
 #if defined(CONFIG_OF)
 static const struct of_device_id davinci_nand_of_match[] = {
 	{.compatible = "ti,davinci-nand", },
@@ -796,18 +822,12 @@ static int nand_davinci_probe(struct platform_device *pdev)
 			info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
 			goto syndrome_done;
 		}
+		if (chunks == 8) {
+			info->ecclayout = hwecc4_4096;
+			info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
+			goto syndrome_done;
+		}
 
-		/* 4KiB page chips are not yet supported. The eccpos from
-		 * nand_ecclayout cannot hold 80 bytes and change to eccpos[]
-		 * breaks userspace ioctl interface with mtd-utils. Once we
-		 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
-		 * for the 4KiB page chips.
-		 *
-		 * TODO: Note that nand_ecclayout has now been expanded and can
-		 *  hold plenty of OOB entries.
-		 */
-		dev_warn(&pdev->dev, "no 4-bit ECC support yet "
-				"for 4KiB-page NAND\n");
 		ret = -EIO;
 		goto err;
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:01 +0000
Subject: mtd: r852: make ecc_reg 32-bit in r852_ecc_correct
Message-ID: <E1ZWta1-0005In-W4@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=cef1ed9c6bcf69245c0b9eb89b3f3a45049ba10c
Commit:     cef1ed9c6bcf69245c0b9eb89b3f3a45049ba10c
Parent:     a11244c0b25b79d2a3b07df429268d66736e5b45
Author:     Nicolas Iooss <nicolas.iooss_linux at m4x.org>
AuthorDate: Sun Jul 5 09:57:41 2015 +0800
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 10:38:25 2015 -0700

    mtd: r852: make ecc_reg 32-bit in r852_ecc_correct
    
    r852_ecc_correct() reads a 32-bit register into a 16-bit variable,
    ecc_reg, but this variable is later used as if it was larger.  This is
    reported by clang when building the kernel with many warnings:
    
        drivers/mtd/nand/r852.c:512:11: error: shift count >= width of type
        [-Werror,-Wshift-count-overflow]
                        ecc_reg >>= 16;
                                ^   ~~
    Fix this by making ecc_reg 32-bit, like the return type of
    r852_read_reg_dword().
    
    Signed-off-by: Nicolas Iooss <nicolas.iooss_linux at m4x.org>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/r852.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c
index 77e96d2..cc6bac5 100644
--- a/drivers/mtd/nand/r852.c
+++ b/drivers/mtd/nand/r852.c
@@ -466,7 +466,7 @@ static int r852_ecc_calculate(struct mtd_info *mtd, const uint8_t *dat,
 static int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat,
 				uint8_t *read_ecc, uint8_t *calc_ecc)
 {
-	uint16_t ecc_reg;
+	uint32_t ecc_reg;
 	uint8_t ecc_status, err_byte;
 	int i, error = 0;
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: fsl-quadspi: Actually clear TX FIFO upon write
Message-ID: <E1ZWta2-0005JC-1j@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=038761dfe4ce145f0f080cc08ee43f6e0ab3ae2f
Commit:     038761dfe4ce145f0f080cc08ee43f6e0ab3ae2f
Parent:     cef1ed9c6bcf69245c0b9eb89b3f3a45049ba10c
Author:     Alexander Stein <alexander.stein at systec-electronic.com>
AuthorDate: Thu Jul 2 11:37:56 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 10:41:33 2015 -0700

    mtd: fsl-quadspi: Actually clear TX FIFO upon write
    
    QUADSPI_MCR_CLR_TXF_MASK is the correct mask for clearing the TX FIFO.
    
    Signed-off-by: Alexander Stein <alexander.stein at systec-electronic.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 4fe13dd..1946c6d 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -539,7 +539,7 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
 
 	/* clear the TX FIFO. */
 	tmp = readl(q->iobase + QUADSPI_MCR);
-	writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
+	writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
 
 	/* fill the TX data to the FIFO */
 	for (j = 0, i = ((count + 3) / 4); j < i; j++) {


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: spi-nor: set SECT_4K for n25q064 SPI flash
Message-ID: <E1ZWta2-0005Jb-49@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0db7fae2736d0db920905c1fb576ec7eab2660c8
Commit:     0db7fae2736d0db920905c1fb576ec7eab2660c8
Parent:     038761dfe4ce145f0f080cc08ee43f6e0ab3ae2f
Author:     Alexey Firago <alexey_firago at mentor.com>
AuthorDate: Tue Jun 30 12:53:46 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 10:43:19 2015 -0700

    mtd: spi-nor: set SECT_4K for n25q064 SPI flash
    
    Micron n25q064 flash supports 4 KiB erase sectors.
    
    Signed-off-by: Alexey Firago <alexey_firago at mentor.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index d78831b..b2e8c3b 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -589,7 +589,7 @@ static const struct spi_device_id spi_nor_ids[] = {
 
 	/* Micron */
 	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
-	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SPI_NOR_QUAD_READ) },
+	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
 	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: nand: sunxi: Replace failsafe timing cfg with calculated value
Message-ID: <E1ZWta2-0005K1-78@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=9c618292dba6aa9b82e8a2e4e6fe70f54bd87a81
Commit:     9c618292dba6aa9b82e8a2e4e6fe70f54bd87a81
Parent:     0db7fae2736d0db920905c1fb576ec7eab2660c8
Author:     Roy Spliet <r.spliet at ultimaker.com>
AuthorDate: Fri Jun 26 11:00:10 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 10:45:52 2015 -0700

    mtd: nand: sunxi: Replace failsafe timing cfg with calculated value
    
    The TIMING_CFG register was previously statically set to a magic value
    (extracted from Allwinner's BSP) when initializing the NAND controller.
    Now that we have more details about the TIMING_CFG register layout
    (extracted from the A83 user manual) we can dynamically calculate the
    appropriate value for each NAND chip and set it when selecting the
    chip.
    
    Signed-off-by: Roy Spliet <r.spliet at ultimaker.com>
    Acked-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/sunxi_nand.c | 73 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 6f93b29..663e331 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -99,6 +99,12 @@
 				 NFC_CMD_INT_ENABLE | \
 				 NFC_DMA_INT_ENABLE)
 
+/* define NFC_TIMING_CFG register layout */
+#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD)		\
+	(((tWB) & 0x3) | (((tADL) & 0x3) << 2) |		\
+	(((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) |		\
+	(((tCAD) & 0x7) << 8))
+
 /* define bit use in NFC_CMD */
 #define NFC_CMD_LOW_BYTE	GENMASK(7, 0)
 #define NFC_CMD_HIGH_BYTE	GENMASK(15, 8)
@@ -208,6 +214,7 @@ struct sunxi_nand_hw_ecc {
  * @nand:		base NAND chip structure
  * @mtd:		base MTD structure
  * @clk_rate:		clk_rate required for this NAND chip
+ * @timing_cfg		TIMING_CFG register value for this NAND chip
  * @selected:		current active CS
  * @nsels:		number of CS lines required by the NAND chip
  * @sels:		array of CS lines descriptions
@@ -217,6 +224,7 @@ struct sunxi_nand_chip {
 	struct nand_chip nand;
 	struct mtd_info mtd;
 	unsigned long clk_rate;
+	u32 timing_cfg;
 	int selected;
 	int nsels;
 	struct sunxi_nand_chip_sel sels[0];
@@ -403,6 +411,7 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
 		}
 	}
 
+	writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
 	writel(ctl, nfc->regs + NFC_REG_CTL);
 
 	sunxi_nand->selected = chip;
@@ -807,10 +816,33 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
 	return 0;
 }
 
+static const s32 tWB_lut[] = {6, 12, 16, 20};
+static const s32 tRHW_lut[] = {4, 8, 12, 20};
+
+static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
+		u32 clk_period)
+{
+	u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
+	int i;
+
+	for (i = 0; i < lut_size; i++) {
+		if (clk_cycles <= lut[i])
+			return i;
+	}
+
+	/* Doesn't fit */
+	return -EINVAL;
+}
+
+#define sunxi_nand_lookup_timing(l, p, c) \
+			_sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
+
 static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
 				       const struct nand_sdr_timings *timings)
 {
+	struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller);
 	u32 min_clk_period = 0;
+	s32 tWB, tADL, tWHR, tRHW, tCAD;
 
 	/* T1 <=> tCLS */
 	if (timings->tCLS_min > min_clk_period)
@@ -872,6 +904,41 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
 	if (timings->tWC_min > (min_clk_period * 2))
 		min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
 
+	/* T16 - T19 + tCAD */
+	tWB  = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
+					min_clk_period);
+	if (tWB < 0) {
+		dev_err(nfc->dev, "unsupported tWB\n");
+		return tWB;
+	}
+
+	tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
+	if (tADL > 3) {
+		dev_err(nfc->dev, "unsupported tADL\n");
+		return -EINVAL;
+	}
+
+	tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
+	if (tWHR > 3) {
+		dev_err(nfc->dev, "unsupported tWHR\n");
+		return -EINVAL;
+	}
+
+	tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
+					min_clk_period);
+	if (tRHW < 0) {
+		dev_err(nfc->dev, "unsupported tRHW\n");
+		return tRHW;
+	}
+
+	/*
+	 * TODO: according to ONFI specs this value only applies for DDR NAND,
+	 * but Allwinner seems to set this to 0x7. Mimic them for now.
+	 */
+	tCAD = 0x7;
+
+	/* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
+	chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
 
 	/* Convert min_clk_period from picoseconds to nanoseconds */
 	min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
@@ -884,8 +951,6 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
 	 */
 	chip->clk_rate = (2 * NSEC_PER_SEC) / min_clk_period;
 
-	/* TODO: configure T16-T19 */
-
 	return 0;
 }
 
@@ -1377,11 +1442,9 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, nfc);
 
 	/*
-	 * TODO: replace these magic values with proper flags as soon as we
-	 * know what they are encoding.
+	 * TODO: replace this magic value with EDO flag
 	 */
 	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
-	writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG);
 
 	ret = sunxi_nand_chips_init(dev, nfc);
 	if (ret) {


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: nand: sunxi: Set serial access mode correctly
Message-ID: <E1ZWta2-0005KT-AO@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=d052e508a4069f0711ea68156f4b1565bf14c41c
Commit:     d052e508a4069f0711ea68156f4b1565bf14c41c
Parent:     9c618292dba6aa9b82e8a2e4e6fe70f54bd87a81
Author:     Roy Spliet <r.spliet at ultimaker.com>
AuthorDate: Fri Jun 26 11:00:11 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jul 20 10:45:53 2015 -0700

    mtd: nand: sunxi: Set serial access mode correctly
    
    Replaces the hard coded "always use EDO" policy with that prescribed
    by the ONFI 3.1 specification that EDO mode should always be used if tRC
    is below 30ns.
    
    Signed-off-by: Roy Spliet <r.spliet at ultimaker.com>
    Acked-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/sunxi_nand.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 663e331..f97a58d 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -99,6 +99,9 @@
 				 NFC_CMD_INT_ENABLE | \
 				 NFC_DMA_INT_ENABLE)
 
+/* define bit use in NFC_TIMING_CTL */
+#define NFC_TIMING_CTL_EDO	BIT(8)
+
 /* define NFC_TIMING_CFG register layout */
 #define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD)		\
 	(((tWB) & 0x3) | (((tADL) & 0x3) << 2) |		\
@@ -225,6 +228,7 @@ struct sunxi_nand_chip {
 	struct mtd_info mtd;
 	unsigned long clk_rate;
 	u32 timing_cfg;
+	u32 timing_ctl;
 	int selected;
 	int nsels;
 	struct sunxi_nand_chip_sel sels[0];
@@ -411,6 +415,7 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
 		}
 	}
 
+	writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
 	writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
 	writel(ctl, nfc->regs + NFC_REG_CTL);
 
@@ -940,6 +945,13 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
 	/* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
 	chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
 
+	/*
+	 * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
+	 * output cycle timings shall be used if the host drives tRC less than
+	 * 30 ns.
+	 */
+	chip->timing_ctl = (timings->tRC_min < 30000) ? NFC_TIMING_CTL_EDO : 0;
+
 	/* Convert min_clk_period from picoseconds to nanoseconds */
 	min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
 
@@ -1441,11 +1453,6 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, nfc);
 
-	/*
-	 * TODO: replace this magic value with EDO flag
-	 */
-	writel(0x100, nfc->regs + NFC_REG_TIMING_CTL);
-
 	ret = sunxi_nand_chips_init(dev, nfc);
 	if (ret) {
 		dev_err(dev, "failed to init nand chips\n");


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: m25p80: allow arbitrary OF matching for "jedec,spi-nor"
Message-ID: <E1ZWta2-0005Ks-Ct@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=43163022927b6e7d202a7e6f939c3f392465494d
Commit:     43163022927b6e7d202a7e6f939c3f392465494d
Parent:     d052e508a4069f0711ea68156f4b1565bf14c41c
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Tue May 19 14:38:22 2015 -0700
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Jul 21 09:33:42 2015 -0700

    mtd: m25p80: allow arbitrary OF matching for "jedec,spi-nor"
    
    When we added the "jedec,spi-nor" compatible string for use in this
    driver, we added it as a modalias option. The modalias can be derived in
    different ways for platform devices vs. device tree (of_*) matching. But
    for device tree matching (the primary target of this identifier string),
    the modalias is determined from the first entry in the 'compatible'
    property. IOW, the following properties would bind to this driver:
    
    	// Option (a), modalias = "spi-nor"
    	compatible = "jedec,spi-nor";
    
    	// Option (b), modalias = "spi-nor"
    	compatible = "idontknowwhatimdoing,spi-nor";
    
    But the following would not:
    
    	// Option (c), modalias = "shinynewdevice"
    	compatible = "myvendor,shinynewdevice", "jedec,spi-nor";
    
    So, we'd like to match (a) and (c) (even when we don't have an explicit
    entry for "shinynewdevice"), and we'd rather not allow (b).
    
    To do this, we
      (1) always (for devices without specific platform data) pass the
          modalias to the spi-nor library;
      (2) rework the spi-nor library to not reject "bad" names, and
          instead just fall back to autodetection; and
      (3) add the .of_match_table to properly catch all "jedec,spi-nor".
    
    This allows (a) and (c) without warnings, and rejects (b).
    
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/m25p80.c  | 18 +++++++++++-------
 drivers/mtd/spi-nor/spi-nor.c |  8 ++++----
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d313f948b..9cd3631 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -223,8 +223,6 @@ static int m25p_probe(struct spi_device *spi)
 	 */
 	if (data && data->type)
 		flash_name = data->type;
-	else if (!strcmp(spi->modalias, "spi-nor"))
-		flash_name = NULL; /* auto-detect */
 	else
 		flash_name = spi->modalias;
 
@@ -289,19 +287,25 @@ static const struct spi_device_id m25p_ids[] = {
 	{"m25p40-nonjedec"},	{"m25p80-nonjedec"},	{"m25p16-nonjedec"},
 	{"m25p32-nonjedec"},	{"m25p64-nonjedec"},	{"m25p128-nonjedec"},
 
-	/*
-	 * Generic support for SPI NOR that can be identified by the JEDEC READ
-	 * ID opcode (0x9F). Use this, if possible.
-	 */
-	{"spi-nor"},
 	{ },
 };
 MODULE_DEVICE_TABLE(spi, m25p_ids);
 
+static const struct of_device_id m25p_of_table[] = {
+	/*
+	 * Generic compatibility for SPI NOR that can be identified by the
+	 * JEDEC READ ID opcode (0x9F). Use this, if possible.
+	 */
+	{ .compatible = "jedec,spi-nor" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, m25p_of_table);
+
 static struct spi_driver m25p80_driver = {
 	.driver = {
 		.name	= "m25p80",
 		.owner	= THIS_MODULE,
+		.of_match_table = m25p_of_table,
 	},
 	.id_table	= m25p_ids,
 	.probe	= m25p_probe,
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index b2e8c3b..47516d3 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1015,11 +1015,11 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	if (ret)
 		return ret;
 
-	/* Try to auto-detect if chip name wasn't specified */
-	if (!name)
-		id = spi_nor_read_id(nor);
-	else
+	if (name)
 		id = spi_nor_match_id(name);
+	/* Try to auto-detect if chip name wasn't specified or not found */
+	if (!id)
+		id = spi_nor_read_id(nor);
 	if (IS_ERR_OR_NULL(id))
 		return -ENOENT;
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: spi-nor: fsl-quadspi: dynamically map memory space for AHB read
Message-ID: <E1ZWta2-0005LJ-FA@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=49bd706aac8fe7fa90988ecd3fd5c276575b194e
Commit:     49bd706aac8fe7fa90988ecd3fd5c276575b194e
Parent:     43163022927b6e7d202a7e6f939c3f392465494d
Author:     Han Xu <han.xu at freescale.com>
AuthorDate: Tue Aug 4 10:25:22 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:39 2015 -0700

    mtd: spi-nor: fsl-quadspi: dynamically map memory space for AHB read
    
    QSPI may failed to map enough memory (256MB) for AHB read in
    previous implementation, especially in 3G/1G memory layout kernel.
    Dynamically map memory to avoid such issue.
    
    This implementation generally map QUADSPI_MAX_IOMAP (default 4MB) memory
    for AHB read, it should be enough for common scenarios, and the side
    effect (0.6% performance drop) is minor.
    
    Previous implementation
    
    root at imx6qdlsolo:~# dd if=/dev/mtd0 of=/dev/null bs=1K count=32K
    32768+0 records in
    32768+0 records out
    33554432 bytes (34 MB) copied, 2.16006 s, 15.5 MB/s
    
    root at imx6qdlsolo:~# dd if=/dev/mtd0 of=/dev/null bs=32M count=1
    1+0 records in
    1+0 records out
    33554432 bytes (34 MB) copied, 1.43149 s, 23.4 MB/s
    
    After applied the patch
    
    root at imx6qdlsolo:~# dd if=/dev/mtd0 of=/dev/null bs=1K count=32K
    32768+0 records in
    32768+0 records out
    33554432 bytes (34 MB) copied, 2.1743 s, 15.4 MB/s
    
    root at imx6qdlsolo:~# dd if=/dev/mtd0 of=/dev/null bs=32M count=1
    1+0 records in
    1+0 records out
    33554432 bytes (34 MB) copied, 1.43158 s, 23.4 MB/s
    
    Signed-off-by: Han Xu <han.xu at freescale.com>
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 55 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 1946c6d..2d46036 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -192,6 +192,8 @@
 #define SEQID_EN4B		10
 #define SEQID_BRWR		11
 
+#define QUADSPI_MIN_IOMAP SZ_4M
+
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
@@ -223,8 +225,10 @@ struct fsl_qspi {
 	struct mtd_info mtd[FSL_QSPI_MAX_CHIP];
 	struct spi_nor nor[FSL_QSPI_MAX_CHIP];
 	void __iomem *iobase;
-	void __iomem *ahb_base; /* Used when read from AHB bus */
+	void __iomem *ahb_addr;
 	u32 memmap_phy;
+	u32 memmap_offs;
+	u32 memmap_len;
 	struct clk *clk, *clk_en;
 	struct device *dev;
 	struct completion c;
@@ -732,11 +736,42 @@ static int fsl_qspi_read(struct spi_nor *nor, loff_t from,
 	struct fsl_qspi *q = nor->priv;
 	u8 cmd = nor->read_opcode;
 
-	dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n",
-		cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len);
+	/* if necessary,ioremap buffer before AHB read, */
+	if (!q->ahb_addr) {
+		q->memmap_offs = q->chip_base_addr + from;
+		q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
+
+		q->ahb_addr = ioremap_nocache(
+				q->memmap_phy + q->memmap_offs,
+				q->memmap_len);
+		if (!q->ahb_addr) {
+			dev_err(q->dev, "ioremap failed\n");
+			return -ENOMEM;
+		}
+	/* ioremap if the data requested is out of range */
+	} else if (q->chip_base_addr + from < q->memmap_offs
+			|| q->chip_base_addr + from + len >
+			q->memmap_offs + q->memmap_len) {
+		iounmap(q->ahb_addr);
+
+		q->memmap_offs = q->chip_base_addr + from;
+		q->memmap_len = len > QUADSPI_MIN_IOMAP ? len : QUADSPI_MIN_IOMAP;
+		q->ahb_addr = ioremap_nocache(
+				q->memmap_phy + q->memmap_offs,
+				q->memmap_len);
+		if (!q->ahb_addr) {
+			dev_err(q->dev, "ioremap failed\n");
+			return -ENOMEM;
+		}
+	}
+
+	dev_dbg(q->dev, "cmd [%x],read from 0x%p, len:%d\n",
+		cmd, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
+		len);
 
 	/* Read out the data directly from the AHB buffer.*/
-	memcpy(buf, q->ahb_base + q->chip_base_addr + from, len);
+	memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
+		len);
 
 	*retlen += len;
 	return 0;
@@ -821,9 +856,11 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 					"QuadSPI-memory");
-	q->ahb_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(q->ahb_base))
-		return PTR_ERR(q->ahb_base);
+	if (!devm_request_mem_region(dev, res->start, resource_size(res),
+				     res->name)) {
+		dev_err(dev, "can't request region for resource %pR\n", res);
+		return -EBUSY;
+	}
 
 	q->memmap_phy = res->start;
 
@@ -989,6 +1026,10 @@ static int fsl_qspi_remove(struct platform_device *pdev)
 	mutex_destroy(&q->lock);
 	clk_unprepare(q->clk);
 	clk_unprepare(q->clk_en);
+
+	if (q->ahb_addr)
+		iounmap(q->ahb_addr);
+
 	return 0;
 }
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: spi-nor: fsl-quadspi: use quirk to distinguish different qspi
 version
Message-ID: <E1ZWta2-0005Ll-JC@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=80d37724089bc5d09fa12601a763bde01899ba88
Commit:     80d37724089bc5d09fa12601a763bde01899ba88
Parent:     49bd706aac8fe7fa90988ecd3fd5c276575b194e
Author:     Han Xu <han.xu at freescale.com>
AuthorDate: Tue Aug 4 10:25:29 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:39 2015 -0700

    mtd: spi-nor: fsl-quadspi: use quirk to distinguish different qspi version
    
    add several quirk to distinguish different version of qspi module.
    
    Signed-off-by: Han Xu <han.xu at freescale.com>
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 2d46036..91bfeac 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -28,6 +28,11 @@
 #include <linux/mtd/spi-nor.h>
 #include <linux/mutex.h>
 
+/* Controller needs driver to swap endian */
+#define QUADSPI_QUIRK_SWAP_ENDIAN	(1 << 0)
+/* Controller needs 4x internal clock */
+#define QUADSPI_QUIRK_4X_INT_CLK	(1 << 1)
+
 /* The registers */
 #define QUADSPI_MCR			0x00
 #define QUADSPI_MCR_RESERVED_SHIFT	16
@@ -204,20 +209,23 @@ struct fsl_qspi_devtype_data {
 	int rxfifo;
 	int txfifo;
 	int ahb_buf_size;
+	int driver_data;
 };
 
 static struct fsl_qspi_devtype_data vybrid_data = {
 	.devtype = FSL_QUADSPI_VYBRID,
 	.rxfifo = 128,
 	.txfifo = 64,
-	.ahb_buf_size = 1024
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
 };
 
 static struct fsl_qspi_devtype_data imx6sx_data = {
 	.devtype = FSL_QUADSPI_IMX6SX,
 	.rxfifo = 128,
 	.txfifo = 512,
-	.ahb_buf_size = 1024
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_4X_INT_CLK,
 };
 
 #define FSL_QSPI_MAX_CHIP	4
@@ -241,14 +249,14 @@ struct fsl_qspi {
 	struct mutex lock;
 };
 
-static inline int is_vybrid_qspi(struct fsl_qspi *q)
+static inline int needs_swap_endian(struct fsl_qspi *q)
 {
-	return q->devtype_data->devtype == FSL_QUADSPI_VYBRID;
+	return q->devtype_data->driver_data & QUADSPI_QUIRK_SWAP_ENDIAN;
 }
 
-static inline int is_imx6sx_qspi(struct fsl_qspi *q)
+static inline int needs_4x_clock(struct fsl_qspi *q)
 {
-	return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX;
+	return q->devtype_data->driver_data & QUADSPI_QUIRK_4X_INT_CLK;
 }
 
 /*
@@ -257,7 +265,7 @@ static inline int is_imx6sx_qspi(struct fsl_qspi *q)
  */
 static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
 {
-	return is_vybrid_qspi(q) ? __swab32(a) : a;
+	return needs_swap_endian(q) ? __swab32(a) : a;
 }
 
 static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
@@ -652,7 +660,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	unsigned long rate = q->clk_rate;
 	int ret;
 
-	if (is_imx6sx_qspi(q))
+	if (needs_4x_clock(q))
 		rate *= 4;
 
 	ret = clk_set_rate(q->clk, rate);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: spi-nor: fsl-quadspi: add imx7d support
Message-ID: <E1ZWta2-0005MA-La@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=d371cbfc151c6a7229150da0954d1f74ea4dcd39
Commit:     d371cbfc151c6a7229150da0954d1f74ea4dcd39
Parent:     80d37724089bc5d09fa12601a763bde01899ba88
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:25:35 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:40 2015 -0700

    mtd: spi-nor: fsl-quadspi: add imx7d support
    
    Support i.mx7d.
    quadspi in i.mx7d increase rxfifo.
    require fill at least 16byte to trigger data transfer.
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Han Xu <han.xu at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 91bfeac..b567756 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -32,6 +32,11 @@
 #define QUADSPI_QUIRK_SWAP_ENDIAN	(1 << 0)
 /* Controller needs 4x internal clock */
 #define QUADSPI_QUIRK_4X_INT_CLK	(1 << 1)
+/*
+ * TKT253890, Controller needs driver to fill txfifo till 16 byte to
+ * trigger data transfer even though extern data will not transferred.
+ */
+#define QUADSPI_QUIRK_TKT253890		(1 << 2)
 
 /* The registers */
 #define QUADSPI_MCR			0x00
@@ -202,6 +207,7 @@
 enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
+	FSL_QUADSPI_IMX7D,
 };
 
 struct fsl_qspi_devtype_data {
@@ -228,6 +234,15 @@ static struct fsl_qspi_devtype_data imx6sx_data = {
 	.driver_data = QUADSPI_QUIRK_4X_INT_CLK,
 };
 
+static struct fsl_qspi_devtype_data imx7d_data = {
+	.devtype = FSL_QUADSPI_IMX7D,
+	.rxfifo = 512,
+	.txfifo = 512,
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_TKT253890
+		       | QUADSPI_QUIRK_4X_INT_CLK,
+};
+
 #define FSL_QSPI_MAX_CHIP	4
 struct fsl_qspi {
 	struct mtd_info mtd[FSL_QSPI_MAX_CHIP];
@@ -259,6 +274,11 @@ static inline int needs_4x_clock(struct fsl_qspi *q)
 	return q->devtype_data->driver_data & QUADSPI_QUIRK_4X_INT_CLK;
 }
 
+static inline int needs_fill_txfifo(struct fsl_qspi *q)
+{
+	return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT253890;
+}
+
 /*
  * An IC bug makes us to re-arrange the 32-bit data.
  * The following chips, such as IMX6SLX, have fixed this bug.
@@ -560,6 +580,11 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
 		txbuf++;
 	}
 
+	/* fill the TXFIFO upto 16 bytes for i.MX7d */
+	if (needs_fill_txfifo(q))
+		for (; i < 4; i++)
+			writel(tmp, q->iobase + QUADSPI_TBDR);
+
 	/* Trigger it */
 	ret = fsl_qspi_runcmd(q, opcode, to, count);
 
@@ -679,6 +704,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 static const struct of_device_id fsl_qspi_dt_ids[] = {
 	{ .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
 	{ .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
+	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: Documentation: fsl-quadspi: Add fsl, imx7d-qspi compatible string
Message-ID: <E1ZWta2-0005MZ-O7@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=151b49e19119da28dfcd29561147ec56913cbe61
Commit:     151b49e19119da28dfcd29561147ec56913cbe61
Parent:     d371cbfc151c6a7229150da0954d1f74ea4dcd39
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:25:41 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:40 2015 -0700

    Documentation: fsl-quadspi: Add fsl, imx7d-qspi compatible string
    
    new compatible string: "fsl,imx7d-qspi"
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 Documentation/devicetree/bindings/mtd/fsl-quadspi.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 4461dc7..ca72696 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -1,7 +1,8 @@
 * Freescale Quad Serial Peripheral Interface(QuadSPI)
 
 Required properties:
-  - compatible : Should be "fsl,vf610-qspi" or "fsl,imx6sx-qspi"
+  - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi",
+		 "fsl,imx7d-qspi"
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
   - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:02 +0000
Subject: mtd: spi-nor: fsl-quadspi: add i.mx6ul support
Message-ID: <E1ZWta2-0005Mz-T4@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=74a081d14f579d0a1de845ba63e8ee5f0c511258
Commit:     74a081d14f579d0a1de845ba63e8ee5f0c511258
Parent:     151b49e19119da28dfcd29561147ec56913cbe61
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:25:47 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:41 2015 -0700

    mtd: spi-nor: fsl-quadspi: add i.mx6ul support
    
    Add i.mx6ul chip support
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Acked-by: Han xu <han.xu at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index b567756..a5db7ad 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -208,6 +208,7 @@ enum fsl_qspi_devtype {
 	FSL_QUADSPI_VYBRID,
 	FSL_QUADSPI_IMX6SX,
 	FSL_QUADSPI_IMX7D,
+	FSL_QUADSPI_IMX6UL,
 };
 
 struct fsl_qspi_devtype_data {
@@ -243,6 +244,15 @@ static struct fsl_qspi_devtype_data imx7d_data = {
 		       | QUADSPI_QUIRK_4X_INT_CLK,
 };
 
+static struct fsl_qspi_devtype_data imx6ul_data = {
+	.devtype = FSL_QUADSPI_IMX6UL,
+	.rxfifo = 128,
+	.txfifo = 512,
+	.ahb_buf_size = 1024,
+	.driver_data = QUADSPI_QUIRK_TKT253890
+		       | QUADSPI_QUIRK_4X_INT_CLK,
+};
+
 #define FSL_QSPI_MAX_CHIP	4
 struct fsl_qspi {
 	struct mtd_info mtd[FSL_QSPI_MAX_CHIP];
@@ -705,6 +715,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = {
 	{ .compatible = "fsl,vf610-qspi", .data = (void *)&vybrid_data, },
 	{ .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
 	{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
+	{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: Documentation: fsl-quadspi: Add fsl, imx6ul-qspi compatible string
Message-ID: <E1ZWta3-0005NP-18@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=cb94d0bb41e43b4fdd219ad930686397814bcd8d
Commit:     cb94d0bb41e43b4fdd219ad930686397814bcd8d
Parent:     74a081d14f579d0a1de845ba63e8ee5f0c511258
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:25:52 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:42 2015 -0700

    Documentation: fsl-quadspi: Add fsl, imx6ul-qspi compatible string
    
    new compatible string: "fsl,imx6ul-qspi".
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 Documentation/devicetree/bindings/mtd/fsl-quadspi.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index ca72696..862aa2f 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -2,7 +2,7 @@
 
 Required properties:
   - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi",
-		 "fsl,imx7d-qspi"
+		 "fsl,imx7d-qspi", "fsl,imx6ul-qspi"
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
   - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: fsl-quadspi: i.MX6SX: fixed the random QSPI access
 failed issue
Message-ID: <E1ZWta3-0005Np-4E@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=cacbef40aac478fb25fb7d18ac22d41a11ce06e2
Commit:     cacbef40aac478fb25fb7d18ac22d41a11ce06e2
Parent:     cb94d0bb41e43b4fdd219ad930686397814bcd8d
Author:     Allen Xu <b45815 at freescale.com>
AuthorDate: Tue Aug 4 10:25:58 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:43 2015 -0700

    mtd: spi-nor: fsl-quadspi: i.MX6SX: fixed the random QSPI access failed issue
    
    We found there is a low probability(5%) QSPI access timeout issue,
    usually it happened on kernel boot stage, the first time kernel tried to
    access QSPI chip. The READ_ID command was sent but not executed,
    consequently the probe function failed.
    
    The root cause is that the divider is not glitchless in i.MX6SX chip.
    If qspi clock enabled then change clock frequency by call clk_set_rate,
    there will be glitch at low possiblity rate and pass to qspi controller.
    The controler will be hang by this glitch.
    
    Based on the new clock flag(CLK_SET_RATE_GATE) and new framework, we
    need to change the approach of seting clock rate.
    1. Disable clock.
    2. call clk_set_rate.
    3. Enable clock again.
    
    Signed-off-by: Han Xu <han.xu at freescale.com>
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 81 +++++++++++++++++++++++++++------------
 1 file changed, 56 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index a5db7ad..8a69b2c 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -655,6 +655,32 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
 		q->iobase + QUADSPI_BFGENCR);
 }
 
+/* This function was used to prepare and enable QSPI clock */
+static int fsl_qspi_clk_prep_enable(struct fsl_qspi *q)
+{
+	int ret;
+
+	ret = clk_prepare_enable(q->clk_en);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(q->clk);
+	if (ret) {
+		clk_disable_unprepare(q->clk_en);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* This function was used to disable and unprepare QSPI clock */
+static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
+{
+	clk_disable_unprepare(q->clk);
+	clk_disable_unprepare(q->clk_en);
+
+}
+
 /* We use this function to do some basic init for spi_nor_scan(). */
 static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 {
@@ -662,11 +688,18 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	u32 reg;
 	int ret;
 
-	/* the default frequency, we will change it in the future.*/
+	/* disable and unprepare clock to avoid glitch pass to controller */
+	fsl_qspi_clk_disable_unprep(q);
+
+	/* the default frequency, we will change it in the future. */
 	ret = clk_set_rate(q->clk, 66000000);
 	if (ret)
 		return ret;
 
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret)
+		return ret;
+
 	/* Init the LUT table. */
 	fsl_qspi_init_lut(q);
 
@@ -698,10 +731,17 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q)
 	if (needs_4x_clock(q))
 		rate *= 4;
 
+	/* disable and unprepare clock to avoid glitch pass to controller */
+	fsl_qspi_clk_disable_unprep(q);
+
 	ret = clk_set_rate(q->clk, rate);
 	if (ret)
 		return ret;
 
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret)
+		return ret;
+
 	/* Init the LUT table again. */
 	fsl_qspi_init_lut(q);
 
@@ -844,22 +884,16 @@ static int fsl_qspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
 	int ret;
 
 	mutex_lock(&q->lock);
-	ret = clk_enable(q->clk_en);
-	if (ret)
-		goto err_mutex;
 
-	ret = clk_enable(q->clk);
+	ret = fsl_qspi_clk_prep_enable(q);
 	if (ret)
-		goto err_clk;
+		goto err_mutex;
 
 	fsl_qspi_set_base_addr(q, nor);
 	return 0;
 
-err_clk:
-	clk_disable(q->clk_en);
 err_mutex:
 	mutex_unlock(&q->lock);
-
 	return ret;
 }
 
@@ -867,8 +901,7 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
 {
 	struct fsl_qspi *q = nor->priv;
 
-	clk_disable(q->clk);
-	clk_disable(q->clk_en);
+	fsl_qspi_clk_disable_unprep(q);
 	mutex_unlock(&q->lock);
 }
 
@@ -918,15 +951,9 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	if (IS_ERR(q->clk))
 		return PTR_ERR(q->clk);
 
-	ret = clk_prepare_enable(q->clk_en);
+	ret = fsl_qspi_clk_prep_enable(q);
 	if (ret) {
-		dev_err(dev, "cannot enable the qspi_en clock: %d\n", ret);
-		return ret;
-	}
-
-	ret = clk_prepare_enable(q->clk);
-	if (ret) {
-		dev_err(dev, "cannot enable the qspi clock: %d\n", ret);
+		dev_err(dev, "can not enable the clock\n");
 		goto clk_failed;
 	}
 
@@ -1032,8 +1059,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	if (ret)
 		goto last_init_failed;
 
-	clk_disable(q->clk);
-	clk_disable(q->clk_en);
+	fsl_qspi_clk_disable_unprep(q);
 	return 0;
 
 last_init_failed:
@@ -1046,9 +1072,9 @@ last_init_failed:
 mutex_failed:
 	mutex_destroy(&q->lock);
 irq_failed:
-	clk_disable_unprepare(q->clk);
+	fsl_qspi_clk_disable_unprep(q);
 clk_failed:
-	clk_disable_unprepare(q->clk_en);
+	dev_err(dev, "Freescale QuadSPI probe failed\n");
 	return ret;
 }
 
@@ -1069,8 +1095,6 @@ static int fsl_qspi_remove(struct platform_device *pdev)
 	writel(0x0, q->iobase + QUADSPI_RSER);
 
 	mutex_destroy(&q->lock);
-	clk_unprepare(q->clk);
-	clk_unprepare(q->clk_en);
 
 	if (q->ahb_addr)
 		iounmap(q->ahb_addr);
@@ -1085,12 +1109,19 @@ static int fsl_qspi_suspend(struct platform_device *pdev, pm_message_t state)
 
 static int fsl_qspi_resume(struct platform_device *pdev)
 {
+	int ret;
 	struct fsl_qspi *q = platform_get_drvdata(pdev);
 
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret)
+		return ret;
+
 	fsl_qspi_nor_setup(q);
 	fsl_qspi_set_map_addr(q);
 	fsl_qspi_nor_setup_last(q);
 
+	fsl_qspi_clk_disable_unprep(q);
+
 	return 0;
 }
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: fsl-quadspi: workaround qspi can't wakeup from wait mode
Message-ID: <E1ZWta3-0005OE-7u@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=5cc66cb7345d1bac71e94d7fd05dc86506f59dfe
Commit:     5cc66cb7345d1bac71e94d7fd05dc86506f59dfe
Parent:     cacbef40aac478fb25fb7d18ac22d41a11ce06e2
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:26:04 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:44 2015 -0700

    mtd: spi-nor: fsl-quadspi: workaround qspi can't wakeup from wait mode
    
    QSPI1 cannot wake up CCM from WAIT mode on SX ARD board, add pmqos to
    let PM NOT enter WAIT mode when accessing QSPI1, refer to TKT245618.
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Han Xu <Han.xu at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 8a69b2c..676b363 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
 #include <linux/mutex.h>
+#include <linux/pm_qos.h>
 
 /* Controller needs driver to swap endian */
 #define QUADSPI_QUIRK_SWAP_ENDIAN	(1 << 0)
@@ -37,6 +38,8 @@
  * trigger data transfer even though extern data will not transferred.
  */
 #define QUADSPI_QUIRK_TKT253890		(1 << 2)
+/* Controller cannot wake up from wait mode, TKT245618 */
+#define QUADSPI_QUIRK_TKT245618         (1 << 3)
 
 /* The registers */
 #define QUADSPI_MCR			0x00
@@ -232,7 +235,8 @@ static struct fsl_qspi_devtype_data imx6sx_data = {
 	.rxfifo = 128,
 	.txfifo = 512,
 	.ahb_buf_size = 1024,
-	.driver_data = QUADSPI_QUIRK_4X_INT_CLK,
+	.driver_data = QUADSPI_QUIRK_4X_INT_CLK
+		       | QUADSPI_QUIRK_TKT245618,
 };
 
 static struct fsl_qspi_devtype_data imx7d_data = {
@@ -272,6 +276,7 @@ struct fsl_qspi {
 	unsigned int chip_base_addr; /* We may support two chips. */
 	bool has_second_chip;
 	struct mutex lock;
+	struct pm_qos_request pm_qos_req;
 };
 
 static inline int needs_swap_endian(struct fsl_qspi *q)
@@ -289,6 +294,11 @@ static inline int needs_fill_txfifo(struct fsl_qspi *q)
 	return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT253890;
 }
 
+static inline int needs_wakeup_wait_mode(struct fsl_qspi *q)
+{
+	return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
+}
+
 /*
  * An IC bug makes us to re-arrange the 32-bit data.
  * The following chips, such as IMX6SLX, have fixed this bug.
@@ -670,12 +680,18 @@ static int fsl_qspi_clk_prep_enable(struct fsl_qspi *q)
 		return ret;
 	}
 
+	if (needs_wakeup_wait_mode(q))
+		pm_qos_add_request(&q->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+
 	return 0;
 }
 
 /* This function was used to disable and unprepare QSPI clock */
 static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
 {
+	if (needs_wakeup_wait_mode(q))
+		pm_qos_remove_request(&q->pm_qos_req);
+
 	clk_disable_unprepare(q->clk);
 	clk_disable_unprepare(q->clk_en);
 
@@ -926,6 +942,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 	if (!q->nor_num || q->nor_num > FSL_QSPI_MAX_CHIP)
 		return -ENODEV;
 
+	q->dev = dev;
+	q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
+	platform_set_drvdata(pdev, q);
+
 	/* find the resources */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
 	q->iobase = devm_ioremap_resource(dev, res);
@@ -971,10 +991,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 		goto irq_failed;
 	}
 
-	q->dev = dev;
-	q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
-	platform_set_drvdata(pdev, q);
-
 	ret = fsl_qspi_nor_setup(q);
 	if (ret)
 		goto irq_failed;


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: fsl-quadspi: reset the module in the probe
Message-ID: <E1ZWta3-0005Od-9e@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=8b8319c8b7d0385659c2df6376955cb6a1d918b6
Commit:     8b8319c8b7d0385659c2df6376955cb6a1d918b6
Parent:     5cc66cb7345d1bac71e94d7fd05dc86506f59dfe
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:26:10 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:44 2015 -0700

    mtd: spi-nor: fsl-quadspi: reset the module in the probe
    
    The uboot may run the QuadSpi controler with command:
        #sf probe
    
    So we should reset the module in the probe.
    This patch also clear the pending interrupts which arised by the uboot
    code.
    
    Signed-off-by: Huang Shijie <shijie8 at gmail.com>
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 676b363..0144821 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -716,6 +716,11 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	if (ret)
 		return ret;
 
+	/* Reset the module */
+	writel(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
+		base + QUADSPI_MCR);
+	udelay(1);
+
 	/* Init the LUT table. */
 	fsl_qspi_init_lut(q);
 
@@ -733,6 +738,9 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
 	writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
 			base + QUADSPI_MCR);
 
+	/* clear all interrupt status */
+	writel(0xffffffff, q->iobase + QUADSPI_FR);
+
 	/* enable the interrupt */
 	writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: fsl-quadspi: fix unsupported cmd when run flash_erase
Message-ID: <E1ZWta3-0005P3-Cn@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=788a6cddda9ba83276e37567c17bb78406904074
Commit:     788a6cddda9ba83276e37567c17bb78406904074
Parent:     8b8319c8b7d0385659c2df6376955cb6a1d918b6
Author:     Frank Li <Frank.Li at freescale.com>
AuthorDate: Tue Aug 4 10:26:16 2015 -0500
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 6 10:07:45 2015 -0700

    mtd: spi-nor: fsl-quadspi: fix unsupported cmd when run flash_erase
    
    Erase function will use cmd 0x20 (SPINOR_OP_BE_4K) if kenrel enable option
    CONFIG_MTD_SPI_NOR_USE_4K_SECTORS.
    
    This command is not in fsl-quadspi driver LUT. So driver continue report
    fsl-quadspi 21e0000.qspi: Unsupported cmd 0x20.
    
    This patch fix this issue.
    
    Signed-off-by: Frank Li <Frank.Li at freescale.com>
    Acked-by: Han Xu <Han.xu at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/fsl-quadspi.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 0144821..d32b7e0 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -397,14 +397,8 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
 	/* Erase a sector */
 	lut_base = SEQID_SE * 4;
 
-	if (q->nor_size <= SZ_16M) {
-		cmd = SPINOR_OP_SE;
-		addrlen = ADDR24BIT;
-	} else {
-		/* use the 4-byte address */
-		cmd = SPINOR_OP_SE;
-		addrlen = ADDR32BIT;
-	}
+	cmd = q->nor[0].erase_opcode;
+	addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
 
 	writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
 			base + QUADSPI_LUT(lut_base));
@@ -473,6 +467,8 @@ static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
 	case SPINOR_OP_BRWR:
 		return SEQID_BRWR;
 	default:
+		if (cmd == q->nor[0].erase_opcode)
+			return SEQID_SE;
 		dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd);
 		break;
 	}


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: brcmnand: Fix misuse of IS_ENABLED
Message-ID: <E1ZWta3-0005PV-G4@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=ddb2c42b677eb2883e532f0928e445fc205d0019
Commit:     ddb2c42b677eb2883e532f0928e445fc205d0019
Parent:     788a6cddda9ba83276e37567c17bb78406904074
Author:     Axel Lin <axel.lin at ingics.com>
AuthorDate: Thu Aug 6 12:29:37 2015 +0800
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 7 16:17:43 2015 -0700

    mtd: brcmnand: Fix misuse of IS_ENABLED
    
    While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
    for other symbols such as __BIG_ENDIAN that is provided directly by
    the compiler.
    
    Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.
    
    Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
    Signed-off-by: Axel Lin <axel.lin at ingics.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/brcmnand/brcmnand.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/brcmnand/brcmnand.h b/drivers/mtd/nand/brcmnand/brcmnand.h
index a20c736..169f99e 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/brcmnand/brcmnand.h
@@ -50,7 +50,7 @@ static inline u32 brcmnand_readl(void __iomem *addr)
 	 * Other architectures (e.g., ARM) either do not support big endian, or
 	 * else leave I/O in little endian mode.
 	 */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		return __raw_readl(addr);
 	else
 		return readl_relaxed(addr);
@@ -59,7 +59,7 @@ static inline u32 brcmnand_readl(void __iomem *addr)
 static inline void brcmnand_writel(u32 val, void __iomem *addr)
 {
 	/* See brcmnand_readl() comments */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		__raw_writel(val, addr);
 	else
 		writel_relaxed(val, addr);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: nand: pxa3xx: Increase initial buffer size
Message-ID: <E1ZWta3-0005Pu-JJ@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=c16340973fcb6461474a9f811f7f3ff2f946b24c
Commit:     c16340973fcb6461474a9f811f7f3ff2f946b24c
Parent:     ddb2c42b677eb2883e532f0928e445fc205d0019
Author:     Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
AuthorDate: Mon Aug 3 11:31:26 2015 -0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 14 11:22:54 2015 -0700

    nand: pxa3xx: Increase initial buffer size
    
    The initial buffer is used for the initial commands used to detect
    a flash device (STATUS, READID and PARAM).
    
    ONFI param page is 256 bytes, and there are three redundant copies
    to be read. JEDEC param page is 512 bytes, and there are also three
    redundant copies to be read. Hence this buffer should be at least
    512 x 3. This commits rounds the buffer size to 2048.
    
    Signed-off-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 1259cc5..9d973cd 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -45,10 +45,13 @@
 
 /*
  * Define a buffer size for the initial command that detects the flash device:
- * STATUS, READID and PARAM. The largest of these is the PARAM command,
- * needing 256 bytes.
+ * STATUS, READID and PARAM.
+ * ONFI param page is 256 bytes, and there are three redundant copies
+ * to be read. JEDEC param page is 512 bytes, and there are also three
+ * redundant copies to be read.
+ * Hence this buffer should be at least 512 x 3. Let's pick 2048.
  */
-#define INIT_BUFFER_SIZE	256
+#define INIT_BUFFER_SIZE	2048
 
 /* registers and bit definitions */
 #define NDCR		(0x00) /* Control register */
@@ -899,14 +902,14 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 		break;
 
 	case NAND_CMD_PARAM:
-		info->buf_count = 256;
+		info->buf_count = INIT_BUFFER_SIZE;
 		info->ndcb0 |= NDCB0_CMD_TYPE(0)
 				| NDCB0_ADDR_CYC(1)
 				| NDCB0_LEN_OVRD
 				| command;
 		info->ndcb1 = (column & 0xFF);
-		info->ndcb3 = 256;
-		info->data_size = 256;
+		info->ndcb3 = INIT_BUFFER_SIZE;
+		info->data_size = INIT_BUFFER_SIZE;
 		break;
 
 	case NAND_CMD_READID:


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: doc: dt: add documentation for nxp,lpc1773-spifi
Message-ID: <E1ZWta3-0005QX-La@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=89f271c4d052063a72af2622f285f70caac91845
Commit:     89f271c4d052063a72af2622f285f70caac91845
Parent:     c16340973fcb6461474a9f811f7f3ff2f946b24c
Author:     Joachim Eastwood <manabian at gmail.com>
AuthorDate: Thu Jul 9 22:19:07 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 14 11:22:54 2015 -0700

    doc: dt: add documentation for nxp,lpc1773-spifi
    
    Add device tree binding documentation for the SPI Flash Interface
    (SPIFI) found on NXP LPC18xx and LPC43xx devies.
    
    Signed-off-by: Joachim Eastwood <manabian at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 .../devicetree/bindings/mtd/nxp-spifi.txt          | 58 ++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/nxp-spifi.txt b/Documentation/devicetree/bindings/mtd/nxp-spifi.txt
new file mode 100644
index 0000000..f8b6b25
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/nxp-spifi.txt
@@ -0,0 +1,58 @@
+* NXP SPI Flash Interface (SPIFI)
+
+NXP SPIFI is a specialized SPI interface for serial Flash devices.
+It supports one Flash device with 1-, 2- and 4-bits width in SPI
+mode 0 or 3. The controller operates in either command or memory
+mode. In memory mode the Flash is accessible from the CPU as
+normal memory.
+
+Required properties:
+  - compatible : Should be "nxp,lpc1773-spifi"
+  - reg : the first contains the register location and length,
+          the second contains the memory mapping address and length
+  - reg-names: Should contain the reg names "spifi" and "flash"
+  - interrupts : Should contain the interrupt for the device
+  - clocks : The clocks needed by the SPIFI controller
+  - clock-names : Should contain the clock names "spifi" and "reg"
+
+Optional properties:
+ - resets : phandle + reset specifier
+
+The SPI Flash must be a child of the SPIFI node and must have a
+compatible property as specified in bindings/mtd/jedec,spi-nor.txt
+
+Optionally it can also contain the following properties.
+ - spi-cpol : Controller only supports mode 0 and 3 so either
+              both spi-cpol and spi-cpha should be present or
+              none of them
+ - spi-cpha : See above
+ - spi-rx-bus-width : Used to select how many pins that are used
+                      for input on the controller
+
+See bindings/spi/spi-bus.txt for more information.
+
+Example:
+spifi: spifi at 40003000 {
+	compatible = "nxp,lpc1773-spifi";
+	reg = <0x40003000 0x1000>, <0x14000000 0x4000000>;
+	reg-names = "spifi", "flash";
+	interrupts = <30>;
+	clocks = <&ccu1 CLK_SPIFI>, <&ccu1 CLK_CPU_SPIFI>;
+	clock-names = "spifi", "reg";
+	resets = <&rgu 53>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		spi-cpol;
+		spi-cpha;
+		spi-rx-bus-width = <4>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 0 {
+			label = "data";
+			reg = <0 0x200000>;
+		};
+	};
+};
+


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: add driver for NXP SPI Flash Interface (SPIFI)
Message-ID: <E1ZWta3-0005R6-Os@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=f617b9587c1662a2352b90cb64ad8bcf0ff4d0af
Commit:     f617b9587c1662a2352b90cb64ad8bcf0ff4d0af
Parent:     89f271c4d052063a72af2622f285f70caac91845
Author:     Joachim Eastwood <manabian at gmail.com>
AuthorDate: Thu Aug 13 19:19:40 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 14 11:22:55 2015 -0700

    mtd: spi-nor: add driver for NXP SPI Flash Interface (SPIFI)
    
    Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
    controller that is found on newer NXP MCU devices.
    
    The controller supports serial SPI Flash devices with 1-, 2-
    and 4-bit width in either SPI mode 0 or 3. The controller
    can operate in either command or memory mode. In memory mode
    the Flash is exposed as normal memory and can be directly
    accessed by the CPU.
    
    Signed-off-by: Joachim Eastwood <manabian at gmail.com>
    Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/Kconfig     |  11 +
 drivers/mtd/spi-nor/Makefile    |   1 +
 drivers/mtd/spi-nor/nxp-spifi.c | 482 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 494 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 64a4f0e..407142e 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -28,4 +28,15 @@ config SPI_FSL_QUADSPI
 	  This enables support for the Quad SPI controller in master mode.
 	  We only connect the NOR to this controller now.
 
+config SPI_NXP_SPIFI
+	tristate "NXP SPI Flash Interface (SPIFI)"
+	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
+	depends on HAS_IOMEM
+	help
+	  Enable support for the NXP LPC SPI Flash Interface controller.
+
+	  SPIFI is a specialized controller for connecting serial SPI
+	  Flash. Enable this option if you have a device with a SPIFI
+	  controller and want to access the Flash as a mtd device.
+
 endif # MTD_SPI_NOR
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 6a7ce14..e53333e 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
+obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
new file mode 100644
index 0000000..9ad1dd0
--- /dev/null
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -0,0 +1,482 @@
+/*
+ * SPI-NOR driver for NXP SPI Flash Interface (SPIFI)
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian at gmail.com>
+ *
+ * Based on Freescale QuadSPI driver:
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+/* NXP SPIFI registers, bits and macros */
+#define SPIFI_CTRL				0x000
+#define  SPIFI_CTRL_TIMEOUT(timeout)		(timeout)
+#define  SPIFI_CTRL_CSHIGH(cshigh)		((cshigh) << 16)
+#define  SPIFI_CTRL_MODE3			BIT(23)
+#define  SPIFI_CTRL_DUAL			BIT(28)
+#define  SPIFI_CTRL_FBCLK			BIT(30)
+#define SPIFI_CMD				0x004
+#define  SPIFI_CMD_DATALEN(dlen)		((dlen) & 0x3fff)
+#define  SPIFI_CMD_DOUT				BIT(15)
+#define  SPIFI_CMD_INTLEN(ilen)			((ilen) << 16)
+#define  SPIFI_CMD_FIELDFORM(field)		((field) << 19)
+#define  SPIFI_CMD_FIELDFORM_ALL_SERIAL		SPIFI_CMD_FIELDFORM(0x0)
+#define  SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA	SPIFI_CMD_FIELDFORM(0x1)
+#define  SPIFI_CMD_FRAMEFORM(frame)		((frame) << 21)
+#define  SPIFI_CMD_FRAMEFORM_OPCODE_ONLY	SPIFI_CMD_FRAMEFORM(0x1)
+#define  SPIFI_CMD_OPCODE(op)			((op) << 24)
+#define SPIFI_ADDR				0x008
+#define SPIFI_IDATA				0x00c
+#define SPIFI_CLIMIT				0x010
+#define SPIFI_DATA				0x014
+#define SPIFI_MCMD				0x018
+#define SPIFI_STAT				0x01c
+#define  SPIFI_STAT_MCINIT			BIT(0)
+#define  SPIFI_STAT_CMD				BIT(1)
+#define  SPIFI_STAT_RESET			BIT(4)
+
+#define SPI_NOR_MAX_ID_LEN	6
+
+struct nxp_spifi {
+	struct device *dev;
+	struct clk *clk_spifi;
+	struct clk *clk_reg;
+	void __iomem *io_base;
+	void __iomem *flash_base;
+	struct mtd_info mtd;
+	struct spi_nor nor;
+	bool memory_mode;
+	u32 mcmd;
+};
+
+static int nxp_spifi_wait_for_cmd(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 !(stat & SPIFI_STAT_CMD), 10, 30);
+	if (ret)
+		dev_warn(spifi->dev, "command timed out\n");
+
+	return ret;
+}
+
+static int nxp_spifi_reset(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	writel(SPIFI_STAT_RESET, spifi->io_base + SPIFI_STAT);
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 !(stat & SPIFI_STAT_RESET), 10, 30);
+	if (ret)
+		dev_warn(spifi->dev, "state reset timed out\n");
+
+	return ret;
+}
+
+static int nxp_spifi_set_memory_mode_off(struct nxp_spifi *spifi)
+{
+	int ret;
+
+	if (!spifi->memory_mode)
+		return 0;
+
+	ret = nxp_spifi_reset(spifi);
+	if (ret)
+		dev_err(spifi->dev, "unable to enter command mode\n");
+	else
+		spifi->memory_mode = false;
+
+	return ret;
+}
+
+static int nxp_spifi_set_memory_mode_on(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	if (spifi->memory_mode)
+		return 0;
+
+	writel(spifi->mcmd, spifi->io_base + SPIFI_MCMD);
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 stat & SPIFI_STAT_MCINIT, 10, 30);
+	if (ret)
+		dev_err(spifi->dev, "unable to enter memory mode\n");
+	else
+		spifi->memory_mode = true;
+
+	return ret;
+}
+
+static int nxp_spifi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	cmd = SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_OPCODE(opcode) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		*buf++ = readb(spifi->io_base + SPIFI_DATA);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+			       int len, int write_enable)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	cmd = SPIFI_CMD_DOUT |
+	      SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_OPCODE(opcode) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		writeb(*buf++, spifi->io_base + SPIFI_DATA);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_read(struct spi_nor *nor, loff_t from, size_t len,
+			  size_t *retlen, u_char *buf)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_on(spifi);
+	if (ret)
+		return ret;
+
+	memcpy_fromio(buf, spifi->flash_base + from, len);
+	*retlen += len;
+
+	return 0;
+}
+
+static void nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len,
+			    size_t *retlen, const u_char *buf)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return;
+
+	writel(to, spifi->io_base + SPIFI_ADDR);
+	*retlen += len;
+
+	cmd = SPIFI_CMD_DOUT |
+	      SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_OPCODE(nor->program_opcode) |
+	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		writeb(*buf++, spifi->io_base + SPIFI_DATA);
+
+	nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	writel(offs, spifi->io_base + SPIFI_ADDR);
+
+	cmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_OPCODE(nor->erase_opcode) |
+	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi)
+{
+	switch (spifi->nor.flash_read) {
+	case SPI_NOR_NORMAL:
+	case SPI_NOR_FAST:
+		spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL;
+		break;
+	case SPI_NOR_DUAL:
+	case SPI_NOR_QUAD:
+		spifi->mcmd = SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA;
+		break;
+	default:
+		dev_err(spifi->dev, "unsupported SPI read mode\n");
+		return -EINVAL;
+	}
+
+	/* Memory mode supports address length between 1 and 4 */
+	if (spifi->nor.addr_width < 1 || spifi->nor.addr_width > 4)
+		return -EINVAL;
+
+	spifi->mcmd |= SPIFI_CMD_OPCODE(spifi->nor.read_opcode) |
+		       SPIFI_CMD_INTLEN(spifi->nor.read_dummy / 8) |
+		       SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+
+	return 0;
+}
+
+static void nxp_spifi_dummy_id_read(struct spi_nor *nor)
+{
+	u8 id[SPI_NOR_MAX_ID_LEN];
+	nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+}
+
+static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
+				 struct device_node *np)
+{
+	struct mtd_part_parser_data ppdata;
+	enum read_mode flash_read;
+	u32 ctrl, property;
+	u16 mode = 0;
+	int ret;
+
+	if (!of_property_read_u32(np, "spi-rx-bus-width", &property)) {
+		switch (property) {
+		case 1:
+			break;
+		case 2:
+			mode |= SPI_RX_DUAL;
+			break;
+		case 4:
+			mode |= SPI_RX_QUAD;
+			break;
+		default:
+			dev_err(spifi->dev, "unsupported rx-bus-width\n");
+			return -EINVAL;
+		}
+	}
+
+	if (of_find_property(np, "spi-cpha", NULL))
+		mode |= SPI_CPHA;
+
+	if (of_find_property(np, "spi-cpol", NULL))
+		mode |= SPI_CPOL;
+
+	/* Setup control register defaults */
+	ctrl = SPIFI_CTRL_TIMEOUT(1000) |
+	       SPIFI_CTRL_CSHIGH(15) |
+	       SPIFI_CTRL_FBCLK;
+
+	if (mode & SPI_RX_DUAL) {
+		ctrl |= SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_DUAL;
+	} else if (mode & SPI_RX_QUAD) {
+		ctrl &= ~SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_QUAD;
+	} else {
+		ctrl |= SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_NORMAL;
+	}
+
+	switch (mode & (SPI_CPHA | SPI_CPOL)) {
+	case SPI_MODE_0:
+		ctrl &= ~SPIFI_CTRL_MODE3;
+		break;
+	case SPI_MODE_3:
+		ctrl |= SPIFI_CTRL_MODE3;
+		break;
+	default:
+		dev_err(spifi->dev, "only mode 0 and 3 supported\n");
+		return -EINVAL;
+	}
+
+	writel(ctrl, spifi->io_base + SPIFI_CTRL);
+
+	spifi->mtd.priv  = &spifi->nor;
+	spifi->nor.mtd   = &spifi->mtd;
+	spifi->nor.dev   = spifi->dev;
+	spifi->nor.priv  = spifi;
+	spifi->nor.read  = nxp_spifi_read;
+	spifi->nor.write = nxp_spifi_write;
+	spifi->nor.erase = nxp_spifi_erase;
+	spifi->nor.read_reg  = nxp_spifi_read_reg;
+	spifi->nor.write_reg = nxp_spifi_write_reg;
+
+	/*
+	 * The first read on a hard reset isn't reliable so do a
+	 * dummy read of the id before calling spi_nor_scan().
+	 * The reason for this problem is unknown.
+	 *
+	 * The official NXP spifilib uses more or less the same
+	 * workaround that is applied here by reading the device
+	 * id multiple times.
+	 */
+	nxp_spifi_dummy_id_read(&spifi->nor);
+
+	ret = spi_nor_scan(&spifi->nor, NULL, flash_read);
+	if (ret) {
+		dev_err(spifi->dev, "device scan failed\n");
+		return ret;
+	}
+
+	ret = nxp_spifi_setup_memory_cmd(spifi);
+	if (ret) {
+		dev_err(spifi->dev, "memory command setup failed\n");
+		return ret;
+	}
+
+	ppdata.of_node = np;
+	ret = mtd_device_parse_register(&spifi->mtd, NULL, &ppdata, NULL, 0);
+	if (ret) {
+		dev_err(spifi->dev, "mtd device parse failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int nxp_spifi_probe(struct platform_device *pdev)
+{
+	struct device_node *flash_np;
+	struct nxp_spifi *spifi;
+	struct resource *res;
+	int ret;
+
+	spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL);
+	if (!spifi)
+		return -ENOMEM;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spifi");
+	spifi->io_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spifi->io_base))
+		return PTR_ERR(spifi->io_base);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash");
+	spifi->flash_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spifi->flash_base))
+		return PTR_ERR(spifi->flash_base);
+
+	spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi");
+	if (IS_ERR(spifi->clk_spifi)) {
+		dev_err(&pdev->dev, "spifi clock not found\n");
+		return PTR_ERR(spifi->clk_spifi);
+	}
+
+	spifi->clk_reg = devm_clk_get(&pdev->dev, "reg");
+	if (IS_ERR(spifi->clk_reg)) {
+		dev_err(&pdev->dev, "reg clock not found\n");
+		return PTR_ERR(spifi->clk_reg);
+	}
+
+	ret = clk_prepare_enable(spifi->clk_reg);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable reg clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(spifi->clk_spifi);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable spifi clock\n");
+		goto dis_clk_reg;
+	}
+
+	spifi->dev = &pdev->dev;
+	platform_set_drvdata(pdev, spifi);
+
+	/* Initialize and reset device */
+	nxp_spifi_reset(spifi);
+	writel(0, spifi->io_base + SPIFI_IDATA);
+	writel(0, spifi->io_base + SPIFI_MCMD);
+	nxp_spifi_reset(spifi);
+
+	flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
+	if (!flash_np) {
+		dev_err(&pdev->dev, "no SPI flash device to configure\n");
+		ret = -ENODEV;
+		goto dis_clks;
+	}
+
+	ret = nxp_spifi_setup_flash(spifi, flash_np);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to setup flash chip\n");
+		goto dis_clks;
+	}
+
+	return 0;
+
+dis_clks:
+	clk_disable_unprepare(spifi->clk_spifi);
+dis_clk_reg:
+	clk_disable_unprepare(spifi->clk_reg);
+	return ret;
+}
+
+static int nxp_spifi_remove(struct platform_device *pdev)
+{
+	struct nxp_spifi *spifi = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(&spifi->mtd);
+	clk_disable_unprepare(spifi->clk_spifi);
+	clk_disable_unprepare(spifi->clk_reg);
+
+	return 0;
+}
+
+static const struct of_device_id nxp_spifi_match[] = {
+	{.compatible = "nxp,lpc1773-spifi"},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, nxp_spifi_match);
+
+static struct platform_driver nxp_spifi_driver = {
+	.probe	= nxp_spifi_probe,
+	.remove	= nxp_spifi_remove,
+	.driver	= {
+		.name = "nxp-spifi",
+		.of_match_table = nxp_spifi_match,
+	},
+};
+module_platform_driver(nxp_spifi_driver);
+
+MODULE_DESCRIPTION("NXP SPI Flash Interface driver");
+MODULE_AUTHOR("Joachim Eastwood <manabian at gmail.com>");
+MODULE_LICENSE("GPL v2");


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:03 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:03 +0000
Subject: mtd: spi-nor: Improve Kconfig help text for SPI_FSL_QUADSPI
Message-ID: <E1ZWta3-0005RW-Sn@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=842c12ddb49ef271ff978cbd022777d3d2c7787f
Commit:     842c12ddb49ef271ff978cbd022777d3d2c7787f
Parent:     f617b9587c1662a2352b90cb64ad8bcf0ff4d0af
Author:     Fabio Estevam <fabio.estevam at freescale.com>
AuthorDate: Thu Aug 13 14:02:05 2015 -0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 14 11:22:56 2015 -0700

    mtd: spi-nor: Improve Kconfig help text for SPI_FSL_QUADSPI
    
    The current "We only connect the NOR to this controller now." text
    is not very clear, so explain it better by saying that generic SPI
    is not supported by SPI_FSL_QUADSPI and only SPI NOR is.
    
    Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 407142e..89bf4c1 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -26,7 +26,8 @@ config SPI_FSL_QUADSPI
 	depends on ARCH_MXC
 	help
 	  This enables support for the Quad SPI controller in master mode.
-	  We only connect the NOR to this controller now.
+	  This controller does not support generic SPI. It only supports
+	  SPI NOR.
 
 config SPI_NXP_SPIFI
 	tristate "NXP SPI Flash Interface (SPIFI)"


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: spi-nor: add Spansion S25FL204K support
Message-ID: <E1ZWta4-0005Ry-1I@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=b4d97f022ac07c26d8f41f105b6c9c9a699875a2
Commit:     b4d97f022ac07c26d8f41f105b6c9c9a699875a2
Parent:     842c12ddb49ef271ff978cbd022777d3d2c7787f
Author:     Antony Pavlov <antonynpavlov at gmail.com>
AuthorDate: Tue Jun 16 11:37:04 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 14 11:22:56 2015 -0700

    mtd: spi-nor: add Spansion S25FL204K support
    
    Spansion S25FL204K is a 4-Mbit 3.0V Serial Flash Memory
    with Uniform 4 kB Sectors.
    
    Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
    Acked-by: Rafa? Mi?ecki <zajec5 at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 47516d3..47df4b5 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -626,6 +626,7 @@ static const struct spi_device_id spi_nor_ids[] = {
 	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
 	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
 	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
+	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SECT_4K) },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
 	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: denali: hide core part from user in Kconfig
Message-ID: <E1ZWta4-0005SN-3w@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=04868a67ed582e845bf14a5a7789f8bdb3faadd3
Commit:     04868a67ed582e845bf14a5a7789f8bdb3faadd3
Parent:     b4d97f022ac07c26d8f41f105b6c9c9a699875a2
Author:     Andy Shevchenko <andriy.shevchenko at linux.intel.com>
AuthorDate: Thu Aug 6 16:04:21 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:21:35 2015 -0700

    mtd: denali: hide core part from user in Kconfig
    
    There is no need to user to see the core part of the driver.
    
    Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/Kconfig | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 5b2806a..3324281 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -42,23 +42,20 @@ config MTD_SM_COMMON
 	default n
 
 config MTD_NAND_DENALI
-        tristate "Support Denali NAND controller"
-        depends on HAS_DMA
-        help
-	  Enable support for the Denali NAND controller.  This should be
-	  combined with either the PCI or platform drivers to provide device
-	  registration.
+	tristate
 
 config MTD_NAND_DENALI_PCI
         tristate "Support Denali NAND controller on Intel Moorestown"
-	depends on PCI && MTD_NAND_DENALI
+	select MTD_NAND_DENALI
+	depends on HAS_DMA && PCI
         help
           Enable the driver for NAND flash on Intel Moorestown, using the
           Denali NAND controller core.
 
 config MTD_NAND_DENALI_DT
 	tristate "Support Denali NAND controller as a DT device"
-	depends on HAVE_CLK && MTD_NAND_DENALI
+	select MTD_NAND_DENALI
+	depends on HAS_DMA && HAVE_CLK
 	help
 	  Enable the driver for NAND flash on platforms using a Denali NAND
 	  controller as a DT device.


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: denali_pci: use module_pci_driver() macro
Message-ID: <E1ZWta4-0005Sm-5v@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=2445d33d852320d4ce700b2428d60991f8cf478f
Commit:     2445d33d852320d4ce700b2428d60991f8cf478f
Parent:     04868a67ed582e845bf14a5a7789f8bdb3faadd3
Author:     Andy Shevchenko <andriy.shevchenko at linux.intel.com>
AuthorDate: Thu Aug 6 16:04:22 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:21:36 2015 -0700

    mtd: denali_pci: use module_pci_driver() macro
    
    Let's use module_pci_driver() macro to reduce code base of the driver.
    
    There is no functional change.
    
    Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/denali_pci.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
index 6e2f387..29e5d0c 100644
--- a/drivers/mtd/nand/denali_pci.c
+++ b/drivers/mtd/nand/denali_pci.c
@@ -129,14 +129,4 @@ static struct pci_driver denali_pci_driver = {
 	.remove = denali_pci_remove,
 };
 
-static int denali_init_pci(void)
-{
-	return pci_register_driver(&denali_pci_driver);
-}
-module_init(denali_init_pci);
-
-static void denali_exit_pci(void)
-{
-	pci_unregister_driver(&denali_pci_driver);
-}
-module_exit(denali_exit_pci);
+module_pci_driver(denali_pci_driver);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: denali_pci: refactor driver using devres API
Message-ID: <E1ZWta4-0005TI-EE@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=add243d5bc371eef66f81c9da4fd4b55a18dad23
Commit:     add243d5bc371eef66f81c9da4fd4b55a18dad23
Parent:     2445d33d852320d4ce700b2428d60991f8cf478f
Author:     Andy Shevchenko <andriy.shevchenko at linux.intel.com>
AuthorDate: Thu Aug 6 16:04:23 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:21:36 2015 -0700

    mtd: denali_pci: refactor driver using devres API
    
    In recent kernels we have a lot of helper functions, including
    devres API, to make life of device driver developer easy.
    
    Convert the driver using devm_kzalloc() and pcim_enable_device().
    
    Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/denali_pci.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
index 29e5d0c..ad16e2e 100644
--- a/drivers/mtd/nand/denali_pci.c
+++ b/drivers/mtd/nand/denali_pci.c
@@ -30,19 +30,19 @@ MODULE_DEVICE_TABLE(pci, denali_pci_ids);
 
 static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	int ret = -ENODEV;
+	int ret;
 	resource_size_t csr_base, mem_base;
 	unsigned long csr_len, mem_len;
 	struct denali_nand_info *denali;
 
-	denali = kzalloc(sizeof(*denali), GFP_KERNEL);
+	denali = devm_kzalloc(&dev->dev, sizeof(*denali), GFP_KERNEL);
 	if (!denali)
 		return -ENOMEM;
 
-	ret = pci_enable_device(dev);
+	ret = pcim_enable_device(dev);
 	if (ret) {
 		pr_err("Spectra: pci_enable_device failed.\n");
-		goto failed_alloc_memery;
+		return ret;
 	}
 
 	if (id->driver_data == INTEL_CE4100) {
@@ -70,14 +70,13 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	ret = pci_request_regions(dev, DENALI_NAND_NAME);
 	if (ret) {
 		pr_err("Spectra: Unable to request memory regions\n");
-		goto failed_enable_dev;
+		return ret;
 	}
 
 	denali->flash_reg = ioremap_nocache(csr_base, csr_len);
 	if (!denali->flash_reg) {
 		pr_err("Spectra: Unable to remap memory region\n");
-		ret = -ENOMEM;
-		goto failed_req_regions;
+		return -ENOMEM;
 	}
 
 	denali->flash_mem = ioremap_nocache(mem_base, mem_len);
@@ -99,13 +98,6 @@ failed_remap_mem:
 	iounmap(denali->flash_mem);
 failed_remap_reg:
 	iounmap(denali->flash_reg);
-failed_req_regions:
-	pci_release_regions(dev);
-failed_enable_dev:
-	pci_disable_device(dev);
-failed_alloc_memery:
-	kfree(denali);
-
 	return ret;
 }
 
@@ -117,9 +109,6 @@ static void denali_pci_remove(struct pci_dev *dev)
 	denali_remove(denali);
 	iounmap(denali->flash_reg);
 	iounmap(denali->flash_mem);
-	pci_release_regions(dev);
-	pci_disable_device(dev);
-	kfree(denali);
 }
 
 static struct pci_driver denali_pci_driver = {


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: denali_pci: switch to dev_err()
Message-ID: <E1ZWta4-0005Tj-GL@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=af83a67cad1452d48ecd77792f9218f26c445650
Commit:     af83a67cad1452d48ecd77792f9218f26c445650
Parent:     add243d5bc371eef66f81c9da4fd4b55a18dad23
Author:     Andy Shevchenko <andriy.shevchenko at linux.intel.com>
AuthorDate: Thu Aug 6 16:04:24 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:21:37 2015 -0700

    mtd: denali_pci: switch to dev_err()
    
    It is better to have device name prefixed the actual error message.
    
    Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/denali_pci.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
index ad16e2e..de31514 100644
--- a/drivers/mtd/nand/denali_pci.c
+++ b/drivers/mtd/nand/denali_pci.c
@@ -41,7 +41,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
 	ret = pcim_enable_device(dev);
 	if (ret) {
-		pr_err("Spectra: pci_enable_device failed.\n");
+		dev_err(&dev->dev, "Spectra: pci_enable_device failed.\n");
 		return ret;
 	}
 
@@ -69,19 +69,19 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
 	ret = pci_request_regions(dev, DENALI_NAND_NAME);
 	if (ret) {
-		pr_err("Spectra: Unable to request memory regions\n");
+		dev_err(&dev->dev, "Spectra: Unable to request memory regions\n");
 		return ret;
 	}
 
 	denali->flash_reg = ioremap_nocache(csr_base, csr_len);
 	if (!denali->flash_reg) {
-		pr_err("Spectra: Unable to remap memory region\n");
+		dev_err(&dev->dev, "Spectra: Unable to remap memory region\n");
 		return -ENOMEM;
 	}
 
 	denali->flash_mem = ioremap_nocache(mem_base, mem_len);
 	if (!denali->flash_mem) {
-		pr_err("Spectra: ioremap_nocache failed!");
+		dev_err(&dev->dev, "Spectra: ioremap_nocache failed!");
 		ret = -ENOMEM;
 		goto failed_remap_reg;
 	}


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: nettel: do not ignore mtd_device_register() failure in
 nettel_init()
Message-ID: <E1ZWta4-0005UD-Jo@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=11c7e0e2f91fdfdf9f7b4d107bc93d6c298c95fe
Commit:     11c7e0e2f91fdfdf9f7b4d107bc93d6c298c95fe
Parent:     af83a67cad1452d48ecd77792f9218f26c445650
Author:     Alexey Khoroshilov <khoroshilov at ispras.ru>
AuthorDate: Fri Aug 14 01:37:47 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:33:34 2015 -0700

    mtd: nettel: do not ignore mtd_device_register() failure in nettel_init()
    
    If mtd_device_register() fails in nettel_init(), iomap left mapped.
    
    The patch adds failure handling for mtd_device_register().
    
    Found by Linux Driver Verification project (linuxtesting.org).
    
    Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/maps/nettel.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index eadcfff..a577ef8 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -385,20 +385,28 @@ static int __init nettel_init(void)
 	}
 	rc = mtd_device_register(intel_mtd, nettel_intel_partitions,
 				 num_intel_partitions);
+	if (rc)
+		goto out_map_destroy;
 #endif
 
 	if (amd_mtd) {
 		rc = mtd_device_register(amd_mtd, nettel_amd_partitions,
 					 num_amd_partitions);
+		if (rc)
+			goto out_mtd_unreg;
 	}
 
 #ifdef CONFIG_MTD_CFI_INTELEXT
 	register_reboot_notifier(&nettel_notifier_block);
 #endif
 
-	return(rc);
+	return rc;
 
+out_mtd_unreg:
 #ifdef CONFIG_MTD_CFI_INTELEXT
+	mtd_device_unregister(intel_mtd);
+out_map_destroy:
+	map_destroy(intel_mtd);
 out_unmap1:
 	iounmap(nettel_intel_map.virt);
 #endif
@@ -407,8 +415,7 @@ out_unmap2:
 	iounmap(nettel_mmcrp);
 	iounmap(nettel_amd_map.virt);
 
-	return(rc);
-
+	return rc;
 }
 
 /****************************************************************************/


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: physmap_of: fix null pointer deference when kzalloc returns null
Message-ID: <E1ZWta4-0005Uh-Ma@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=7e0c19c9608483808e6b5c294e357fa456f058e1
Commit:     7e0c19c9608483808e6b5c294e357fa456f058e1
Parent:     11c7e0e2f91fdfdf9f7b4d107bc93d6c298c95fe
Author:     Colin Ian King <colin.king at canonical.com>
AuthorDate: Fri Jul 17 11:37:52 2015 +0100
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:57:19 2015 -0700

    mtd: physmap_of: fix null pointer deference when kzalloc returns null
    
    static analysis by smatch caught the following error:
    
    drivers/mtd/maps/physmap_of.c:135 of_get_probes()
       error: potential null dereference 'res'.  (kzalloc returns null)
    
    Check for failed kzalloc and return -ENOMEM in of_flash_probe if
    this occurs.
    
    Signed-off-by: Colin Ian King <colin.king at canonical.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/maps/physmap_of.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 774b32f..3e614e9 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -130,6 +130,8 @@ static const char * const *of_get_probes(struct device_node *dp)
 			count++;
 
 	res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
+	if (!res)
+		return NULL;
 	count = 0;
 	while (cplen > 0) {
 		res[count] = cp;
@@ -311,6 +313,10 @@ static int of_flash_probe(struct platform_device *dev)
 
 	ppdata.of_node = dp;
 	part_probe_types = of_get_probes(dp);
+	if (!part_probe_types) {
+		err = -ENOMEM;
+		goto err_out;
+	}
 	mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
 			NULL, 0);
 	of_free_probes(part_probe_types);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: omap_elm: Fix module alias
Message-ID: <E1ZWta4-0005V9-Q5@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0f0aca5d50ced8d8c18c7982a6b6332182b70e33
Commit:     0f0aca5d50ced8d8c18c7982a6b6332182b70e33
Parent:     7e0c19c9608483808e6b5c294e357fa456f058e1
Author:     Axel Lin <axel.lin at ingics.com>
AuthorDate: Tue Aug 18 21:03:13 2015 +0800
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 17:57:46 2015 -0700

    mtd: omap_elm: Fix module alias
    
    Remove extra space after the "platform:" prefix and make the alias matches
    driver name.
    
    Signed-off-by: Axel Lin <axel.lin at ingics.com>
    Acked-by: Roger Quadros <rogerq at ti.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/omap_elm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c
index 376bfe1..235ec79 100644
--- a/drivers/mtd/nand/omap_elm.c
+++ b/drivers/mtd/nand/omap_elm.c
@@ -574,5 +574,5 @@ module_platform_driver(elm_driver);
 
 MODULE_DESCRIPTION("ELM driver for BCH error correction");
 MODULE_AUTHOR("Texas Instruments");
-MODULE_ALIAS("platform: elm");
+MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_LICENSE("GPL v2");


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:04 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:04 +0000
Subject: mtd: pxa3xx_nand: add a default chunk size
Message-ID: <E1ZWta4-0005VX-SW@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=bc3e00f04cc1fe033a289c2fc2e5c73c0168d360
Commit:     bc3e00f04cc1fe033a289c2fc2e5c73c0168d360
Parent:     0f0aca5d50ced8d8c18c7982a6b6332182b70e33
Author:     Antoine T?nart <antoine.tenart at free-electrons.com>
AuthorDate: Tue Aug 18 10:59:10 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 18 18:03:54 2015 -0700

    mtd: pxa3xx_nand: add a default chunk size
    
    When keeping the configuration set by the bootloader (by using
    the marvell,nand-keep-config property), the pxa3xx_nand_detect_config()
    function is called and set the chunk size to 512 as a default value if
    NDCR_PAGE_SZ is not set.
    
    In the other case, when not keeping the bootloader configuration, no
    chunk size is set. Fix this by adding a default chunk size of 512.
    
    Fixes: 70ed85232a93 ("mtd: nand: pxa3xx: Introduce multiple page I/O
    support")
    
    Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
    Acked-by: Robert Jarzmik <robert.jarzmik at free>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 9d973cd..baf3246 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1476,6 +1476,9 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
 	if (pdata->keep_config && !pxa3xx_nand_detect_config(info))
 		goto KEEP_CONFIG;
 
+	/* Set a default chunk size */
+	info->chunk_size = 512;
+
 	ret = pxa3xx_nand_sensing(info);
 	if (ret) {
 		dev_info(&info->pdev->dev, "There is no chip on cs %d!\n",


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: nand: pxa3xx_nand: fix early spurious interrupt
Message-ID: <E1ZWta5-0005Vz-0O@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0b14392db2e998157d924085d7913e537ec26121
Commit:     0b14392db2e998157d924085d7913e537ec26121
Parent:     bc3e00f04cc1fe033a289c2fc2e5c73c0168d360
Author:     Robert Jarzmik <robert.jarzmik at free.fr>
AuthorDate: Wed Aug 19 20:30:14 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Aug 19 15:25:19 2015 -0700

    mtd: nand: pxa3xx_nand: fix early spurious interrupt
    
    When the nand is first probe, and upon the first command start, the
    status bits should be cleared before the interrupts are unmasked.
    
    The bug is tricky : if the bootloader left a status bit set, the
    unmasking of interrupts does trigger the interrupt handler before the
    first command is issued, blocking the good behavior of the nand.
    
    The same would happen if in pxa3xx_nand code flow a status bit is left,
    and then a command is started.
    
    Signed-off-by: Robert Jarzmik <robert.jarzmik at free.fr>
    Acked-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Tested-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index baf3246..faf056b 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -442,8 +442,8 @@ static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
 	ndcr |= NDCR_ND_RUN;
 
 	/* clear status bits and run */
-	nand_writel(info, NDCR, 0);
 	nand_writel(info, NDSR, NDSR_MASK);
+	nand_writel(info, NDCR, 0);
 	nand_writel(info, NDCR, ndcr);
 }
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: nand: pxa3xx-nand: fix random command timeouts
Message-ID: <E1ZWta5-0005WR-3b@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=21fc0ef9652f0c809dc0d3e0a67f1e1bf6ff8255
Commit:     21fc0ef9652f0c809dc0d3e0a67f1e1bf6ff8255
Parent:     0b14392db2e998157d924085d7913e537ec26121
Author:     Robert Jarzmik <robert.jarzmik at free.fr>
AuthorDate: Wed Aug 19 20:30:15 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Aug 19 15:25:32 2015 -0700

    mtd: nand: pxa3xx-nand: fix random command timeouts
    
    When 2 commands are submitted in a row, and the second is very quick,
    the completion of the second command might never come. This happens
    especially if the second command is quick, such as a status read after
    an erase.
    
    The issue is that in the interrupt handler, the status bits are cleared
    after the new command is issued. There is a small temporal window where
    this happens :
     - the previous command has set the command done bit
     - the ready for a command bit is set
     - the handler submits the next command
       - just then, the command completes, and the command done bit is still
         set
     - the handler clears the "previous" command done bit
     - the handler exits
    
    In this flow, the "command done" of the next command will never trigger
    a new interrupt to finish the status command, as it was cleared for both
    commands.
    
    Fix this by clearing the status bit before submitting a new command.
    
    Signed-off-by: Robert Jarzmik <robert.jarzmik at free.fr>
    Acked-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Tested-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index faf056b..51f8a58 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -678,8 +678,14 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 		is_ready = 1;
 	}
 
+	/*
+	 * Clear all status bit before issuing the next command, which
+	 * can and will alter the status bits and will deserve a new
+	 * interrupt on its own. This lets the controller exit the IRQ
+	 */
+	nand_writel(info, NDSR, status);
+
 	if (status & NDSR_WRCMDREQ) {
-		nand_writel(info, NDSR, NDSR_WRCMDREQ);
 		status &= ~NDSR_WRCMDREQ;
 		info->state = STATE_CMD_HANDLE;
 
@@ -700,8 +706,6 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 			nand_writel(info, NDCB0, info->ndcb3);
 	}
 
-	/* clear NDSR to let the controller exit the IRQ */
-	nand_writel(info, NDSR, status);
 	if (is_completed)
 		complete(&info->cmd_complete);
 	if (is_ready)


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: nand: pxa3xx: Increase READ_ID buffer and make the size static
Message-ID: <E1ZWta5-0005Wv-6g@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=b226eca2088004622434cbcc27c6401b64f22d7c
Commit:     b226eca2088004622434cbcc27c6401b64f22d7c
Parent:     21fc0ef9652f0c809dc0d3e0a67f1e1bf6ff8255
Author:     Ezequiel Garc?a <ezequiel at vanguardiasur.com.ar>
AuthorDate: Wed Aug 19 19:40:09 2015 -0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Aug 19 15:53:48 2015 -0700

    nand: pxa3xx: Increase READ_ID buffer and make the size static
    
    The read ID count should be made as large as the maximum READ_ID size,
    so there's no need to have dynamic size. This commit sets the hardware
    maximum read ID count, which should be more than enough on all cases.
    Also, we get rid of the read_id_bytes, and use a macro instead.
    
    Signed-off-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
    Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 31 ++++++++++---------------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 51f8a58..740983a 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -129,6 +129,13 @@
 #define EXT_CMD_TYPE_LAST_RW	1 /* Last naked read/write */
 #define EXT_CMD_TYPE_MONO	0 /* Monolithic read/write */
 
+/*
+ * This should be large enough to read 'ONFI' and 'JEDEC'.
+ * Let's use 7 bytes, which is the maximum ID count supported
+ * by the controller (see NDCR_RD_ID_CNT_MASK).
+ */
+#define READ_ID_BYTES		7
+
 /* macros for registers read/write */
 #define nand_writel(info, off, val)	\
 	writel_relaxed((val), (info)->mmio_base + (off))
@@ -176,8 +183,6 @@ struct pxa3xx_nand_host {
 	/* calculated from pxa3xx_nand_flash data */
 	unsigned int		col_addr_cycles;
 	unsigned int		row_addr_cycles;
-	size_t			read_id_bytes;
-
 };
 
 struct pxa3xx_nand_info {
@@ -917,7 +922,7 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 		break;
 
 	case NAND_CMD_READID:
-		info->buf_count = host->read_id_bytes;
+		info->buf_count = READ_ID_BYTES;
 		info->ndcb0 |= NDCB0_CMD_TYPE(3)
 				| NDCB0_ADDR_CYC(1)
 				| command;
@@ -1254,9 +1259,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 		return -EINVAL;
 	}
 
-	/* calculate flash information */
-	host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
-
 	/* calculate addressing information */
 	host->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
 
@@ -1272,7 +1274,7 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 	ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0;
 	ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0;
 
-	ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
+	ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES);
 	ndcr |= NDCR_SPARE_EN; /* enable spare by default */
 
 	info->reg_ndcr = ndcr;
@@ -1283,23 +1285,10 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 
 static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 {
-	/*
-	 * We set 0 by hard coding here, for we don't support keep_config
-	 * when there is more than one chip attached to the controller
-	 */
-	struct pxa3xx_nand_host *host = info->host[0];
 	uint32_t ndcr = nand_readl(info, NDCR);
 
-	if (ndcr & NDCR_PAGE_SZ) {
-		/* Controller's FIFO size */
-		info->chunk_size = 2048;
-		host->read_id_bytes = 4;
-	} else {
-		info->chunk_size = 512;
-		host->read_id_bytes = 2;
-	}
-
 	/* Set an initial chunk size */
+	info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
 	info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
 	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
 	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: dataflash: Export OF module alias information
Message-ID: <E1ZWta5-0005XR-8i@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=d1d97b76c4af41c8e836e73742c91cbf97d7483c
Commit:     d1d97b76c4af41c8e836e73742c91cbf97d7483c
Parent:     b226eca2088004622434cbcc27c6401b64f22d7c
Author:     Javier Martinez Canillas <javier at osg.samsung.com>
AuthorDate: Thu Aug 20 09:07:16 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Fri Aug 21 18:01:42 2015 -0700

    mtd: dataflash: Export OF module alias information
    
    The SPI core currently reports the MODALIAS uevent as "spi:<modalias>"
    even for SPI devices that were registered by OF.
    
    That means the OF module alias exported by MODULE_OF_TABLE(of,...) is
    currently not used and user-space has no way to autoload this module.
    
    But it is still a good practice to add the OF module alias information
    into the kernel module even when it currently is unused so once the SPI
    core is changed to report a correct OF modalias uevent, module
    autoloading will be working for this driver.
    
    Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/mtd_dataflash.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 0099aba..df6f611 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -102,6 +102,7 @@ static const struct of_device_id dataflash_dt_ids[] = {
 	{ .compatible = "atmel,dataflash", },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, dataflash_dt_ids);
 #endif
 
 /* ......................................................................... */


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: nand: add Toshiba TC58NVG0S3E to nand_ids table
Message-ID: <E1ZWta5-0005Xr-C7@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0cb850486048ba4f64482a9d3e33dff47df34c79
Commit:     0cb850486048ba4f64482a9d3e33dff47df34c79
Parent:     d1d97b76c4af41c8e836e73742c91cbf97d7483c
Author:     Oleksij Rempel <linux at rempel-privat.de>
AuthorDate: Wed Dec 31 13:58:53 2014 +0100
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 25 12:24:02 2015 -0700

    mtd: nand: add Toshiba TC58NVG0S3E to nand_ids table
    
    Add the full description of the Toshiba TC58NVG0S3E NAND chip in the
    nand_ids table so that we can later use the NAND ECC info and ONFI timing
    mode in controller drivers.
    
    Tested with asm9260_nand driver. [Brian: driver still under review]
    
    Signed-off-by: Oleksij Rempel <linux at rempel-privat.de>
    Reviewed-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/nand_ids.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 7124400..a8804a3 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -29,6 +29,10 @@ struct nand_flash_dev nand_flash_ids[] = {
 	 * listed by full ID. We list them first so that we can easily identify
 	 * the most specific match.
 	 */
+	{"TC58NVG0S3E 1G 3.3V 8-bit",
+		{ .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} },
+		  SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512),
+		  2 },
 	{"TC58NVG2S0F 4G 3.3V 8-bit",
 		{ .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} },
 		  SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) },


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: spi-nor: stop (ab)using struct spi_device_id
Message-ID: <E1ZWta5-0005YJ-Fb@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=06bb6f5a69dfc53b79dd5f7afabdcd070a18afbf
Commit:     06bb6f5a69dfc53b79dd5f7afabdcd070a18afbf
Parent:     0cb850486048ba4f64482a9d3e33dff47df34c79
Author:     Rafa? Mi?ecki <zajec5 at gmail.com>
AuthorDate: Mon Aug 10 21:39:03 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 25 13:42:21 2015 -0700

    mtd: spi-nor: stop (ab)using struct spi_device_id
    
    Using struct spi_device_id for storing list of flash devices comes from
    early SPI NOR framework days. Thanks to the commit 70f3ce0510af ("mtd:
    spi-nor: make spi_nor_scan() take a chip type name, not spi_device_id")
    we can stop using spi_device_id and just switch to our own struct.
    
    Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 62 +++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 35 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 47df4b5..c27d427 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -29,6 +29,8 @@
 #define SPI_NOR_MAX_ID_LEN	6
 
 struct flash_info {
+	char		*name;
+
 	/*
 	 * This array stores the ID bytes.
 	 * The first three bytes are the JEDIC ID.
@@ -59,7 +61,7 @@ struct flash_info {
 
 #define JEDEC_MFR(info)	((info)->id[0])
 
-static const struct spi_device_id *spi_nor_match_id(const char *name);
+static const struct flash_info *spi_nor_match_id(const char *name);
 
 /*
  * Read the status register, returning its value in the location
@@ -169,7 +171,7 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 }
 
 /* Enable/disable 4-byte addressing mode. */
-static inline int set_4byte(struct spi_nor *nor, struct flash_info *info,
+static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
 			    int enable)
 {
 	int status;
@@ -469,7 +471,6 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-	((kernel_ulong_t)&(struct flash_info) {				\
 		.id = {							\
 			((_jedec_id) >> 16) & 0xff,			\
 			((_jedec_id) >> 8) & 0xff,			\
@@ -481,11 +482,9 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 		.sector_size = (_sector_size),				\
 		.n_sectors = (_n_sectors),				\
 		.page_size = 256,					\
-		.flags = (_flags),					\
-	})
+		.flags = (_flags),
 
 #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-	((kernel_ulong_t)&(struct flash_info) {				\
 		.id = {							\
 			((_jedec_id) >> 16) & 0xff,			\
 			((_jedec_id) >> 8) & 0xff,			\
@@ -498,17 +497,14 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 		.sector_size = (_sector_size),				\
 		.n_sectors = (_n_sectors),				\
 		.page_size = 256,					\
-		.flags = (_flags),					\
-	})
+		.flags = (_flags),
 
 #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
-	((kernel_ulong_t)&(struct flash_info) {				\
 		.sector_size = (_sector_size),				\
 		.n_sectors = (_n_sectors),				\
 		.page_size = (_page_size),				\
 		.addr_width = (_addr_width),				\
-		.flags = (_flags),					\
-	})
+		.flags = (_flags),
 
 /* NOTE: double check command sets and memory organization when you add
  * more nor chips.  This current list focusses on newer chips, which
@@ -521,7 +517,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  * For historical (and compatibility) reasons (before we got above config) some
  * old entries may be missing 4K flag.
  */
-static const struct spi_device_id spi_nor_ids[] = {
+static const struct flash_info spi_nor_ids[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
 	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
 	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
@@ -703,11 +699,11 @@ static const struct spi_device_id spi_nor_ids[] = {
 	{ },
 };
 
-static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
+static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 {
 	int			tmp;
 	u8			id[SPI_NOR_MAX_ID_LEN];
-	struct flash_info	*info;
+	const struct flash_info	*info;
 
 	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
 	if (tmp < 0) {
@@ -716,7 +712,7 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
 	}
 
 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
-		info = (void *)spi_nor_ids[tmp].driver_data;
+		info = &spi_nor_ids[tmp];
 		if (info->id_len) {
 			if (!memcmp(info->id, id, info->id_len))
 				return &spi_nor_ids[tmp];
@@ -962,7 +958,7 @@ static int micron_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
-static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
 {
 	int status;
 
@@ -1004,8 +1000,7 @@ static int spi_nor_check(struct spi_nor *nor)
 
 int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 {
-	const struct spi_device_id	*id = NULL;
-	struct flash_info		*info;
+	const struct flash_info *info = NULL;
 	struct device *dev = nor->dev;
 	struct mtd_info *mtd = nor->mtd;
 	struct device_node *np = dev->of_node;
@@ -1017,26 +1012,24 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 		return ret;
 
 	if (name)
-		id = spi_nor_match_id(name);
+		info = spi_nor_match_id(name);
 	/* Try to auto-detect if chip name wasn't specified or not found */
-	if (!id)
-		id = spi_nor_read_id(nor);
-	if (IS_ERR_OR_NULL(id))
+	if (!info)
+		info = spi_nor_read_id(nor);
+	if (IS_ERR_OR_NULL(info))
 		return -ENOENT;
 
-	info = (void *)id->driver_data;
-
 	/*
 	 * If caller has specified name of flash model that can normally be
 	 * detected using JEDEC, let's verify it.
 	 */
 	if (name && info->id_len) {
-		const struct spi_device_id *jid;
+		const struct flash_info *jinfo;
 
-		jid = spi_nor_read_id(nor);
-		if (IS_ERR(jid)) {
-			return PTR_ERR(jid);
-		} else if (jid != id) {
+		jinfo = spi_nor_read_id(nor);
+		if (IS_ERR(jinfo)) {
+			return PTR_ERR(jinfo);
+		} else if (jinfo != info) {
 			/*
 			 * JEDEC knows better, so overwrite platform ID. We
 			 * can't trust partitions any longer, but we'll let
@@ -1045,9 +1038,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 			 * information, even if it's not 100% accurate.
 			 */
 			dev_warn(dev, "found %s, expected %s\n",
-				 jid->name, id->name);
-			id = jid;
-			info = (void *)jid->driver_data;
+				 jinfo->name, info->name);
+			info = jinfo;
 		}
 	}
 
@@ -1197,7 +1189,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 
 	nor->read_dummy = spi_nor_read_dummy_cycles(nor);
 
-	dev_info(dev, "%s (%lld Kbytes)\n", id->name,
+	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
 			(long long)mtd->size >> 10);
 
 	dev_dbg(dev,
@@ -1220,9 +1212,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 }
 EXPORT_SYMBOL_GPL(spi_nor_scan);
 
-static const struct spi_device_id *spi_nor_match_id(const char *name)
+static const struct flash_info *spi_nor_match_id(const char *name)
 {
-	const struct spi_device_id *id = spi_nor_ids;
+	const struct flash_info *id = spi_nor_ids;
 
 	while (id->name[0]) {
 		if (!strcmp(name, id->name))


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: blkdevs: fix switch-bool compilation warning
Message-ID: <E1ZWta5-0005Yl-JT@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=cc7fce80229067890365c1ee196be5d304d36dea
Commit:     cc7fce80229067890365c1ee196be5d304d36dea
Parent:     06bb6f5a69dfc53b79dd5f7afabdcd070a18afbf
Author:     Tomer Barletz <barletz at gmail.com>
AuthorDate: Tue Aug 4 21:00:24 2015 -0700
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Tue Aug 25 13:58:10 2015 -0700

    mtd: blkdevs: fix switch-bool compilation warning
    
    With gcc 5.1 I get:
    warning: switch condition has boolean value [-Wswitch-bool]
    
    Signed-off-by: Tomer Barletz <barletz at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/mtd_blkdevs.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 41acc50..8830475 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -97,14 +97,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 	if (req->cmd_flags & REQ_DISCARD)
 		return tr->discard(dev, block, nsect);
 
-	switch(rq_data_dir(req)) {
-	case READ:
+	if (rq_data_dir(req) == READ) {
 		for (; nsect > 0; nsect--, block++, buf += tr->blksize)
 			if (tr->readsect(dev, block, buf))
 				return -EIO;
 		rq_flush_dcache_pages(req);
 		return 0;
-	case WRITE:
+	} else {
 		if (!tr->writesect)
 			return -EIO;
 
@@ -113,9 +112,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 			if (tr->writesect(dev, block, buf))
 				return -EIO;
 		return 0;
-	default:
-		printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
-		return -EIO;
 	}
 }
 


From linux-mtd at lists.infradead.org  Tue Sep  1 14:59:05 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 01 Sep 2015 21:59:05 +0000
Subject: mtd: mtd_oobtest: Fix the address offset with vary_offset case
Message-ID: <E1ZWta5-0005ZD-M8@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=718e38b4d96085b4dab08d3d32e5e033aa1ba6e9
Commit:     718e38b4d96085b4dab08d3d32e5e033aa1ba6e9
Parent:     cc7fce80229067890365c1ee196be5d304d36dea
Author:     Roger Quadros <rogerq at ti.com>
AuthorDate: Wed Jul 8 14:50:19 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Aug 27 16:30:01 2015 -0700

    mtd: mtd_oobtest: Fix the address offset with vary_offset case
    
    When vary_offset is set (e.g. test case 3), the offset is not always
    zero so memcmpshow() will show the wrong offset in the print message.
    To fix this we introduce a new function memcmpshowoffset() which takes
    offset as a parameter and displays the right offset and use it in
    the case where offset is non zero.
    
    The old memcmpshow() functionality is preserved by converting it into
    a macro with offset preset to 0.
    
    Signed-off-by: Roger Quadros <rogerq at ti.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/tests/oobtest.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c
index 8e8525f..3176212 100644
--- a/drivers/mtd/tests/oobtest.c
+++ b/drivers/mtd/tests/oobtest.c
@@ -125,7 +125,8 @@ static int write_whole_device(void)
  * Display the address, offset and data bytes at comparison failure.
  * Return number of bitflips encountered.
  */
-static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t count)
+static size_t memcmpshowoffset(loff_t addr, loff_t offset, const void *cs,
+			       const void *ct, size_t count)
 {
 	const unsigned char *su1, *su2;
 	int res;
@@ -135,8 +136,9 @@ static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t cou
 	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) {
 		res = *su1 ^ *su2;
 		if (res) {
-			pr_info("error @addr[0x%lx:0x%zx] 0x%x -> 0x%x diff 0x%x\n",
-				(unsigned long)addr, i, *su1, *su2, res);
+			pr_info("error @addr[0x%lx:0x%lx] 0x%x -> 0x%x diff 0x%x\n",
+				(unsigned long)addr, (unsigned long)offset + i,
+				*su1, *su2, res);
 			bitflips += hweight8(res);
 		}
 	}
@@ -144,6 +146,9 @@ static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t cou
 	return bitflips;
 }
 
+#define memcmpshow(addr, cs, ct, count) memcmpshowoffset((addr), 0, (cs), (ct),\
+							 (count))
+
 /*
  * Compare with 0xff and show the address, offset and data bytes at
  * comparison failure. Return number of bitflips encountered.
@@ -228,9 +233,10 @@ static int verify_eraseblock(int ebnum)
 				errcnt += 1;
 				return err ? err : -1;
 			}
-			bitflips = memcmpshow(addr, readbuf + use_offset,
-					      writebuf + (use_len_max * i) + use_offset,
-					      use_len);
+			bitflips = memcmpshowoffset(addr, use_offset,
+						    readbuf + use_offset,
+						    writebuf + (use_len_max * i) + use_offset,
+						    use_len);
 
 			/* verify pre-offset area for 0xff */
 			bitflips += memffshow(addr, 0, readbuf, use_offset);


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: spi-nor: Add support for Micron n25q064a serial flash
Message-ID: <E1ZXbb4-0005Fs-3h@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=2a06c7b1fd2389aed2a308db8de803603d592444
Commit:     2a06c7b1fd2389aed2a308db8de803603d592444
Parent:     718e38b4d96085b4dab08d3d32e5e033aa1ba6e9
Author:     Mika Westerberg <mika.westerberg at linux.intel.com>
AuthorDate: Thu Aug 27 12:52:19 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 13:56:24 2015 -0700

    mtd: spi-nor: Add support for Micron n25q064a serial flash
    
    Add Micron (n25q064a) 8MB flash to the list of supported chips.
    
    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
    Reviewed-by: Jagan Teki <jteki at openedev.com>
    [Brian: fixup context]
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c27d427..2adf35b 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -586,6 +586,7 @@ static const struct flash_info spi_nor_ids[] = {
 	/* Micron */
 	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SPI_NOR_QUAD_READ) },
 	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: spi-nor: Add support for sst25wf020a
Message-ID: <E1ZXbb4-0005GF-9y@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=a1d97ef96e3899ad9d4ec0024f9b4927e0490689
Commit:     a1d97ef96e3899ad9d4ec0024f9b4927e0490689
Parent:     2a06c7b1fd2389aed2a308db8de803603d592444
Author:     Alexis Ballier <aballier at gentoo.org>
AuthorDate: Fri Aug 14 19:35:39 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 13:57:05 2015 -0700

    mtd: spi-nor: Add support for sst25wf020a
    
    It is a 256KiB flash with 4 KiB erase sectors
    and 64KiB overlay blocks.
    
    This is the one available on Hardkernel's Odroid U3 shield.
    
    Signed-off-by: Alexis Ballier <aballier at gentoo.org>
    [Brian: seems like this does NOT require the usual SST_WRITE hacks]
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 2adf35b..984f6f4 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -634,6 +634,7 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
 	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
 	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SECT_4K) },
 	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
 	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
 


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: nand: omap2: Rename shippable module to omap2_nand
Message-ID: <E1ZXbb4-0005Ge-C2@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=092f05c3eccbd616a0cfa21945412a3e82a9fb6c
Commit:     092f05c3eccbd616a0cfa21945412a3e82a9fb6c
Parent:     a1d97ef96e3899ad9d4ec0024f9b4927e0490689
Author:     Roger Quadros <rogerq at ti.com>
AuthorDate: Fri Aug 21 13:45:35 2015 +0300
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 14:04:49 2015 -0700

    mtd: nand: omap2: Rename shippable module to omap2_nand
    
    As both omap2 onenand and omap2 nand driver modules are
    named the same i.e. "omap2.ko", only one of them gets shipped
    during MODPOST if both are configured as loadable modules.
    
    To avoid this ambiguity let's ship the omap2 nand
    driver as "omap2_nand.ko"
    
    Reported by Pierre Neyron via github
    https://github.com/beagleboard/linux/issues/40
    
    Cc: Robert Nelson <robertcnelson at gmail.com>
    Signed-off-by: Roger Quadros <rogerq at ti.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1f897ec..075a027 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -26,7 +26,8 @@ obj-$(CONFIG_MTD_NAND_CS553X)		+= cs553x_nand.o
 obj-$(CONFIG_MTD_NAND_NDFC)		+= ndfc.o
 obj-$(CONFIG_MTD_NAND_ATMEL)		+= atmel_nand.o
 obj-$(CONFIG_MTD_NAND_GPIO)		+= gpio.o
-obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2.o
+omap2_nand-objs := omap2.o
+obj-$(CONFIG_MTD_NAND_OMAP2) 		+= omap2_nand.o
 obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD)	+= omap_elm.o
 obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
 obj-$(CONFIG_MTD_NAND_PXA3xx)		+= pxa3xx_nand.o


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: spi-nor: allow dual/quad reads on S25FL129P
Message-ID: <E1ZXbb4-0005H3-E3@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=c1752086796bafaf0c933240642ed1cf21ddab4f
Commit:     c1752086796bafaf0c933240642ed1cf21ddab4f
Parent:     092f05c3eccbd616a0cfa21945412a3e82a9fb6c
Author:     Jonas Gorski <jogo at openwrt.org>
AuthorDate: Wed Aug 26 14:56:53 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 14:07:53 2015 -0700

    mtd: spi-nor: allow dual/quad reads on S25FL129P
    
    According to the datasheet[1], both S25FL129P0 (256kB sectors) and
    S25FL129P1 (64kB sectors) support dual read, quad read, dual i/o read
    and quad i/o read.
    
    I have verified dual read to be working for S25FL129P1 on a dual
    capable spi controller. Quad as well as S25FL129P0 is untested, lacking
    hardware to verify.
    
    [1] http://www.spansion.com/Support/Datasheets/S25FL129P_00.pdf
    
    Signed-off-by: Jonas Gorski <jogo at openwrt.org>
    Reviewed-by: Marek Vasut <marex at denx.de>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 984f6f4..295e56e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -611,8 +611,8 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
 	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
-	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
 	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
 	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: spi-nor: s25sl064p supports both dual and quad I/O
Message-ID: <E1ZXbb4-0005HT-Gy@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0f12a27b47284e86eaa4a5ad3877ec3018463178
Commit:     0f12a27b47284e86eaa4a5ad3877ec3018463178
Parent:     c1752086796bafaf0c933240642ed1cf21ddab4f
Author:     Joachim Eastwood <manabian at gmail.com>
AuthorDate: Fri Aug 14 18:42:32 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 14:09:56 2015 -0700

    mtd: spi-nor: s25sl064p supports both dual and quad I/O
    
    This chip can be found on Hitex LPC4350 Evaluation Board.
    
    Signed-off-by: Joachim Eastwood <manabian at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 295e56e..25372f9 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -603,7 +603,7 @@ static const struct flash_info spi_nor_ids[] = {
 	 * for the chips listed here (without boot sectors).
 	 */
 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
+	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },


From linux-mtd at lists.infradead.org  Thu Sep  3 13:59:02 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Thu, 03 Sep 2015 20:59:02 +0000
Subject: mtd: spi-nor: fix NULL dereference when no match found in
 spi_nor_ids[]
Message-ID: <E1ZXbb4-0005Hw-JS@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=2ff46e6fea6254ac8fa97aeb9c14e51436ab95f6
Commit:     2ff46e6fea6254ac8fa97aeb9c14e51436ab95f6
Parent:     0f12a27b47284e86eaa4a5ad3877ec3018463178
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Wed Sep 2 16:34:35 2015 -0700
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Wed Sep 2 16:34:35 2015 -0700

    mtd: spi-nor: fix NULL dereference when no match found in spi_nor_ids[]
    
    Commit 06bb6f5a69df ("mtd: spi-nor: stop (ab)using struct
    spi_device_id") converted an array into a pointer, which means that
    we should be checking if the pointer goes anywhere, not whether the C
    string is empty. To do the latter means we dereference a NULL pointer
    when we reach the terminating entry, for which 'name' is now NULL
    instead of an array { 0, 0, ... }.
    
    Sample crash:
    
    [    1.101371] Unable to handle kernel NULL pointer dereference at virtual address 00000000
    [    1.109457] pgd = c0004000
    [    1.112157] [00000000] *pgd=00000000
    [    1.115736] Internal error: Oops: 5 [#1] SMP ARM
    [    1.120345] Modules linked in:
    [    1.123405] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 4.2.0-next-20150902+ #61
    [    1.130611] Hardware name: Rockchip (Device Tree)
    [    1.135306] task: ee0b8d40 ti: ee0ba000 task.ti: ee0ba000
    [    1.140697] PC is at spi_nor_scan+0x90/0x8c4
    [    1.144958] LR is at spi_nor_scan+0xa4/0x8c4
    ...
    [    1.504112] [<c03cc2e0>] (spi_nor_scan) from [<c03cb188>] (m25p_probe+0xc8/0x11c)
    [    1.511583] [<c03cb188>] (m25p_probe) from [<c03cd9d8>] (spi_drv_probe+0x60/0x7c)
    [    1.519055] [<c03cd9d8>] (spi_drv_probe) from [<c037faa0>] (driver_probe_device+0x1a0/0x444)
    [    1.527478] [<c037faa0>] (driver_probe_device) from [<c037fec8>] (__device_attach_driver+0x94/0xa0)
    [    1.536507] [<c037fec8>] (__device_attach_driver) from [<c037db3c>] (bus_for_each_drv+0x94/0xa4)
    [    1.545277] [<c037db3c>] (bus_for_each_drv) from [<c037f7e4>] (__device_attach+0xa4/0x144)
    [    1.553526] [<c037f7e4>] (__device_attach) from [<c0380058>] (device_initial_probe+0x1c/0x20)
    [    1.562035] [<c0380058>] (device_initial_probe) from [<c037ec88>] (bus_probe_device+0x38/0x94)
    [    1.570631] [<c037ec88>] (bus_probe_device) from [<c037ccf4>] (device_add+0x430/0x558)
    [    1.578534] [<c037ccf4>] (device_add) from [<c03d0240>] (spi_add_device+0xe4/0x174)
    [    1.586178] [<c03d0240>] (spi_add_device) from [<c03d0a24>] (spi_register_master+0x698/0x7d4)
    [    1.594688] [<c03d0a24>] (spi_register_master) from [<c03d0ba0>] (devm_spi_register_master+0x40/0x7c)
    [    1.603892] [<c03d0ba0>] (devm_spi_register_master) from [<c03d2fb4>] (rockchip_spi_probe+0x360/0x3f4)
    [    1.613182] [<c03d2fb4>] (rockchip_spi_probe) from [<c0381e34>] (platform_drv_probe+0x58/0xa8)
    [    1.621779] [<c0381e34>] (platform_drv_probe) from [<c037faa0>] (driver_probe_device+0x1a0/0x444)
    [    1.630635] [<c037faa0>] (driver_probe_device) from [<c037fdc4>] (__driver_attach+0x80/0xa4)
    [    1.639058] [<c037fdc4>] (__driver_attach) from [<c037e850>] (bus_for_each_dev+0x98/0xac)
    [    1.647221] [<c037e850>] (bus_for_each_dev) from [<c037f448>] (driver_attach+0x28/0x30)
    [    1.655210] [<c037f448>] (driver_attach) from [<c037ef74>] (bus_add_driver+0x128/0x250)
    [    1.663200] [<c037ef74>] (bus_add_driver) from [<c0380c40>] (driver_register+0xac/0xf0)
    [    1.671191] [<c0380c40>] (driver_register) from [<c0381d50>] (__platform_driver_register+0x58/0x6c)
    [    1.680221] [<c0381d50>] (__platform_driver_register) from [<c0a467c8>] (rockchip_spi_driver_init+0x18/0x20)
    [    1.690033] [<c0a467c8>] (rockchip_spi_driver_init) from [<c00098a4>] (do_one_initcall+0x124/0x1dc)
    [    1.699063] [<c00098a4>] (do_one_initcall) from [<c0a19f84>] (kernel_init_freeable+0x218/0x2ec)
    [    1.707748] [<c0a19f84>] (kernel_init_freeable) from [<c0719ed8>] (kernel_init+0x1c/0xf4)
    [    1.715912] [<c0719ed8>] (kernel_init) from [<c000fe50>] (ret_from_fork+0x14/0x24)
    [    1.723460] Code: e3510000 159f67c0 0a00000c e5961000 (e5d13000)
    [    1.729564] ---[ end trace 95baa6b3b861ce25 ]---
    
    Fixes: 06bb6f5a69df ("mtd: spi-nor: stop (ab)using struct spi_device_id")
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
    Cc: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 25372f9..f59aedf 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1218,7 +1218,7 @@ static const struct flash_info *spi_nor_match_id(const char *name)
 {
 	const struct flash_info *id = spi_nor_ids;
 
-	while (id->name[0]) {
+	while (id->name) {
 		if (!strcmp(name, id->name))
 			return id;
 		id++;


From linux-mtd at lists.infradead.org  Mon Sep 21 13:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Mon, 21 Sep 2015 20:59:01 +0000
Subject: mtd: nand: sunxi: fix OOB handling in ->write_xxx() functions
Message-ID: <E1Ze8Av-0000sw-KU@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=03a0e8a7c5ea29b5c4e72dfd64900b47a8fb6f2d
Commit:     03a0e8a7c5ea29b5c4e72dfd64900b47a8fb6f2d
Parent:     6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f
Author:     Boris BREZILLON <boris.brezillon at free-electrons.com>
AuthorDate: Mon Sep 14 10:41:03 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Sep 21 13:36:42 2015 -0700

    mtd: nand: sunxi: fix OOB handling in ->write_xxx() functions
    
    The USER_DATA register cannot be accessed using byte accessors on A13
    SoCs, thus triggering a bug when using memcpy_toio on this register.
    Declare an helper macros to convert an OOB buffer into a suitable
    USER_DATA value and vice-versa.
    
    This patch also fixes an error in the oob_required logic (some OOB data
    are not written even if the user required it) by removing the
    oob_required condition, which is perfectly valid since the core already
    fill ->oob_poi with FFs when oob_required is false.
    
    Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Cc: <stable at vger.kernel.org> # 3.19+
    Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support")
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/sunxi_nand.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index f97a58d..279cafd 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -147,6 +147,10 @@
 #define NFC_ECC_MODE		GENMASK(15, 12)
 #define NFC_RANDOM_SEED		GENMASK(30, 16)
 
+/* NFC_USER_DATA helper macros */
+#define NFC_BUF_TO_USER_DATA(buf)	((buf)[0] | ((buf)[1] << 8) | \
+					((buf)[2] << 16) | ((buf)[3] << 24))
+
 #define NFC_DEFAULT_TIMEOUT_MS	1000
 
 #define NFC_SRAM_SIZE		1024
@@ -646,15 +650,9 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
 		offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize;
 
 		/* Fill OOB data in */
-		if (oob_required) {
-			tmp = 0xffffffff;
-			memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp,
-				    4);
-		} else {
-			memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE,
-				    chip->oob_poi + offset - mtd->writesize,
-				    4);
-		}
+		writel(NFC_BUF_TO_USER_DATA(chip->oob_poi +
+					    layout->oobfree[i].offset),
+		       nfc->regs + NFC_REG_USER_DATA_BASE);
 
 		chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1);
 
@@ -784,14 +782,8 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
 		offset += ecc->size;
 
 		/* Fill OOB data in */
-		if (oob_required) {
-			tmp = 0xffffffff;
-			memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp,
-				    4);
-		} else {
-			memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob,
-				    4);
-		}
+		writel(NFC_BUF_TO_USER_DATA(oob),
+		       nfc->regs + NFC_REG_USER_DATA_BASE);
 
 		tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR |
 		      (1 << 30);


From linux-mtd at lists.infradead.org  Mon Sep 21 17:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Tue, 22 Sep 2015 00:59:01 +0000
Subject: mtd: nand: sunxi: fix sunxi_nand_chips_cleanup()
Message-ID: <E1ZeBvB-00042d-5g@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=8e375ccda31ccc73b087134e263c48d2114534f4
Commit:     8e375ccda31ccc73b087134e263c48d2114534f4
Parent:     03a0e8a7c5ea29b5c4e72dfd64900b47a8fb6f2d
Author:     Boris BREZILLON <boris.brezillon at free-electrons.com>
AuthorDate: Sun Sep 13 18:14:43 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Sep 21 17:11:59 2015 -0700

    mtd: nand: sunxi: fix sunxi_nand_chips_cleanup()
    
    The sunxi_nand_chips_cleanup() function is missing a call to list_del()
    which generates a double free error.
    
    Reported-by: Priit Laes <plaes at plaes.org>
    Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
    Cc: <stable at vger.kernel.org> # 3.19+
    Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support")
    Tested-by: Priit Laes <plaes at plaes.org>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/sunxi_nand.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 279cafd..e7d333c 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1381,6 +1381,7 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
 					node);
 		nand_release(&chip->mtd);
 		sunxi_nand_ecc_cleanup(&chip->nand.ecc);
+		list_del(&chip->node);
 	}
 }
 


From linux-mtd at lists.infradead.org  Sun Sep 27 17:59:01 2015
From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List)
Date: Mon, 28 Sep 2015 00:59:01 +0000
Subject: mxc_nand: fix copy_spare
Message-ID: <E1ZgMmT-0001dK-9K@bombadil.infradead.org>

Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=e5a5d92d9dc36055b971d79e408e345f5ce88701
Commit:     e5a5d92d9dc36055b971d79e408e345f5ce88701
Parent:     8e375ccda31ccc73b087134e263c48d2114534f4
Author:     Eric Benard <eric at eukrea.com>
AuthorDate: Wed Sep 23 17:07:28 2015 +0200
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Sun Sep 27 17:09:35 2015 -0700

    mxc_nand: fix copy_spare
    
    it was broken by 35d5d20efad8a04c8c002c7f31241dff973977a6
    "mtd: mxc_nand: cleanup copy_spare function"
    
    else we get the following error :
    [   22.709507] ubi0: attaching mtd3
    [   23.613470] ubi0: scanning is finished
    [   23.617278] ubi0: empty MTD device detected
    [   23.623219] Unhandled fault: imprecise external abort (0x1c06) at 0x9e62f0ec
    [   23.630291] pgd = 9df80000
    [   23.633005] [9e62f0ec] *pgd=8e60041e(bad)
    [   23.637064] Internal error: : 1c06 [#1] SMP ARM
    [   23.641605] Modules linked in:
    [   23.644687] CPU: 0 PID: 99 Comm: ubiattach Not tainted 4.2.0-dirty #22
    [   23.651222] Hardware name: Freescale i.MX53 (Device Tree Support)
    [   23.657322] task: 9e687300 ti: 9dcfc000 task.ti: 9dcfc000
    [   23.662744] PC is at memcpy16_toio+0x4c/0x74
    [   23.667026] LR is at mxc_nand_command+0x484/0x640
    [   23.671739] pc : [<803f9c08>]    lr : [<803faeb0>]    psr: 60000013
    [   23.671739] sp : 9dcfdb10  ip : 9e62f0ea  fp : 9dcfdb1c
    [   23.683222] r10: a09c1000  r9 : 0000001a  r8 : ffffffff
    [   23.688453] r7 : ffffffff  r6 : 9e674810  r5 : 9e674810  r4 : 000000b6
    [   23.694985] r3 : a09c16a4  r2 : a09c16a4  r1 : a09c16a4  r0 : 0000ffff
    [   23.701521] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
    [   23.708662] Control: 10c5387d  Table: 8df80019  DAC: 00000015
    [   23.714413] Process ubiattach (pid: 99, stack limit = 0x9dcfc210)
    [   23.720514] Stack: (0x9dcfdb10 to 0x9dcfe000)
    [   23.724881] db00:                                     9dcfdb6c 9dcfdb20 803faeb0 803f9bc8
    [   23.733069] db20: 803f227c 803f9b74 ffffffff 9e674810 9e674810 9e674810 00000040 9e62f010
    [   23.741255] db40: 803faa2c 9e674b40 9e674810 803faa2c 00000400 803faa2c 00000000 9df42800
    [   23.749441] db60: 9dcfdb9c 9dcfdb70 803f2024 803faa38 9e4201cc 00000000 803f0a78 9e674b40
    [   23.757627] db80: 803f1f80 9e674810 00000400 00000400 9dcfdc14 9dcfdba0 803f3bd8 803f1f8c
    [   23.765814] dba0: 9e4201cc 00000000 00000580 00000000 00000000 800718c0 0000007f 00001000
    [   23.774000] dbc0: 9df42800 000000e0 00000000 00000000 9e4201cc 00000000 00000000 00000000
    [   23.782186] dbe0: 00000580 00000580 00000000 9e674810 9dcfdc20 9dcfdce8 9df42800 00580000
    [   23.790372] dc00: 00000000 00000400 9dcfdc6c 9dcfdc18 803f3f94 803f39a4 9dcfdc20 00000000
    [   23.798558] dc20: 00000000 00000400 00000000 00000000 00000000 00000000 9df42800 00000000
    [   23.806744] dc40: 9dcfdd0c 00580000 00000000 00000400 00000000 9df42800 9dee1000 9d802000
    [   23.814930] dc60: 9dcfdc94 9dcfdc70 803eb63c 803f3f38 00000400 9dcfdce8 9df42800 dead4ead
    [   23.823116] dc80: 803eb5f4 00000000 9dcfdcc4 9dcfdc98 803e82ac 803eb600 00000400 9dcfdce8
    [   23.831301] dca0: 9df42800 00000400 9dee0000 00000000 00000400 00000000 9dcfdd1c 9dcfdcc8
    [   23.839488] dcc0: 80406048 803e8230 00000400 9dcfdce8 9df42800 9dcfdc78 00000008 00000000
    [   23.847673] dce0: 00000000 00000000 00000000 00000004 00000000 9df42800 9dee0000 00000000
    [   23.855859] dd00: 9d802030 00000000 9dc8b214 9d802000 9dcfdd44 9dcfdd20 804066cc 80405f50
    [   23.864047] dd20: 00000400 9dc8b200 9d802030 9df42800 9dee0000 9dc8b200 9dcfdd84 9dcfdd48
    [   23.872233] dd40: 8040a544 804065ac 9e401c80 000080d0 9dcfdd84 00000001 800fc828 9df42400
    [   23.880418] dd60: 00000000 00000080 9dc8b200 9dc8b200 9dc8b200 9dee0000 9dcfdddc 9dcfdd88
    [   23.888605] dd80: 803fb560 8040a440 9dcfddc4 9dcfdd98 800f1428 9dee1000 a0acf000 00000000
    [   23.896792] dda0: 00000000 ffffffff 00000006 00000000 9dee0000 9dee0000 00005600 00000080
    [   23.904979] ddc0: 9dc8b200 a0acf000 9dc8b200 8112514c 9dcfde24 9dcfdde0 803fc08c 803fb4f0
    [   23.913165] dde0: 9e401c80 00000013 9dcfde04 9dcfddf8 8006bbf8 8006ba00 9dcfde24 00000000
    [   23.921351] de00: 9dee0000 00000065 9dee0000 00000001 9dc8b200 8112514c 9dcfde84 9dcfde28
    [   23.929538] de20: 8040afa0 803fb948 ffffffff 00000000 9dc8b214 9dcfde40 800f1428 800f11dc
    [   23.937724] de40: 9dc8b21c 9dc8b20c 9dc8b204 9dee1000 9dc8b214 8069bb60 fffff000 fffff000
    [   23.945911] de60: 9e7b5400 00000000 9dee0000 9dee1000 00001000 9e7b5400 9dcfdecc 9dcfde88
    [   23.954097] de80: 803ff1bc 8040a630 9dcfdea4 9dcfde98 00000800 00000800 9dcfdecc 9dcfdea8
    [   23.962284] dea0: 803e8f6c 00000000 7e87ab70 9e7b5400 80113e30 00000003 9dcfc000 00000000
    [   23.970470] dec0: 9dcfdf04 9dcfded0 804008cc 803feb98 ffffffff 00000003 00000000 00000000
    [   23.978656] dee0: 00000000 00000000 9e7cb000 9dc193e0 7e87ab70 9dd92140 9dcfdf7c 9dcfdf08
    [   23.986842] df00: 80113b5c 8040080c 800fbed8 8006bbf0 9e7cb000 00000003 9e7cb000 9dd92140
    [   23.995029] df20: 9dc193e0 9dd92148 9dcfdf4c 9dcfdf38 8011022c 800fbe78 8000f9cc 9e687300
    [   24.003216] df40: 9dcfdf6c 9dcfdf50 8011f798 8007ffe8 7e87ab70 9dd92140 00000003 9dd92140
    [   24.011402] df60: 40186f40 7e87ab70 9dcfc000 00000000 9dcfdfa4 9dcfdf80 80113e30 8011373c
    [   24.019588] df80: 7e87ab70 7e87ab70 7e87aea9 00000036 8000fb84 9dcfc000 00000000 9dcfdfa8
    [   24.027775] dfa0: 8000f9a0 80113e00 7e87ab70 7e87ab70 00000003 40186f40 7e87ab70 00000000
    [   24.035962] dfc0: 7e87ab70 7e87ab70 7e87aea9 00000036 00000000 00000000 76fd1f70 00000000
    [   24.044148] dfe0: 76f80f8c 7e87ab28 00009810 76f80fc4 60000010 00000003 00000000 00000000
    [   24.052328] Backtrace:
    [   24.054806] [<803f9bbc>] (memcpy16_toio) from [<803faeb0>] (mxc_nand_command+0x484/0x640)
    [   24.062996] [<803faa2c>] (mxc_nand_command) from [<803f2024>] (nand_write_page+0xa4/0x154)
    [   24.071264]  r10:9df42800 r9:00000000 r8:803faa2c r7:00000400 r6:803faa2c r5:9e674810
    [   24.079180]  r4:9e674b40
    [   24.081738] [<803f1f80>] (nand_write_page) from [<803f3bd8>] (nand_do_write_ops+0x240/0x444)
    [   24.090180]  r8:00000400 r7:00000400 r6:9e674810 r5:803f1f80 r4:9e674b40
    [   24.096970] [<803f3998>] (nand_do_write_ops) from [<803f3f94>] (nand_write+0x68/0x88)
    [   24.104804]  r10:00000400 r9:00000000 r8:00580000 r7:9df42800 r6:9dcfdce8 r5:9dcfdc20
    [   24.112719]  r4:9e674810
    [   24.115287] [<803f3f2c>] (nand_write) from [<803eb63c>] (part_write+0x48/0x50)
    [   24.122514]  r10:9d802000 r9:9dee1000 r8:9df42800 r7:00000000 r6:00000400 r5:00000000
    [   24.130429]  r4:00580000
    [   24.132989] [<803eb5f4>] (part_write) from [<803e82ac>] (mtd_write+0x88/0xa0)
    [   24.140129]  r5:00000000 r4:803eb5f4
    [   24.143748] [<803e8224>] (mtd_write) from [<80406048>] (ubi_io_write+0x104/0x65c)
    [   24.151235]  r7:00000000 r6:00000400 r5:00000000 r4:9dee0000
    [   24.156968] [<80405f44>] (ubi_io_write) from [<804066cc>] (ubi_io_write_ec_hdr+0x12c/0x190)
    [   24.165323]  r10:9d802000 r9:9dc8b214 r8:00000000 r7:9d802030 r6:00000000 r5:9dee0000
    [   24.173239]  r4:9df42800
    [   24.175798] [<804065a0>] (ubi_io_write_ec_hdr) from [<8040a544>] (ubi_early_get_peb+0x110/0x1f0)
    [   24.184587]  r6:9dc8b200 r5:9dee0000 r4:9df42800
    [   24.189262] [<8040a434>] (ubi_early_get_peb) from [<803fb560>] (create_vtbl+0x7c/0x238)
    [   24.197271]  r10:9dee0000 r9:9dc8b200 r8:9dc8b200 r7:9dc8b200 r6:00000080 r5:00000000
    [   24.205187]  r4:9df42400
    [   24.207746] [<803fb4e4>] (create_vtbl) from [<803fc08c>] (ubi_read_volume_table+0x750/0xa64)
    [   24.216187]  r10:8112514c r9:9dc8b200 r8:a0acf000 r7:9dc8b200 r6:00000080 r5:00005600
    [   24.224103]  r4:9dee0000
    [   24.226662] [<803fb93c>] (ubi_read_volume_table) from [<8040afa0>] (ubi_attach+0x97c/0x152c)
    [   24.235103]  r10:8112514c r9:9dc8b200 r8:00000001 r7:9dee0000 r6:00000065 r5:9dee0000
    [   24.243018]  r4:00000000
    [   24.245579] [<8040a624>] (ubi_attach) from [<803ff1bc>] (ubi_attach_mtd_dev+0x630/0xbac)
    [   24.253673]  r10:9e7b5400 r9:00001000 r8:9dee1000 r7:9dee0000 r6:00000000 r5:9e7b5400
    [   24.261588]  r4:fffff000
    [   24.264148] [<803feb8c>] (ubi_attach_mtd_dev) from [<804008cc>] (ctrl_cdev_ioctl+0xcc/0x1cc)
    [   24.272589]  r10:00000000 r9:9dcfc000 r8:00000003 r7:80113e30 r6:9e7b5400 r5:7e87ab70
    [   24.280505]  r4:00000000
    [   24.283070] [<80400800>] (ctrl_cdev_ioctl) from [<80113b5c>] (do_vfs_ioctl+0x42c/0x6c4)
    [   24.291077]  r6:9dd92140 r5:7e87ab70 r4:9dc193e0
    [   24.295753] [<80113730>] (do_vfs_ioctl) from [<80113e30>] (SyS_ioctl+0x3c/0x64)
    [   24.303066]  r10:00000000 r9:9dcfc000 r8:7e87ab70 r7:40186f40 r6:9dd92140 r5:00000003
    [   24.310981]  r4:9dd92140
    [   24.313549] [<80113df4>] (SyS_ioctl) from [<8000f9a0>] (ret_fast_syscall+0x0/0x54)
    [   24.321123]  r9:9dcfc000 r8:8000fb84 r7:00000036 r6:7e87aea9 r5:7e87ab70 r4:7e87ab70
    [   24.328957] Code: e1c300b0 e1510002 e1a03001 1afffff9 (e89da800)
    [   24.335066] ---[ end trace ab1cb17887f21bbb ]---
    [   24.340249] Unhandled fault: imprecise external abort (0x1c06) at 0x7ee8bcf0
    [   24.347310] pgd = 9df3c000
    [   24.350023] [7ee8bcf0] *pgd=8dcbf831, *pte=8eb3334f, *ppte=8eb3383f
    Segmentation fault
    
    Fixes: 35d5d20efad8 ("mtd: mxc_nand: cleanup copy_spare function")
    Signed-off-by: Eric B?nard <eric at eukrea.com>
    Reviewed-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
    Reviewed-by: Baruch Siach <baruch at tkos.co.il>
    Cc: <stable at vger.kernel.org>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/nand/mxc_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 2426db8..f04445b 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -879,7 +879,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
 				      oob_chunk_size);
 
 		/* the last chunk */
-		memcpy16_toio(&s[oob_chunk_size * sparebuf_size],
+		memcpy16_toio(&s[i * sparebuf_size],
 			      &d[i * oob_chunk_size],
 			      host->used_oobsize - i * oob_chunk_size);
 	}


