From gregor.boirie at parrot.com  Mon Oct  1 04:01:15 2012
From: gregor.boirie at parrot.com (=?UTF-8?B?R3LDqWdvciBCb2lyaWU=?=)
Date: Mon, 1 Oct 2012 10:01:15 +0200
Subject: m25p80: missing MTD owner
Message-ID: <50694DCB.6010303@parrot.com>

Hi all,

It seems possible to unload m25p80 module while a JFFS2 partition is
still mounted onto flash. This produces oops when MTD layer tries to
access underlying device later on.

A quick look at m25p_probe shows that "owner" field of allocated mtd
device structure is left uninitialized, preventing MTD layer from
incrementing module usage count. This patch for v3.4.11 solves the issue
for me :

@@ -873,6 +873,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        else
                flash->mtd.name = dev_name(&spi->dev);

+       flash->mtd.owner = THIS_MODULE;
        flash->mtd.type = MTD_NORFLASH;
        flash->mtd.writesize = 1;
        flash->mtd.flags = MTD_CAP_NORFLASH;


Regards.

-- 
Gr?gor Boirie
Software engineer
R&D / OS platform
tel +33 1 48 03 73 24
-----------------------------------------
Parrot
174, quai de Jemmapes
75010 Paris  France
tel + 33 1 48 03 60 60
fax + 33 1 48 03 06 66
-----------------------------------------
http://www.parrot.com


From sachin.kamat at linaro.org  Mon Oct  1 14:10:55 2012
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Mon, 1 Oct 2012 23:40:55 +0530
Subject: [PATCH] mtd: onenand: Make flexonenand_set_boundary static
In-Reply-To: <CAH9JG2W4jVxrTQVwoLrnMmypcHhM5mfciyK=tvGmi+8i_L78vQ@mail.gmail.com>
References: <1348294351-27182-1-git-send-email-sachin.kamat@linaro.org>
 <CAH9JG2W4jVxrTQVwoLrnMmypcHhM5mfciyK=tvGmi+8i_L78vQ@mail.gmail.com>
Message-ID: <CAK9yfHx=oYRmmceTWhvSBP+3yBQsdHTXE_WHebPKFYTwmXLjQg@mail.gmail.com>

Hi David,

Please line up this patch for 3.7.

On 22 September 2012 12:10, Kyungmin Park <kyungmin.park at samsung.com> wrote:
> On 9/22/12, Sachin Kamat <sachin.kamat at linaro.org> wrote:
>> Fixes the following sparse warning:
>> drivers/mtd/onenand/onenand_base.c:3697:5: warning:
>> symbol 'flexonenand_set_boundary' was not declared. Should it be static?
>>
>> Cc: Kyungmin Park <kyungmin.park at samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park at samsung.com>
>> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
>> ---
>>  drivers/mtd/onenand/onenand_base.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/mtd/onenand/onenand_base.c
>> b/drivers/mtd/onenand/onenand_base.c
>> index 7153e0d..b3f41f2 100644
>> --- a/drivers/mtd/onenand/onenand_base.c
>> +++ b/drivers/mtd/onenand/onenand_base.c
>> @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct
>> mtd_info *mtd, int start, int
>>   * flexonenand_set_boundary  - Writes the SLC boundary
>>   * @param mtd                        - mtd info structure
>>   */
>> -int flexonenand_set_boundary(struct mtd_info *mtd, int die,
>> +static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
>>                                   int boundary, int lock)
>>  {
>>       struct onenand_chip *this = mtd->priv;
>> --
>> 1.7.4.1
>>
>>
>> ______________________________________________________
>> Linux MTD discussion mailing list
>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>



-- 
With warm regards,
Sachin


From sachin.kamat at linaro.org  Mon Oct  1 14:11:30 2012
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Mon, 1 Oct 2012 23:41:30 +0530
Subject: [PATCH] mtd: ofpart: Fix incorrect NULL check in
 parse_ofoldpart_partitions()
In-Reply-To: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
References: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <CAK9yfHyFT8Cz8J1aGhQgAUE_A-_2qjd5U5JPs17rxgd9x3erjw@mail.gmail.com>

ping...

On 25 September 2012 15:27, Sachin Kamat <sachin.kamat at linaro.org> wrote:
> The pointer returned by kzalloc should be tested for NULL
> to avoid potential NULL pointer dereference later. Incorrect
> pointer was being tested for NULL. Bug introduced by commit fbcf62a3
> (mtd: physmap_of: move parse_obsolete_partitions to become separate
> parser).
> This patch fixes this bug.
>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
> Cc: Artem Bityutskiy <artem.bityutskiy at intel.com>
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
> ---
>  drivers/mtd/ofpart.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
> index 64be8f0..d9127e2 100644
> --- a/drivers/mtd/ofpart.c
> +++ b/drivers/mtd/ofpart.c
> @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
>         nr_parts = plen / sizeof(part[0]);
>
>         *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
> -       if (!pparts)
> +       if (!*pparts)
>                 return -ENOMEM;
>
>         names = of_get_property(dp, "partition-names", &plen);
> --
> 1.7.4.1
>



-- 
With warm regards,
Sachin


From hechtb at googlemail.com  Tue Oct  2 09:12:00 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  2 Oct 2012 15:12:00 +0200
Subject: [PATCH 0/2] Add DMA and device tree support to the flash controller
 FLCTL
Message-ID: <1349183522-15321-1-git-send-email-hechtb@gmail.com>

This mini-series consists of 2 separately posted patch-sets that shrunk
to one patch each. It adds DMA support for the data part (not ECC) as
well as device tree support to the FLCTL flash controller.
As the 2nd patch is based on the 1st, I've decided to
collect them here to avoid any confusion.

The first set contained
[PATCH 1/2] mtd: sh_flctl: Setup and release DMA channels
[PATCH 2/2] mtd: sh_flctl: Use DMA for data fifo FLTDFIFO when available
and was merged after 2 reviews to
[PATCH] mtd: sh_flctl: Add DMA capabilty (same patch as in here)

The second set contained
[PATCH 1/3] mtd: sh_flctl: Probe SNAND_E flag from NAND chip
[PATCH 2/3] mtd: sh_flctl: Add device tree support
[PATCH 3/3] mtd: sh_flctl: Add sh7372 device tree config
and is merged here to
mtd: sh_flctl: Add device tree support

Patch 1 can be omitted as SNAND_E is handled in the FLCTL source anyway
correctly in set_cmd_regs() and the flag can be removed from existing board
codes without this patch.
Patch 2 without patch 3 may be confusing so I merged them too. Documentation
is added as well.

I've added linux-arm-kernel at lists.infradead.org as recipient for the
device tree part.

The patchset is based on
l2-mtd	git://git.infradead.org/users/dedekind/l2-mtd.git
with reverted commit e26c113b4130aefa1d8446602bb5b05cfd646bfe.


Bastian Hecht (2):
  mtd: sh_flctl: Add DMA capabilty
  mtd: sh_flctl: Add device tree support

 .../devicetree/bindings/mtd/flctl-nand.txt         |   37 +++
 drivers/mtd/nand/sh_flctl.c                        |  266 +++++++++++++++++++-
 include/linux/mtd/sh_flctl.h                       |   12 +
 3 files changed, 305 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

-- 
1.7.5.4



From hechtb at googlemail.com  Tue Oct  2 09:12:01 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  2 Oct 2012 15:12:01 +0200
Subject: [PATCH 1/2] mtd: sh_flctl: Add DMA capabilty
In-Reply-To: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
Message-ID: <1349183522-15321-2-git-send-email-hechtb@gmail.com>

The code probes if DMA channels can get allocated and tears them down at
removal/failure if needed.
If available it uses them to transfer the data part (not ECC). On
failure we fall back to PIO mode.

Based on Guennadi Liakhovetski's code from the sh_mmcif driver.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
---
 drivers/mtd/nand/sh_flctl.c  |  174 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/mtd/sh_flctl.h |   12 +++
 2 files changed, 183 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4fbfe96..0fead2a 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -24,10 +24,13 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
@@ -106,6 +109,84 @@ static void wait_completion(struct sh_flctl *flctl)
 	writeb(0x0, FLTRCR(flctl));
 }
 
+static void flctl_dma_complete(void *param)
+{
+	struct sh_flctl *flctl = param;
+
+	complete(&flctl->dma_complete);
+}
+
+static void flctl_release_dma(struct sh_flctl *flctl)
+{
+	if (flctl->chan_fifo0_rx) {
+		dma_release_channel(flctl->chan_fifo0_rx);
+		flctl->chan_fifo0_rx = NULL;
+	}
+	if (flctl->chan_fifo0_tx) {
+		dma_release_channel(flctl->chan_fifo0_tx);
+		flctl->chan_fifo0_tx = NULL;
+	}
+}
+
+static void flctl_setup_dma(struct sh_flctl *flctl)
+{
+	dma_cap_mask_t mask;
+	struct dma_slave_config cfg;
+	struct platform_device *pdev = flctl->pdev;
+	struct sh_flctl_platform_data *pdata = pdev->dev.platform_data;
+	int ret;
+
+	if (!pdata)
+		return;
+
+	if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0)
+		return;
+
+	/* We can only either use DMA for both Tx and Rx or not use it at all */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_tx);
+	dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__,
+		flctl->chan_fifo0_tx);
+
+	if (!flctl->chan_fifo0_tx)
+		return;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.slave_id = pdata->slave_id_fifo0_tx;
+	cfg.direction = DMA_MEM_TO_DEV;
+	cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl);
+	cfg.src_addr = 0;
+	ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_rx);
+	dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__,
+		flctl->chan_fifo0_rx);
+
+	if (!flctl->chan_fifo0_rx)
+		goto err;
+
+	cfg.slave_id = pdata->slave_id_fifo0_rx;
+	cfg.direction = DMA_DEV_TO_MEM;
+	cfg.dst_addr = 0;
+	cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl);
+	ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	init_completion(&flctl->dma_complete);
+
+	return;
+
+err:
+	flctl_release_dma(flctl);
+}
+
 static void set_addr(struct mtd_info *mtd, int column, int page_addr)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -261,6 +342,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
 	timeout_error(flctl, __func__);
 }
 
+static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
+					int len, enum dma_data_direction dir)
+{
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct dma_chan *chan;
+	enum dma_transfer_direction tr_dir;
+	dma_addr_t dma_addr;
+	dma_cookie_t cookie = -EINVAL;
+	uint32_t reg;
+	int ret;
+
+	if (dir == DMA_FROM_DEVICE) {
+		chan = flctl->chan_fifo0_rx;
+		tr_dir = DMA_DEV_TO_MEM;
+	} else {
+		chan = flctl->chan_fifo0_tx;
+		tr_dir = DMA_MEM_TO_DEV;
+	}
+
+	dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
+
+	if (dma_addr)
+		desc = dmaengine_prep_slave_single(chan, dma_addr, len,
+			tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+	if (desc) {
+		reg = readl(FLINTDMACR(flctl));
+		reg |= DREQ0EN;
+		writel(reg, FLINTDMACR(flctl));
+
+		desc->callback = flctl_dma_complete;
+		desc->callback_param = flctl;
+		cookie = dmaengine_submit(desc);
+
+		dma_async_issue_pending(chan);
+	} else {
+		/* DMA failed, fall back to PIO */
+		flctl_release_dma(flctl);
+		dev_warn(&flctl->pdev->dev,
+			 "DMA failed, falling back to PIO\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	ret =
+	wait_for_completion_timeout(&flctl->dma_complete,
+				msecs_to_jiffies(3000));
+
+	if (ret <= 0) {
+		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+		dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
+	}
+
+out:
+	reg = readl(FLINTDMACR(flctl));
+	reg &= ~DREQ0EN;
+	writel(reg, FLINTDMACR(flctl));
+
+	dma_unmap_single(chan->device->dev, dma_addr, len, dir);
+
+	/* ret > 0 is success */
+	return ret;
+}
+
 static void read_datareg(struct sh_flctl *flctl, int offset)
 {
 	unsigned long data;
@@ -279,11 +424,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 
 	len_4align = (rlen + 3) / 4;
 
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_rx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0)
+			goto convert;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_rfifo_ready(flctl);
 		buf[i] = readl(FLDTFIFO(flctl));
-		buf[i] = be32_to_cpu(buf[i]);
 	}
+
+convert:
+	for (i = 0; i < len_4align; i++)
+		buf[i] = be32_to_cpu(buf[i]);
 }
 
 static enum flctl_ecc_res_t read_ecfiforeg
@@ -308,13 +462,23 @@ static enum flctl_ecc_res_t read_ecfiforeg
 static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 {
 	int i, len_4align;
-	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 	void *fifo_addr = (void *)FLDTFIFO(flctl);
 
 	len_4align = (rlen + 3) / 4;
+
+	for (i = 0; i < len_4align; i++)
+			buf[i] = cpu_to_be32(buf[i]);
+
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_tx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0)
+			return;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_wfifo_ready(flctl);
-		writel(cpu_to_be32(data[i]), fifo_addr);
+		writel(buf[i], fifo_addr);
 	}
 }
 
@@ -930,6 +1094,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume(&pdev->dev);
 
+	flctl_setup_dma(flctl);
+
 	ret = nand_scan_ident(flctl_mtd, 1, NULL);
 	if (ret)
 		goto err_chip;
@@ -947,6 +1113,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	return 0;
 
 err_chip:
+	flctl_release_dma(flctl);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(irq, flctl);
 err_flste:
@@ -960,6 +1127,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
 {
 	struct sh_flctl *flctl = platform_get_drvdata(pdev);
 
+	flctl_release_dma(flctl);
 	nand_release(&flctl->mtd);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(platform_get_irq(pdev, 0), flctl);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 01e4b15..e98fe7e 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -20,6 +20,7 @@
 #ifndef __SH_FLCTL_H__
 #define __SH_FLCTL_H__
 
+#include <linux/completion.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
@@ -107,6 +108,7 @@
 #define ESTERINTE	(0x1 << 24)	/* ECC error interrupt enable */
 #define AC1CLR		(0x1 << 19)	/* ECC FIFO clear */
 #define AC0CLR		(0x1 << 18)	/* Data FIFO clear */
+#define DREQ0EN		(0x1 << 16)	/* FLDTFIFODMA Request Enable */
 #define ECERB		(0x1 << 9)	/* ECC error */
 #define STERB		(0x1 << 8)	/* Status error */
 #define STERINTE	(0x1 << 4)	/* Status error enable */
@@ -138,6 +140,8 @@ enum flctl_ecc_res_t {
 	FL_TIMEOUT
 };
 
+struct dma_chan;
+
 struct sh_flctl {
 	struct mtd_info		mtd;
 	struct nand_chip	chip;
@@ -161,6 +165,11 @@ struct sh_flctl {
 	unsigned hwecc:1;	/* Hardware ECC (0 = disabled, 1 = enabled) */
 	unsigned holden:1;	/* Hardware has FLHOLDCR and HOLDEN is set */
 	unsigned qos_request:1;	/* QoS request to prevent deep power shutdown */
+
+	/* DMA related objects */
+	struct dma_chan		*chan_fifo0_rx;
+	struct dma_chan		*chan_fifo0_tx;
+	struct completion	dma_complete;
 };
 
 struct sh_flctl_platform_data {
@@ -170,6 +179,9 @@ struct sh_flctl_platform_data {
 
 	unsigned has_hwecc:1;
 	unsigned use_holden:1;
+
+	unsigned int            slave_id_fifo0_tx;
+	unsigned int            slave_id_fifo0_rx;
 };
 
 static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
-- 
1.7.5.4



From hechtb at googlemail.com  Tue Oct  2 09:12:02 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  2 Oct 2012 15:12:02 +0200
Subject: [PATCH 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
Message-ID: <1349183522-15321-3-git-send-email-hechtb@gmail.com>

The flctl can now be probed via device tree setup in addition to the
existing platform data way.

SoC specific setup data is set in the .data member of the OF match, so
kept within the driver itself, while board/user specific setup - like
partitioning - is taken from the device tree.

Actual configuration is added for the SoC sh7372.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
---
 .../devicetree/bindings/mtd/flctl-nand.txt         |   37 ++++++++
 drivers/mtd/nand/sh_flctl.c                        |   92 ++++++++++++++++++--
 2 files changed, 122 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
new file mode 100644
index 0000000..f615031
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
@@ -0,0 +1,37 @@
+FLCTL NAND controller
+
+Required properties:
+- compatible : "renesas,shmobile-flctl-sh7372"
+- reg : Address range of the FLCTL
+- interrupts : flste IRQ number
+- nand-bus-width : bus width to NAND chip
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+	flctl at e6a30000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "renesas,shmobile-flctl-sh7372";
+		reg = <0xe6a30000 0x100>;
+		interrupts = <0x0d80>;
+
+		nand-bus-width = <16>;
+
+		system at 0 {
+			label = "system";
+			reg = <0x0 0x8000000>;
+		};
+
+		userdata at 8000000 {
+			label = "userdata";
+			reg = <0x8000000 0x10000000>;
+		};
+
+		cache at 18000000 {
+			label = "cache";
+			reg = <0x18000000 0x8000000>;
+		};
+	};
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 0fead2a..4c7e542 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -28,6 +28,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mtd.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/sh_dma.h>
@@ -1020,6 +1023,73 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+struct flctl_soc_config {
+	unsigned long flcmncr_val;
+	unsigned has_hwecc:1;
+	unsigned use_holden:1;
+};
+
+static struct flctl_soc_config flctl_sh7372_config = {
+	.flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL,
+	.has_hwecc = 1,
+	.use_holden = 1,
+};
+
+static const struct of_device_id of_flctl_match[] = {
+	{ .compatible = "renesas,shmobile-flctl-sh7372",
+				.data = &flctl_sh7372_config },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_flctl_match);
+
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	const struct of_device_id *match;
+	struct flctl_soc_config *config;
+	struct sh_flctl_platform_data *pdata;
+	struct device_node *dn = dev->of_node;
+	int ret;
+
+	match = of_match_device(of_flctl_match, dev);
+	if (match)
+		config = (struct flctl_soc_config *)match->data;
+	else {
+		dev_err(dev, "%s: no OF configuration attached\n", __func__);
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data),
+								GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "%s: failed to allocate config data\n", __func__);
+		return NULL;
+	}
+
+	/* set SoC specific options */
+	pdata->flcmncr_val = config->flcmncr_val;
+	pdata->has_hwecc = config->has_hwecc;
+	pdata->use_holden = config->use_holden;
+
+	/* parse user defined options */
+	ret = of_get_nand_bus_width(dn);
+	if (ret == 16)
+		pdata->flcmncr_val |= SEL_16BIT;
+	else if (ret != 8) {
+		dev_err(dev, "%s: invalid bus width\n", __func__);
+		return NULL;
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+#define of_flctl_match NULL
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit flctl_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -1029,12 +1099,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	struct sh_flctl_platform_data *pdata;
 	int ret = -ENXIO;
 	int irq;
-
-	pdata = pdev->dev.platform_data;
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
+	struct mtd_part_parser_data ppdata = {};
 
 	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
 	if (!flctl) {
@@ -1066,6 +1131,16 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 		goto err_flste;
 	}
 
+	if (pdev->dev.of_node)
+		pdata = flctl_parse_dt(&pdev->dev);
+	else
+		pdata = pdev->dev.platform_data;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no setup data defined\n");
+		return -EINVAL;
+	}
+
 	platform_set_drvdata(pdev, flctl);
 	flctl_mtd = &flctl->mtd;
 	nand = &flctl->chip;
@@ -1108,7 +1183,9 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_chip;
 
-	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+	ppdata.of_node = pdev->dev.of_node;
+	ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts,
+			pdata->nr_parts);
 
 	return 0;
 
@@ -1142,6 +1219,7 @@ static struct platform_driver flctl_driver = {
 	.driver = {
 		.name	= "sh_flctl",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_flctl_match,
 	},
 };
 
-- 
1.7.5.4



From dedekind1 at gmail.com  Tue Oct  2 09:35:41 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 02 Oct 2012 16:35:41 +0300
Subject: [GIT PULL] UBI changes for 3.7-rc1
Message-ID: <1349184941.2017.70.camel@sauron.fi.intel.com>

Hi Linus,

please, pull UBI changes.

The following changes since commit 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d:

  Linux 3.6-rc4 (2012-09-01 10:39:58 -0700)

are available in the git repository at:

  git://git.infradead.org/linux-ubi.git tags/upstream-3.7-rc1

for you to fetch changes up to 55393ba1bdedc5ded79b34b4cc08898a7776cddb:

  UBI: fix trivial typo 'it' => 'is' (2012-09-26 13:22:50 +0300)

----------------------------------------------------------------
The main change is the way we reserve eraseblocks for bad blocks
handling. We used to reserve 2% of the partition, but now we are
more aggressive and we reserve 2% of the entire chip, which is
what actually manufacturers specify in data sheets. We introduced
an option to users to override the default, though.

There are a couple of fixes as well, and a number of cleanups.

----------------------------------------------------------------
Artem Bityutskiy (7):
      UBI: print image sequence number as unsigned integer
      UBI: print PID in debug messages
      arm: sam9_l9260_defconfig: correct CONFIG_MTD_UBI_BEB_LIMIT
      UBI: fix autoresize handling in R/O mode
      UBI: comply with coding style
      UBI: use pr_ helper instead of printk
      UBI: print less

Brian Norris (1):
      UBI: fix trivial typo 'it' => 'is'

Jiang Lu (1):
      UBI: load after mtd device drivers

Matthieu CASTET (1):
      UBI: erase free PEB with bitflip in EC header

Richard Genoud (9):
      mtd: mark mtd_is_partition argument as constant
      mtd: mtdparts: introduce mtd_get_device_size
      UBI: use the whole MTD device size to get bad_peb_limit
      UBI: separate bad_peb_limit in a function
      UBI: introduce MTD_PARAM_MAX_COUNT
      UBI: prepare for max_beb_per1024 module parameter addition
      UBI: check max_beb_per1024 value in ubi_attach_mtd_dev
      UBI: allow specifying bad PEBs limit using module parameter
      UBI: add max_beb_per1024 to attach ioctl

Shmulik Ladkani (5):
      arm: sam9_l9260_defconfig: prepare to UBI config change
      UBI: introduce new bad PEB limit
      UBI: limit amount of reserved eraseblocks for bad PEB handling
      UBI: kill CONFIG_MTD_UBI_BEB_RESERVE
      arm: sam9_l9260_defconfig: remove non-existing config option

 arch/arm/configs/sam9_l9260_defconfig |   2 +-
 drivers/mtd/mtdpart.c                 |  12 ++++++++++-
 drivers/mtd/ubi/Kconfig               |  40 ++++++++++++++++++++++++------------
 drivers/mtd/ubi/attach.c              |  46 ++++++++++++++++++++---------------------
 drivers/mtd/ubi/build.c               | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------
 drivers/mtd/ubi/cdev.c                |  18 ++++++++--------
 drivers/mtd/ubi/debug.c               | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------------------------------------------
 drivers/mtd/ubi/debug.h               |  12 ++++-------
 drivers/mtd/ubi/eba.c                 |  33 ++++++++++++++----------------
 drivers/mtd/ubi/gluebi.c              |  30 +++++++++++++--------------
 drivers/mtd/ubi/io.c                  |  80 +++++++++++++++++++++++++++++++++++------------------------------------
 drivers/mtd/ubi/misc.c                |  14 +++++++++----
 drivers/mtd/ubi/ubi.h                 |  16 +++++++--------
 drivers/mtd/ubi/vtbl.c                |  10 ++++-----
 drivers/mtd/ubi/wl.c                  |  48 +++++++++++++++++++++++++++----------------
 include/linux/mtd/partitions.h        |   3 ++-
 include/mtd/ubi-user.h                |  16 ++++++++++++++-
 17 files changed, 412 insertions(+), 325 deletions(-)

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121002/993f0a81/attachment.sig>

From dedekind1 at gmail.com  Tue Oct  2 09:35:46 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 02 Oct 2012 16:35:46 +0300
Subject: [GIT PULL] UBIFS changes for 3.7-rc1
Message-ID: <1349184946.2017.71.camel@sauron.fi.intel.com>

Hi Linus,

please, pull UBIFS changes.

The following changes since commit 69f9025894c391fec2f7c7ea9150203418454915:

  UBIFS: fix error messages spelling (2012-08-22 17:41:09 +0300)

are available in the git repository at:

  git://git.infradead.org/linux-ubifs.git tags/upstream-3.7-rc1

for you to fetch changes up to 3668b70fcf1fdc6799abf15f70fe3f50f407ec82:

  UBIFS: print less (2012-08-31 17:32:58 +0300)

----------------------------------------------------------------
No big changes for 3.7 in UBIFS:
* Error reporting and debug printing improvements
* Power cut emulation fixes
* Minor cleanups

----------------------------------------------------------------
Artem Bityutskiy (8):
      UBIFS: print PID in debug messages
      UBIFS: always print full error reports
      UBIFS: improve scanning debug output
      UBIFS: fix power cut emulation for mtdram
      UBIFS: use __aligned() attribute
      UBIFS: comply with coding style
      UBIFS: use pr_ helper instead of printk
      UBIFS: print less

Jiri Slaby (1):
      UBIFS: remove __DATE__ and __TIME__

 fs/ubifs/budget.c     |   5 +-
 fs/ubifs/commit.c     |   8 +--
 fs/ubifs/compress.c   |   7 +--
 fs/ubifs/debug.c      | 633 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------------------------------------------------------------------------------------
 fs/ubifs/debug.h      |  15 ++---
 fs/ubifs/dir.c        |   4 +-
 fs/ubifs/file.c       |   4 +-
 fs/ubifs/gc.c         |   6 +-
 fs/ubifs/log.c        |  14 ++---
 fs/ubifs/lprops.c     |  66 ++++++++++-----------
 fs/ubifs/lpt.c        |   5 +-
 fs/ubifs/lpt_commit.c |  58 ++++++++-----------
 fs/ubifs/orphan.c     |   7 +--
 fs/ubifs/recovery.c   |  11 ++--
 fs/ubifs/replay.c     |  16 ++---
 fs/ubifs/sb.c         |  19 +++---
 fs/ubifs/scan.c       |  15 +++--
 fs/ubifs/super.c      | 119 ++++++++++++++++++--------------------
 fs/ubifs/tnc_misc.c   |   4 +-
 fs/ubifs/ubifs.h      |  13 ++---
 20 files changed, 451 insertions(+), 578 deletions(-)

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121002/96597aa9/attachment.sig>

From arnd at arndb.de  Tue Oct  2 09:54:00 2012
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 2 Oct 2012 13:54:00 +0000
Subject: [PATCH 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <1349183522-15321-3-git-send-email-hechtb@gmail.com>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <1349183522-15321-3-git-send-email-hechtb@gmail.com>
Message-ID: <201210021354.01247.arnd@arndb.de>

On Tuesday 02 October 2012, Bastian Hecht wrote:
> +Required properties:
> +- compatible : "renesas,shmobile-flctl-sh7372"
> +- reg : Address range of the FLCTL
> +- interrupts : flste IRQ number
> +- nand-bus-width : bus width to NAND chip
> +
> +The device tree may optionally contain sub-nodes describing partitions of the
> +address space. See partition.txt for more detail.
> +
> +Example:
> +
> +       flctl at e6a30000 {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               compatible = "renesas,shmobile-flctl-sh7372";
> +               reg = <0xe6a30000 0x100>;
> +               interrupts = <0x0d80>;
> +
> +               nand-bus-width = <16>;
> +
> +               system at 0 {
> +                       label = "system";
> +                       reg = <0x0 0x8000000>;
> +               };
> +
> +               userdata at 8000000 {
> +                       label = "userdata";
> +                       reg = <0x8000000 0x10000000>;
> +               };
> +
> +               cache at 18000000 {
> +                       label = "cache";
> +                       reg = <0x18000000 0x8000000>;
> +               };
> +       };

Since you are also adding dma-engine support, I would suggest you specify
a "dmas" and "dma-names" property as well, so the device can find the
right dma channel. The code might not do that yet while you're still
sorting out the dependencies (and the sh dmaengine code is not yet
converted to DT), but I think it would be good to nail down the binding
for this device.

	Arnd


From g.liakhovetski at gmx.de  Tue Oct  2 09:55:05 2012
From: g.liakhovetski at gmx.de (Guennadi Liakhovetski)
Date: Tue, 2 Oct 2012 15:55:05 +0200 (CEST)
Subject: [PATCH 1/2] mtd: sh_flctl: Add DMA capabilty
In-Reply-To: <1349183522-15321-2-git-send-email-hechtb@gmail.com>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <1349183522-15321-2-git-send-email-hechtb@gmail.com>
Message-ID: <Pine.LNX.4.64.1210021534570.15778@axis700.grange>

On Tue, 2 Oct 2012, Bastian Hecht wrote:

> The code probes if DMA channels can get allocated and tears them down at
> removal/failure if needed.
> If available it uses them to transfer the data part (not ECC). On
> failure we fall back to PIO mode.
> 
> Based on Guennadi Liakhovetski's code from the sh_mmcif driver.
> 
> Signed-off-by: Bastian Hecht <hechtb at gmail.com>

Looks mostly good to me, just a couple of cosmetic remarks below. They are 
not critical, so, I won't be upset, if you fix them later:-) In any case

Reviewed-by: Guennadi Liakhovetski <g.liakhovetski at gmx.de>

> ---
>  drivers/mtd/nand/sh_flctl.c  |  174 +++++++++++++++++++++++++++++++++++++++++-
>  include/linux/mtd/sh_flctl.h |   12 +++
>  2 files changed, 183 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
> index 4fbfe96..0fead2a 100644
> --- a/drivers/mtd/nand/sh_flctl.c
> +++ b/drivers/mtd/nand/sh_flctl.c
> @@ -24,10 +24,13 @@
>  #include <linux/module.h>
>  #include <linux/kernel.h>
>  #include <linux/delay.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/sh_dma.h>
>  #include <linux/slab.h>
>  #include <linux/string.h>
>  
> @@ -106,6 +109,84 @@ static void wait_completion(struct sh_flctl *flctl)
>  	writeb(0x0, FLTRCR(flctl));
>  }
>  
> +static void flctl_dma_complete(void *param)
> +{
> +	struct sh_flctl *flctl = param;
> +
> +	complete(&flctl->dma_complete);

I think I mentioned in the first review, that it is good to include 
headers everywhere, where they are needed and not rely on pulling them in 
via other headers. So, it would be good to also include complete.h here 
directly.

[snip]

> @@ -308,13 +462,23 @@ static enum flctl_ecc_res_t read_ecfiforeg
>  static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
>  {
>  	int i, len_4align;
> -	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
> +	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
>  	void *fifo_addr = (void *)FLDTFIFO(flctl);
>  
>  	len_4align = (rlen + 3) / 4;
> +
> +	for (i = 0; i < len_4align; i++)
> +			buf[i] = cpu_to_be32(buf[i]);

indentation ran away here.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/


From g.liakhovetski at gmx.de  Tue Oct  2 10:04:54 2012
From: g.liakhovetski at gmx.de (Guennadi Liakhovetski)
Date: Tue, 2 Oct 2012 16:04:54 +0200 (CEST)
Subject: [PATCH 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <201210021354.01247.arnd@arndb.de>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <1349183522-15321-3-git-send-email-hechtb@gmail.com>
 <201210021354.01247.arnd@arndb.de>
Message-ID: <Pine.LNX.4.64.1210021602250.15778@axis700.grange>

Hi Arnd

On Tue, 2 Oct 2012, Arnd Bergmann wrote:

> On Tuesday 02 October 2012, Bastian Hecht wrote:
> > +Required properties:
> > +- compatible : "renesas,shmobile-flctl-sh7372"
> > +- reg : Address range of the FLCTL
> > +- interrupts : flste IRQ number
> > +- nand-bus-width : bus width to NAND chip
> > +
> > +The device tree may optionally contain sub-nodes describing partitions of the
> > +address space. See partition.txt for more detail.
> > +
> > +Example:
> > +
> > +       flctl at e6a30000 {
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               compatible = "renesas,shmobile-flctl-sh7372";
> > +               reg = <0xe6a30000 0x100>;
> > +               interrupts = <0x0d80>;
> > +
> > +               nand-bus-width = <16>;
> > +
> > +               system at 0 {
> > +                       label = "system";
> > +                       reg = <0x0 0x8000000>;
> > +               };
> > +
> > +               userdata at 8000000 {
> > +                       label = "userdata";
> > +                       reg = <0x8000000 0x10000000>;
> > +               };
> > +
> > +               cache at 18000000 {
> > +                       label = "cache";
> > +                       reg = <0x18000000 0x8000000>;
> > +               };
> > +       };
> 
> Since you are also adding dma-engine support, I would suggest you specify
> a "dmas" and "dma-names" property as well, so the device can find the
> right dma channel. The code might not do that yet while you're still
> sorting out the dependencies (and the sh dmaengine code is not yet
> converted to DT), but I think it would be good to nail down the binding
> for this device.

Have DMA DT bindings been accepted yet, are they fixed? Wouldn't it be 
better to wait until patches appear in a tree, at least with high 
probability heading towards the mainline, or have they already?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/


From vikram186 at gmail.com  Tue Oct  2 10:26:13 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 19:56:13 +0530
Subject: [RFC PATCH 0/8] mtd_tests: Remove duplicate code and cleanups
Message-ID: <506AF985.30104@gmail.com>

Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: Brian Norris <computersforpeace at gmail.com>
Cc: Adrian Hunter <ext-adrian.hunter at nokia.com>
Cc: Iwo Mergler <Iwo.Mergler at netcommwireless.com.au>

This RFC patchset moves some common code in all the tests to a common header
file. Also, all the printk,PRINT_PREF are replaced with pr_info style prints.
This way duplicates are eliminated and the code looks clean.

I deliberately missed out the mtd_oobtest as Brian Norris has already sent a
patch for that.

All the patches are compile tested and checkpatch clean(No checkpatch warnings
are introduced by the code that is added in this patch).

Vikram Narayanan(8):
  mtd_tests: Refactor duplicate code
  mtd_pagetest: Replace printk with pr_{info,crit}
  mtd_torturetest: Replace printk with pr_{info,crit}
  mtd_subpagetest: Replace printk with pr_info
  mtd_stresstest: Replace printk with pr_{info,crit}
  mtd_speedtest: Replace printk with pr_{info,crit}
  mtd_readtest: Replace printk with pr_info
  mtd_nandbiterrs: Replace msg macro with pr_info

 drivers/mtd/tests/mtd_nandbiterrs.c |   97 +++++++-----------
 drivers/mtd/tests/mtd_oobtest.c     |   31 +-----
 drivers/mtd/tests/mtd_pagetest.c    |  191 +++++++++++++++--------------------
 drivers/mtd/tests/mtd_readtest.c    |   42 ++++----
 drivers/mtd/tests/mtd_speedtest.c   |  140 ++++++++------------------
 drivers/mtd/tests/mtd_stresstest.c  |   71 ++++---------
 drivers/mtd/tests/mtd_subpagetest.c |  147 +++++++++++----------------
 drivers/mtd/tests/mtd_tests.h       |   60 +++++++++++
 drivers/mtd/tests/mtd_torturetest.c |  104 +++++++------------
 9 files changed, 370 insertions(+), 513 deletions(-)


From vikram186 at gmail.com  Tue Oct  2 10:28:00 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 19:58:00 +0530
Subject: [PATCH 1/8] mtd_tests: Refactor duplicate code
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AF9F0.7010903@gmail.com>

Move the duplicate code from all the tests to a common header.

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_nandbiterrs.c |   29 ++---------------
 drivers/mtd/tests/mtd_oobtest.c     |   31 ++----------------
 drivers/mtd/tests/mtd_pagetest.c    |   39 ++++------------------
 drivers/mtd/tests/mtd_speedtest.c   |   60 ++--------------------------------
 drivers/mtd/tests/mtd_stresstest.c  |   31 ++----------------
 drivers/mtd/tests/mtd_subpagetest.c |   29 +---------------
 drivers/mtd/tests/mtd_tests.h       |   60 +++++++++++++++++++++++++++++++++++
 drivers/mtd/tests/mtd_torturetest.c |   33 +------------------
 8 files changed, 84 insertions(+), 228 deletions(-)
 create mode 100644 drivers/mtd/tests/mtd_tests.h

diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c
index cc8d62c..072fc43 100644
--- a/drivers/mtd/tests/mtd_nandbiterrs.c
+++ b/drivers/mtd/tests/mtd_nandbiterrs.c
@@ -46,6 +46,7 @@
 #include <linux/err.h>
 #include <linux/mtd/nand.h>
 #include <linux/slab.h>
+#include "mtd_tests.h"
 
 #define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
 
@@ -97,30 +98,6 @@ static uint8_t hash(unsigned offset)
 	return c;
 }
 
-static int erase_block(void)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = eraseblock * mtd->erasesize;
-
-	msg("erase_block\n");
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err || ei.state == MTD_ERASE_FAILED) {
-		msg("error %d while erasing\n", err);
-		if (!err)
-			err = -EIO;
-		return err;
-	}
-
-	return 0;
-}
-
 /* Writes wbuffer to page */
 static int write_page(int log)
 {
@@ -414,7 +391,7 @@ static int __init mtd_nandbiterrs_init(void)
 		goto exit_rbuffer;
 	}
 
-	err = erase_block();
+	err = erase_eraseblock(mtd, eraseblock);
 	if (err)
 		goto exit_error;
 
@@ -427,7 +404,7 @@ static int __init mtd_nandbiterrs_init(void)
 		goto exit_error;
 
 	/* We leave the block un-erased in case of test failure. */
-	err = erase_block();
+	err = erase_eraseblock(mtd, eraseblock);
 	if (err)
 		goto exit_error;
 
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index ed9b628..6714985 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include "mtd_tests.h"
 
 #define PRINT_PREF KERN_INFO "mtd_oobtest: "
 
@@ -67,32 +68,6 @@ static void set_random_data(unsigned char *buf, size_t len)
 		buf[i] = simple_rand();
 }
 
-static int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int erase_whole_device(void)
 {
 	int err;
@@ -102,7 +77,7 @@ static int erase_whole_device(void)
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
-		err = erase_eraseblock(i);
+		err = erase_eraseblock(mtd, i);
 		if (err)
 			return err;
 		cond_resched();
@@ -597,7 +572,7 @@ static int __init mtd_oobtest_init(void)
 			errcnt += 1;
 		}
 
-		err = erase_eraseblock(ebcnt - 1);
+		err = erase_eraseblock(mtd, ebcnt - 1);
 		if (err)
 			goto out;
 
diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c
index 252ddb0..2a09405 100644
--- a/drivers/mtd/tests/mtd_pagetest.c
+++ b/drivers/mtd/tests/mtd_pagetest.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include "mtd_tests.h"
 
 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
 
@@ -66,32 +67,6 @@ static void set_random_data(unsigned char *buf, size_t len)
 		buf[i] = simple_rand();
 }
 
-static int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int write_eraseblock(int ebnum)
 {
 	int err = 0;
@@ -321,7 +296,7 @@ static int erasecrosstest(void)
 		ebnum2 -= 1;
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
-	err = erase_eraseblock(ebnum);
+	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
@@ -354,7 +329,7 @@ static int erasecrosstest(void)
 	}
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
-	err = erase_eraseblock(ebnum);
+	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
@@ -369,7 +344,7 @@ static int erasecrosstest(void)
 	}
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum2);
-	err = erase_eraseblock(ebnum2);
+	err = erase_eraseblock(mtd, ebnum2);
 	if (err)
 		return err;
 
@@ -412,7 +387,7 @@ static int erasetest(void)
 	}
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
-	err = erase_eraseblock(ebnum);
+	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
@@ -426,7 +401,7 @@ static int erasetest(void)
 	}
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
-	err = erase_eraseblock(ebnum);
+	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
@@ -557,7 +532,7 @@ static int __init mtd_pagetest_init(void)
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
-		err = erase_eraseblock(i);
+		err = erase_eraseblock(mtd, i);
 		if (err)
 			goto out;
 		cond_resched();
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 42b0f74..e3518b4 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/random.h>
+#include "mtd_tests.h"
 
 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
 
@@ -57,59 +58,6 @@ static void set_random_data(unsigned char *buf, size_t len)
 		buf[i] = random32();
 }
 
-static int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int multiblock_erase(int ebnum, int blocks)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize * blocks;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n",
-		       err, ebnum, blocks);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d,"
-		       "blocks %d\n", ebnum, blocks);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int erase_whole_device(void)
 {
 	int err;
@@ -118,7 +66,7 @@ static int erase_whole_device(void)
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
-		err = erase_eraseblock(i);
+		err = erase_eraseblock(mtd, i);
 		if (err)
 			return err;
 		cond_resched();
@@ -510,7 +458,7 @@ static int __init mtd_speedtest_init(void)
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
-		err = erase_eraseblock(i);
+		err = erase_eraseblock(mtd, i);
 		if (err)
 			goto out;
 		cond_resched();
@@ -533,7 +481,7 @@ static int __init mtd_speedtest_init(void)
 				i++;
 				continue;
 			}
-			err = multiblock_erase(i, j);
+			err = multiblock_erase(mtd, i, j);
 			if (err)
 				goto out;
 			cond_resched();
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index cb268ce..87e2e05 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 #include <linux/random.h>
+#include "mtd_tests.h"
 
 #define PRINT_PREF KERN_INFO "mtd_stresstest: "
 
@@ -81,32 +82,6 @@ static int rand_len(int offs)
 	return len;
 }
 
-static int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (unlikely(err)) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (unlikely(ei.state == MTD_ERASE_FAILED)) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int is_block_bad(int ebnum)
 {
 	loff_t addr = ebnum * mtd->erasesize;
@@ -154,7 +129,7 @@ static int do_write(void)
 
 	offs = offsets[eb];
 	if (offs >= mtd->erasesize) {
-		err = erase_eraseblock(eb);
+		err = erase_eraseblock(mtd, eb);
 		if (err)
 			return err;
 		offs = offsets[eb] = 0;
@@ -165,7 +140,7 @@ static int do_write(void)
 		if (bbt[eb + 1])
 			len = mtd->erasesize - offs;
 		else {
-			err = erase_eraseblock(eb + 1);
+			err = erase_eraseblock(mtd, eb + 1);
 			if (err)
 				return err;
 			offsets[eb + 1] = 0;
diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c
index 9667bf5..642f958 100644
--- a/drivers/mtd/tests/mtd_subpagetest.c
+++ b/drivers/mtd/tests/mtd_subpagetest.c
@@ -26,6 +26,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include "mtd_tests.h"
 
 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
 
@@ -69,32 +70,6 @@ static inline void clear_data(unsigned char *buf, size_t len)
 	memset(buf, 0, len);
 }
 
-static int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int erase_whole_device(void)
 {
 	int err;
@@ -104,7 +79,7 @@ static int erase_whole_device(void)
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
-		err = erase_eraseblock(i);
+		err = erase_eraseblock(mtd, i);
 		if (err)
 			return err;
 		cond_resched();
diff --git a/drivers/mtd/tests/mtd_tests.h b/drivers/mtd/tests/mtd_tests.h
new file mode 100644
index 0000000..b590c69
--- /dev/null
+++ b/drivers/mtd/tests/mtd_tests.h
@@ -0,0 +1,60 @@
+/*
+ * Derived from the code which has
+ * Copyright (C) 2006-2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __MTD_TESTS_H__
+#define __MTD_TESTS_H__
+
+#include <linux/mtd/mtd.h>
+
+int multiblock_erase(struct mtd_info *mtd, int ebnum, int blocks)
+{
+	int err;
+	struct erase_info ei;
+	loff_t addr = ebnum * mtd->erasesize;
+
+	memset(&ei, 0, sizeof(struct erase_info));
+	ei.mtd  = mtd;
+	ei.addr = addr;
+	ei.len  = mtd->erasesize * blocks;
+
+	err = mtd_erase(mtd, &ei);
+	if (err) {
+		pr_info("error %d while erasing EB %d, blocks %d\n",
+			       err, ebnum, blocks);
+		return err;
+	}
+
+	if (ei.state == MTD_ERASE_FAILED) {
+		pr_info("some erase error occurred at EB %d,"
+		       "blocks %d\n", ebnum, blocks);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+int erase_eraseblock(struct mtd_info *mtd, int ebnum)
+{
+	return multiblock_erase(mtd, ebnum, 1);
+}
+
+#endif /* __MTD_TESTS_H__ */
+
diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c
index b65861b..31c2eaf 100644
--- a/drivers/mtd/tests/mtd_torturetest.c
+++ b/drivers/mtd/tests/mtd_torturetest.c
@@ -30,7 +30,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-
+#include "mtd_tests.h"
 #define PRINT_PREF KERN_INFO "mtd_torturetest: "
 #define RETRIES 3
 
@@ -92,35 +92,6 @@ static inline void stop_timing(void)
 }
 
 /*
- * Erase eraseblock number @ebnum.
- */
-static inline int erase_eraseblock(int ebnum)
-{
-	int err;
-	struct erase_info ei;
-	loff_t addr = ebnum * mtd->erasesize;
-
-	memset(&ei, 0, sizeof(struct erase_info));
-	ei.mtd  = mtd;
-	ei.addr = addr;
-	ei.len  = mtd->erasesize;
-
-	err = mtd_erase(mtd, &ei);
-	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
-		return err;
-	}
-
-	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-/*
  * Check that the contents of eraseblock number @enbum is equivalent to the
  * @buf buffer.
  */
@@ -316,7 +287,7 @@ static int __init tort_init(void)
 		for (i = eb; i < eb + ebcnt; i++) {
 			if (bad_ebs[i - eb])
 				continue;
-			err = erase_eraseblock(i);
+			err = erase_eraseblock(mtd, i);
 			if (err)
 				goto out;
 			cond_resched();
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:28:47 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 19:58:47 +0530
Subject: [PATCH 2/8] mtd_pagetest: Replace printk with pr_{info,crit}
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFA1F.50206@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_pagetest.c |  152 +++++++++++++++++++-------------------
 1 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c
index 2a09405..12f0a2e 100644
--- a/drivers/mtd/tests/mtd_pagetest.c
+++ b/drivers/mtd/tests/mtd_pagetest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -29,8 +31,6 @@
 #include <linux/sched.h>
 #include "mtd_tests.h"
 
-#define PRINT_PREF KERN_INFO "mtd_pagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -77,7 +77,7 @@ static int write_eraseblock(int ebnum)
 	cond_resched();
 	err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
 	if (err || written != mtd->erasesize)
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr);
 
 	return err;
@@ -106,7 +106,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr0);
 			return err;
 		}
@@ -114,7 +114,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)(addrn - bufsize));
 			return err;
 		}
@@ -123,12 +123,12 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr);
 			break;
 		}
 		if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_info("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -141,7 +141,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr0);
 			return err;
 		}
@@ -149,7 +149,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)(addrn - bufsize));
 			return err;
 		}
@@ -158,14 +158,14 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err;
 		}
 		memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);
 		set_random_data(boundary + pgsize, pgsize);
 		if (memcmp(twopages, boundary, bufsize)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_info("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -181,10 +181,10 @@ static int crosstest(void)
 	loff_t addr, addr0, addrn;
 	unsigned char *pp1, *pp2, *pp3, *pp4;
 
-	printk(PRINT_PREF "crosstest\n");
+	pr_info("crosstest\n");
 	pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
 	if (!pp1) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 	pp2 = pp1 + pgsize;
@@ -206,7 +206,7 @@ static int crosstest(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -218,7 +218,7 @@ static int crosstest(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -226,12 +226,12 @@ static int crosstest(void)
 
 	/* Read first page to pp2 */
 	addr = addr0;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp2);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -239,12 +239,12 @@ static int crosstest(void)
 
 	/* Read last page to pp3 */
 	addr = addrn - pgsize;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp3);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -252,25 +252,25 @@ static int crosstest(void)
 
 	/* Read first page again to pp4 */
 	addr = addr0;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp4);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
 	}
 
 	/* pp2 and pp4 should be the same */
-	printk(PRINT_PREF "verifying pages read at %#llx match\n",
+	pr_info("verifying pages read at %#llx match\n",
 	       (long long)addr0);
 	if (memcmp(pp2, pp4, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_info("verify failed!\n");
 		errcnt += 1;
 	} else if (!err)
-		printk(PRINT_PREF "crosstest ok\n");
+		pr_info("crosstest ok\n");
 	kfree(pp1);
 	return err;
 }
@@ -282,7 +282,7 @@ static int erasecrosstest(void)
 	loff_t addr0;
 	char *readbuf = twopages;
 
-	printk(PRINT_PREF "erasecrosstest\n");
+	pr_info("erasecrosstest\n");
 
 	ebnum = 0;
 	addr0 = 0;
@@ -295,79 +295,79 @@ static int erasecrosstest(void)
 	while (ebnum2 && bbt[ebnum2])
 		ebnum2 -= 1;
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	memset(readbuf, 0, pgsize);
 	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+	pr_info("verifying 1st page of block %d\n", ebnum);
 	if (memcmp(writebuf, readbuf, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_info("verify failed!\n");
 		errcnt += 1;
 		return -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum2);
+	pr_info("erasing block %d\n", ebnum2);
 	err = erase_eraseblock(mtd, ebnum2);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	memset(readbuf, 0, pgsize);
 	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+	pr_info("verifying 1st page of block %d\n", ebnum);
 	if (memcmp(writebuf, readbuf, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_info("verify failed!\n");
 		errcnt += 1;
 		return -1;
 	}
 
 	if (!err)
-		printk(PRINT_PREF "erasecrosstest ok\n");
+		pr_info("erasecrosstest ok\n");
 	return err;
 }
 
@@ -377,7 +377,7 @@ static int erasetest(void)
 	int err = 0, i, ebnum, ok = 1;
 	loff_t addr0;
 
-	printk(PRINT_PREF "erasetest\n");
+	pr_info("erasetest\n");
 
 	ebnum = 0;
 	addr0 = 0;
@@ -386,40 +386,40 @@ static int erasetest(void)
 		ebnum += 1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(mtd, ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	err = mtd_read(mtd, addr0, pgsize, &read, twopages);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_info("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n",
+	pr_info("verifying 1st page of block %d is all 0xff\n",
 	       ebnum);
 	for (i = 0; i < pgsize; ++i)
 		if (twopages[i] != 0xff) {
-			printk(PRINT_PREF "verifying all 0xff failed at %d\n",
+			pr_info("verifying all 0xff failed at %d\n",
 			       i);
 			errcnt += 1;
 			ok = 0;
@@ -427,7 +427,7 @@ static int erasetest(void)
 		}
 
 	if (ok && !err)
-		printk(PRINT_PREF "erasetest ok\n");
+		pr_info("erasetest ok\n");
 
 	return err;
 }
@@ -439,7 +439,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -449,18 +449,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -470,26 +470,26 @@ static int __init mtd_pagetest_init(void)
 	uint64_t tmp;
 	uint32_t i;
 
-	printk(KERN_INFO "\n");
-	printk(KERN_INFO "=================================================\n");
+
+	printk(KERN_INFO "\n=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -499,7 +499,7 @@ static int __init mtd_pagetest_init(void)
 	pgcnt = mtd->erasesize / mtd->writesize;
 	pgsize = mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -509,17 +509,17 @@ static int __init mtd_pagetest_init(void)
 	bufsize = pgsize * 2;
 	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	twopages = kmalloc(bufsize, GFP_KERNEL);
 	if (!twopages) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	boundary = kmalloc(bufsize, GFP_KERNEL);
 	if (!boundary) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -528,7 +528,7 @@ static int __init mtd_pagetest_init(void)
 		goto out;
 
 	/* Erase all eraseblocks */
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -537,11 +537,11 @@ static int __init mtd_pagetest_init(void)
 			goto out;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 
 	/* Write all eraseblocks */
 	simple_srand(1);
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -549,14 +549,14 @@ static int __init mtd_pagetest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(1);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -564,10 +564,10 @@ static int __init mtd_pagetest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = crosstest();
 	if (err)
@@ -581,7 +581,7 @@ static int __init mtd_pagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 out:
 
 	kfree(bbt);
@@ -590,7 +590,7 @@ out:
 	kfree(writebuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:29:31 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 19:59:31 +0530
Subject: [PATCH 3/8] mtd_torturetest: Replace printk with pr_{info,crit}
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFA4B.6040508@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_torturetest.c |   73 ++++++++++++++++++-----------------
 1 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c
index 31c2eaf..f07d4aa 100644
--- a/drivers/mtd/tests/mtd_torturetest.c
+++ b/drivers/mtd/tests/mtd_torturetest.c
@@ -23,6 +23,8 @@
  * damage caused by this program.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -31,7 +33,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include "mtd_tests.h"
-#define PRINT_PREF KERN_INFO "mtd_torturetest: "
+
 #define RETRIES 3
 
 static int eb = 8;
@@ -110,40 +112,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
 retry:
 	err = mtd_read(mtd, addr, len, &read, check_buf);
 	if (mtd_is_bitflip(err))
-		printk(PRINT_PREF "single bit flip occurred at EB %d "
+		pr_info("single bit flip occurred at EB %d "
 		       "MTD reported that it was fixed.\n", ebnum);
 	else if (err) {
-		printk(PRINT_PREF "error %d while reading EB %d, "
+		pr_info("error %d while reading EB %d, "
 		       "read %zd\n", err, ebnum, read);
 		return err;
 	}
 
 	if (read != len) {
-		printk(PRINT_PREF "failed to read %zd bytes from EB %d, "
+		pr_info("failed to read %zd bytes from EB %d, "
 		       "read only %zd, but no error reported\n",
 		       len, ebnum, read);
 		return -EIO;
 	}
 
 	if (memcmp(buf, check_buf, len)) {
-		printk(PRINT_PREF "read wrong data from EB %d\n", ebnum);
+		pr_info("read wrong data from EB %d\n", ebnum);
 		report_corrupt(check_buf, buf);
 
 		if (retries++ < RETRIES) {
 			/* Try read again */
 			yield();
-			printk(PRINT_PREF "re-try reading data from EB %d\n",
+			pr_info("re-try reading data from EB %d\n",
 			       ebnum);
 			goto retry;
 		} else {
-			printk(PRINT_PREF "retried %d times, still errors, "
+			pr_info("retried %d times, still errors, "
 			       "give-up\n", RETRIES);
 			return -EINVAL;
 		}
 	}
 
 	if (retries != 0)
-		printk(PRINT_PREF "only attempt number %d was OK (!!!)\n",
+		pr_info("only attempt number %d was OK (!!!)\n",
 		       retries);
 
 	return 0;
@@ -162,12 +164,12 @@ static inline int write_pattern(int ebnum, void *buf)
 	}
 	err = mtd_write(mtd, addr, len, &written, buf);
 	if (err) {
-		printk(PRINT_PREF "error %d while writing EB %d, written %zd"
+		pr_info("error %d while writing EB %d, written %zd"
 		      " bytes\n", err, ebnum, written);
 		return err;
 	}
 	if (written != len) {
-		printk(PRINT_PREF "written only %zd bytes of %zd, but no error"
+		pr_info("written only %zd bytes of %zd, but no error"
 		       " reported\n", written, len);
 		return -EIO;
 	}
@@ -180,66 +182,65 @@ static int __init tort_init(void)
 	int err = 0, i, infinite = !cycles_count;
 	int bad_ebs[ebcnt];
 
-	printk(KERN_INFO "\n");
-	printk(KERN_INFO "=================================================\n");
-	printk(PRINT_PREF "Warning: this program is trying to wear out your "
+	printk(KERN_INFO "\n=================================================\n");
+	pr_info("Warning: this program is trying to wear out your "
 	       "flash, stop it if this is not wanted.\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
-	printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
+	pr_info("MTD device: %d\n", dev);
+	pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n",
 	       ebcnt, eb, eb + ebcnt - 1, dev);
 	if (pgcnt)
-		printk(PRINT_PREF "torturing just %d pages per eraseblock\n",
+		pr_info("torturing just %d pages per eraseblock\n",
 			pgcnt);
-	printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled");
+	pr_info("write verify %s\n", check ? "enabled" : "disabled");
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
 		pgsize = mtd->writesize;
 
 	if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) {
-		printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt);
+		pr_info("error: invalid pgcnt value %d\n", pgcnt);
 		goto out_mtd;
 	}
 
 	err = -ENOMEM;
 	patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_5A5) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out_mtd;
 	}
 
 	patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_A5A) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out_patt_5A5;
 	}
 
 	patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_FF) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out_patt_A5A;
 	}
 
 	check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!check_buf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out_patt_FF;
 	}
 
@@ -266,13 +267,13 @@ static int __init tort_init(void)
 			err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize);
 
 			if (err < 0) {
-				printk(PRINT_PREF "block_isbad() returned %d "
+				pr_info("block_isbad() returned %d "
 				       "for EB %d\n", err, i);
 				goto out;
 			}
 
 			if (err) {
-				printk("EB %d is bad. Skip it.\n", i);
+				pr_info("EB %d is bad. Skip it.\n", i);
 				bad_ebs[i - eb] = 1;
 			}
 		}
@@ -300,7 +301,7 @@ static int __init tort_init(void)
 					continue;
 				err = check_eraseblock(i, patt_FF);
 				if (err) {
-					printk(PRINT_PREF "verify failed"
+					pr_info("verify failed"
 					       " for 0xFF... pattern\n");
 					goto out;
 				}
@@ -333,7 +334,7 @@ static int __init tort_init(void)
 					patt = patt_A5A;
 				err = check_eraseblock(i, patt);
 				if (err) {
-					printk(PRINT_PREF "verify failed for %s"
+					pr_info("verify failed for %s"
 					       " pattern\n",
 					       ((eb + erase_cycles) & 1) ?
 					       "0x55AA55..." : "0xAA55AA...");
@@ -351,7 +352,7 @@ static int __init tort_init(void)
 			stop_timing();
 			ms = (finish.tv_sec - start.tv_sec) * 1000 +
 			     (finish.tv_usec - start.tv_usec) / 1000;
-			printk(PRINT_PREF "%08u erase cycles done, took %lu "
+			pr_info("%08u erase cycles done, took %lu "
 			       "milliseconds (%lu seconds)\n",
 			       erase_cycles, ms, ms / 1000);
 			start_timing();
@@ -362,7 +363,7 @@ static int __init tort_init(void)
 	}
 out:
 
-	printk(PRINT_PREF "finished after %u erase cycles\n",
+	pr_info("finished after %u erase cycles\n",
 	       erase_cycles);
 	kfree(check_buf);
 out_patt_FF:
@@ -374,7 +375,7 @@ out_patt_5A5:
 out_mtd:
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred during torturing\n", err);
+		pr_info("error %d occurred during torturing\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
@@ -412,9 +413,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
 			       &bits) >= 0)
 			pages++;
 
-	printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n",
+	pr_info("verify fails on %d pages, %d bytes/%d bits\n",
 	       pages, bytes, bits);
-	printk(PRINT_PREF "The following is a list of all differences between"
+	pr_info("The following is a list of all differences between"
 	       " what was read from flash and what was expected\n");
 
 	for (i = 0; i < check_len; i += pgsize) {
@@ -428,7 +429,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
 		printk("-------------------------------------------------------"
 		       "----------------------------------\n");
 
-		printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify,"
+		pr_info("Page %zd has %d bytes/%d bits failing verify,"
 		       " starting at offset 0x%x\n",
 		       (mtd->erasesize - check_len + i) / pgsize,
 		       bytes, bits, first);
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:30:49 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 20:00:49 +0530
Subject: [PATCH 4/8] mtd_subpagetest: Replace printk with pr_info
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFA99.7000106@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_subpagetest.c |  118 +++++++++++++++++-----------------
 1 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c
index 642f958..06df151 100644
--- a/drivers/mtd/tests/mtd_subpagetest.c
+++ b/drivers/mtd/tests/mtd_subpagetest.c
@@ -19,6 +19,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -28,8 +30,6 @@
 #include <linux/sched.h>
 #include "mtd_tests.h"
 
-#define PRINT_PREF KERN_INFO "mtd_subpagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -75,7 +75,7 @@ static int erase_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -84,7 +84,7 @@ static int erase_whole_device(void)
 			return err;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -97,11 +97,11 @@ static int write_eraseblock(int ebnum)
 	set_random_data(writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr);
 		if (written != subpgsize) {
-			printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-			printk(PRINT_PREF "  written: %#zx\n", written);
+			pr_info("  write size: %#x\n", subpgsize);
+			pr_info("  written: %#zx\n", written);
 		}
 		return err ? err : -1;
 	}
@@ -111,11 +111,11 @@ static int write_eraseblock(int ebnum)
 	set_random_data(writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr);
 		if (written != subpgsize) {
-			printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-			printk(PRINT_PREF "  written: %#zx\n", written);
+			pr_info("  write size: %#x\n", subpgsize);
+			pr_info("  written: %#zx\n", written);
 		}
 		return err ? err : -1;
 	}
@@ -135,12 +135,12 @@ static int write_eraseblock2(int ebnum)
 		set_random_data(writebuf, subpgsize * k);
 		err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
 		if (unlikely(err || written != subpgsize * k)) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_info("error: write failed at %#llx\n",
 			       (long long)addr);
 			if (written != subpgsize) {
-				printk(PRINT_PREF "  write size: %#x\n",
+				pr_info("  write size: %#x\n",
 				       subpgsize * k);
-				printk(PRINT_PREF "  written: %#08zx\n",
+				pr_info("  written: %#08zx\n",
 				       written);
 			}
 			return err ? err : -1;
@@ -173,23 +173,23 @@ static int verify_eraseblock(int ebnum)
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
 		if (mtd_is_bitflip(err) && read == subpgsize) {
-			printk(PRINT_PREF "ECC correction at %#llx\n",
+			pr_info("ECC correction at %#llx\n",
 			       (long long)addr);
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err ? err : -1;
 		}
 	}
 	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_info("error: verify failed at %#llx\n",
 		       (long long)addr);
-		printk(PRINT_PREF "------------- written----------------\n");
+		pr_info("------------- written----------------\n");
 		print_subpage(writebuf);
-		printk(PRINT_PREF "------------- read ------------------\n");
+		pr_info("------------- read ------------------\n");
 		print_subpage(readbuf);
-		printk(PRINT_PREF "-------------------------------------\n");
+		pr_info("-------------------------------------\n");
 		errcnt += 1;
 	}
 
@@ -200,23 +200,23 @@ static int verify_eraseblock(int ebnum)
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
 		if (mtd_is_bitflip(err) && read == subpgsize) {
-			printk(PRINT_PREF "ECC correction at %#llx\n",
+			pr_info("ECC correction at %#llx\n",
 			       (long long)addr);
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err ? err : -1;
 		}
 	}
 	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_info("error: verify failed at %#llx\n",
 		       (long long)addr);
-		printk(PRINT_PREF "------------- written----------------\n");
+		pr_info("------------- written----------------\n");
 		print_subpage(writebuf);
-		printk(PRINT_PREF "------------- read ------------------\n");
+		pr_info("------------- read ------------------\n");
 		print_subpage(readbuf);
-		printk(PRINT_PREF "-------------------------------------\n");
+		pr_info("-------------------------------------\n");
 		errcnt += 1;
 	}
 
@@ -237,17 +237,17 @@ static int verify_eraseblock2(int ebnum)
 		err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
 		if (unlikely(err || read != subpgsize * k)) {
 			if (mtd_is_bitflip(err) && read == subpgsize * k) {
-				printk(PRINT_PREF "ECC correction at %#llx\n",
+				pr_info("ECC correction at %#llx\n",
 				       (long long)addr);
 				err = 0;
 			} else {
-				printk(PRINT_PREF "error: read failed at "
+				pr_info("error: read failed at "
 				       "%#llx\n", (long long)addr);
 				return err ? err : -1;
 			}
 		}
 		if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_info("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -270,17 +270,17 @@ static int verify_eraseblock_ff(int ebnum)
 		err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 		if (unlikely(err || read != subpgsize)) {
 			if (mtd_is_bitflip(err) && read == subpgsize) {
-				printk(PRINT_PREF "ECC correction at %#llx\n",
+				pr_info("ECC correction at %#llx\n",
 				       (long long)addr);
 				err = 0;
 			} else {
-				printk(PRINT_PREF "error: read failed at "
+				pr_info("error: read failed at "
 				       "%#llx\n", (long long)addr);
 				return err ? err : -1;
 			}
 		}
 		if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-			printk(PRINT_PREF "error: verify 0xff failed at "
+			pr_info("error: verify 0xff failed at "
 			       "%#llx\n", (long long)addr);
 			errcnt += 1;
 		}
@@ -295,7 +295,7 @@ static int verify_all_eraseblocks_ff(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "verifying all eraseblocks for 0xff\n");
+	pr_info("verifying all eraseblocks for 0xff\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -303,10 +303,10 @@ static int verify_all_eraseblocks_ff(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -317,7 +317,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -327,18 +327,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -352,22 +352,22 @@ static int __init mtd_subpagetest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
 		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -377,7 +377,7 @@ static int __init mtd_subpagetest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, subpage size %u, count of eraseblocks %u, "
 	       "pages per eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -387,12 +387,12 @@ static int __init mtd_subpagetest_init(void)
 	bufsize = subpgsize * 32;
 	writebuf = kmalloc(bufsize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	readbuf = kmalloc(bufsize, GFP_KERNEL);
 	if (!readbuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -404,7 +404,7 @@ static int __init mtd_subpagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	simple_srand(1);
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -413,13 +413,13 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	simple_srand(1);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -427,10 +427,10 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = erase_whole_device();
 	if (err)
@@ -442,7 +442,7 @@ static int __init mtd_subpagetest_init(void)
 
 	/* Write all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -450,14 +450,14 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -465,10 +465,10 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = erase_whole_device();
 	if (err)
@@ -478,7 +478,7 @@ static int __init mtd_subpagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 
 out:
 	kfree(bbt);
@@ -486,7 +486,7 @@ out:
 	kfree(writebuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:31:28 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 20:01:28 +0530
Subject: [PATCH 5/8] mtd_stresstest: Replace printk with pr_{info,crit}
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFAC0.80100@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_stresstest.c |   40 ++++++++++++++++++------------------
 1 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index 87e2e05..1ceacfa 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -30,8 +32,6 @@
 #include <linux/random.h>
 #include "mtd_tests.h"
 
-#define PRINT_PREF KERN_INFO "mtd_stresstest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -89,7 +89,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -112,7 +112,7 @@ static int do_read(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (unlikely(err || read != len)) {
-		printk(PRINT_PREF "error: read failed at 0x%llx\n",
+		pr_info("error: read failed at 0x%llx\n",
 		       (long long)addr);
 		if (!err)
 			err = -EINVAL;
@@ -149,7 +149,7 @@ static int do_write(void)
 	addr = eb * mtd->erasesize + offs;
 	err = mtd_write(mtd, addr, len, &written, writebuf);
 	if (unlikely(err || written != len)) {
-		printk(PRINT_PREF "error: write failed at 0x%llx\n",
+		pr_info("error: write failed at 0x%llx\n",
 		       (long long)addr);
 		if (!err)
 			err = -EINVAL;
@@ -178,21 +178,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		return 0;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -206,22 +206,22 @@ static int __init mtd_stresstest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -232,14 +232,14 @@ static int __init mtd_stresstest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
 	       pgsize, ebcnt, pgcnt, mtd->oobsize);
 
 	if (ebcnt < 2) {
-		printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
+		pr_info("error: need at least 2 eraseblocks\n");
 		err = -ENOSPC;
 		goto out_put_mtd;
 	}
@@ -252,7 +252,7 @@ static int __init mtd_stresstest_init(void)
 	writebuf = vmalloc(bufsize);
 	offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL);
 	if (!readbuf || !writebuf || !offsets) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	for (i = 0; i < ebcnt; i++)
@@ -265,16 +265,16 @@ static int __init mtd_stresstest_init(void)
 		goto out;
 
 	/* Do operations */
-	printk(PRINT_PREF "doing operations\n");
+	pr_info("doing operations\n");
 	for (op = 0; op < count; op++) {
 		if ((op & 1023) == 0)
-			printk(PRINT_PREF "%d operations done\n", op);
+			pr_info("%d operations done\n", op);
 		err = do_operation();
 		if (err)
 			goto out;
 		cond_resched();
 	}
-	printk(PRINT_PREF "finished, %d operations done\n", op);
+	pr_info("finished, %d operations done\n", op);
 
 out:
 	kfree(offsets);
@@ -284,7 +284,7 @@ out:
 out_put_mtd:
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:32:01 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 20:02:01 +0530
Subject: [PATCH 6/8] mtd_speedtest: Replace printk with pr_{info,crit}
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFAE1.40809@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_speedtest.c |   80 ++++++++++++++++++------------------
 1 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index e3518b4..0ffa026 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -29,8 +31,6 @@
 #include <linux/random.h>
 #include "mtd_tests.h"
 
-#define PRINT_PREF KERN_INFO "mtd_speedtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -82,7 +82,7 @@ static int write_eraseblock(int ebnum)
 
 	err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf);
 	if (err || written != mtd->erasesize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n", addr);
+		pr_info("error: write failed at %#llx\n", addr);
 		if (!err)
 			err = -EINVAL;
 	}
@@ -100,7 +100,7 @@ static int write_eraseblock_by_page(int ebnum)
 	for (i = 0; i < pgcnt; i++) {
 		err = mtd_write(mtd, addr, pgsize, &written, buf);
 		if (err || written != pgsize) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_info("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -123,7 +123,7 @@ static int write_eraseblock_by_2pages(int ebnum)
 	for (i = 0; i < n; i++) {
 		err = mtd_write(mtd, addr, sz, &written, buf);
 		if (err || written != sz) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_info("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -135,7 +135,7 @@ static int write_eraseblock_by_2pages(int ebnum)
 	if (pgcnt % 2) {
 		err = mtd_write(mtd, addr, pgsize, &written, buf);
 		if (err || written != pgsize) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_info("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -156,7 +156,7 @@ static int read_eraseblock(int ebnum)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != mtd->erasesize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n", addr);
+		pr_info("error: read failed at %#llx\n", addr);
 		if (!err)
 			err = -EINVAL;
 	}
@@ -177,7 +177,7 @@ static int read_eraseblock_by_page(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -203,7 +203,7 @@ static int read_eraseblock_by_2pages(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != sz) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -218,7 +218,7 @@ static int read_eraseblock_by_2pages(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -235,7 +235,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -269,21 +269,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		goto out;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 out:
 	goodebcnt = ebcnt - bad;
 	return 0;
@@ -299,25 +299,25 @@ static int __init mtd_speedtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
 	if (count)
-		printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count);
+		pr_info("MTD device: %d    count: %d\n", dev, count);
 	else
-		printk(PRINT_PREF "MTD device: %d\n", dev);
+		pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -328,7 +328,7 @@ static int __init mtd_speedtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -340,7 +340,7 @@ static int __init mtd_speedtest_init(void)
 	err = -ENOMEM;
 	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -355,7 +355,7 @@ static int __init mtd_speedtest_init(void)
 		goto out;
 
 	/* Write all eraseblocks, 1 eraseblock at a time */
-	printk(PRINT_PREF "testing eraseblock write speed\n");
+	pr_info("testing eraseblock write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -367,10 +367,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed);
+	pr_info("eraseblock write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 1 eraseblock at a time */
-	printk(PRINT_PREF "testing eraseblock read speed\n");
+	pr_info("testing eraseblock read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -382,14 +382,14 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed);
+	pr_info("eraseblock read speed is %ld KiB/s\n", speed);
 
 	err = erase_whole_device();
 	if (err)
 		goto out;
 
 	/* Write all eraseblocks, 1 page at a time */
-	printk(PRINT_PREF "testing page write speed\n");
+	pr_info("testing page write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -401,10 +401,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed);
+	pr_info("page write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 1 page at a time */
-	printk(PRINT_PREF "testing page read speed\n");
+	pr_info("testing page read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -416,14 +416,14 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed);
+	pr_info("page read speed is %ld KiB/s\n", speed);
 
 	err = erase_whole_device();
 	if (err)
 		goto out;
 
 	/* Write all eraseblocks, 2 pages at a time */
-	printk(PRINT_PREF "testing 2 page write speed\n");
+	pr_info("testing 2 page write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -435,10 +435,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed);
+	pr_info("2 page write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 2 pages at a time */
-	printk(PRINT_PREF "testing 2 page read speed\n");
+	pr_info("testing 2 page read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -450,10 +450,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed);
+	pr_info("2 page read speed is %ld KiB/s\n", speed);
 
 	/* Erase all eraseblocks */
-	printk(PRINT_PREF "Testing erase speed\n");
+	pr_info("Testing erase speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -465,12 +465,12 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed);
+	pr_info("erase speed is %ld KiB/s\n", speed);
 
 	/* Multi-block erase all eraseblocks */
 	for (k = 1; k < 7; k++) {
 		blocks = 1 << k;
-		printk(PRINT_PREF "Testing %dx multi-block erase speed\n",
+		pr_info("Testing %dx multi-block erase speed\n",
 		       blocks);
 		start_timing();
 		for (i = 0; i < ebcnt; ) {
@@ -489,16 +489,16 @@ static int __init mtd_speedtest_init(void)
 		}
 		stop_timing();
 		speed = calc_speed();
-		printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n",
+		pr_info("%dx multi-block erase speed is %ld KiB/s\n",
 		       blocks, speed);
 	}
-	printk(PRINT_PREF "finished\n");
+	pr_info("finished\n");
 out:
 	kfree(iobuf);
 	kfree(bbt);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:33:15 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 20:03:15 +0530
Subject: [PATCH 7/8] mtd_readtest: Replace printk with pr_info
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFB2B.50109@gmail.com>

Remove PRINT_PREF macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_readtest.c |   42 +++++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 121aba1..b7cb99b5 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,8 +29,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_readtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -56,7 +56,7 @@ static int read_eraseblock_by_page(int ebnum)
 		if (ret == -EUCLEAN)
 			ret = 0;
 		if (ret || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_info("error: read failed at %#llx\n",
 			       (long long)addr);
 			if (!err)
 				err = ret;
@@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum)
 			ret = mtd_read_oob(mtd, addr, &ops);
 			if ((ret && !mtd_is_bitflip(ret)) ||
 					ops.oobretlen != mtd->oobsize) {
-				printk(PRINT_PREF "error: read oob failed at "
+				pr_info("error: read oob failed at "
 						  "%#llx\n", (long long)addr);
 				if (!err)
 					err = ret;
@@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum)
 	char line[128];
 	int pg, oob;
 
-	printk(PRINT_PREF "dumping eraseblock %d\n", ebnum);
+	pr_info("dumping eraseblock %d\n", ebnum);
 	n = mtd->erasesize;
 	for (i = 0; i < n;) {
 		char *p = line;
@@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum)
 	}
 	if (!mtd->oobsize)
 		return;
-	printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum);
+	pr_info("dumping oob from eraseblock %d\n", ebnum);
 	n = mtd->oobsize;
 	for (pg = 0, i = 0; pg < pgcnt; pg++)
 		for (oob = 0; oob < n;) {
@@ -134,7 +134,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		return 0;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: Cannot get MTD device\n");
+		pr_info("error: Cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void)
 	err = -ENOMEM;
 	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf1) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void)
 		goto out;
 
 	/* Read all eraseblocks 1 page at a time */
-	printk(PRINT_PREF "testing page read\n");
+	pr_info("testing page read\n");
 	for (i = 0; i < ebcnt; ++i) {
 		int ret;
 
@@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void)
 	}
 
 	if (err)
-		printk(PRINT_PREF "finished with errors\n");
+		pr_info("finished with errors\n");
 	else
-		printk(PRINT_PREF "finished\n");
+		pr_info("finished\n");
 
 out:
 
@@ -246,7 +246,7 @@ out:
 	kfree(bbt);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Tue Oct  2 10:33:45 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Tue, 02 Oct 2012 20:03:45 +0530
Subject: [PATCH 8/8] mtd_nandbiterrs: Replace msg macro with pr_info
In-Reply-To: <506AF985.30104@gmail.com>
References: <506AF985.30104@gmail.com>
Message-ID: <506AFB49.6010109@gmail.com>

Remove msg macro and use pr_fmt to add the prefix

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_nandbiterrs.c |   68 +++++++++++++++++-----------------
 1 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c
index 072fc43..b94c4ac 100644
--- a/drivers/mtd/tests/mtd_nandbiterrs.c
+++ b/drivers/mtd/tests/mtd_nandbiterrs.c
@@ -39,6 +39,9 @@
  * this program; see the file COPYING. If not, write to the Free Software
  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -48,8 +51,6 @@
 #include <linux/slab.h>
 #include "mtd_tests.h"
 
-#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
-
 static int dev;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -105,11 +106,11 @@ static int write_page(int log)
 	size_t written;
 
 	if (log)
-		msg("write_page\n");
+		pr_info("write_page\n");
 
 	err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);
 	if (err || written != mtd->writesize) {
-		msg("error: write failed at %#llx\n", (long long)offset);
+		pr_info("error: write failed at %#llx\n", (long long)offset);
 		if (!err)
 			err = -EIO;
 	}
@@ -124,7 +125,7 @@ static int rewrite_page(int log)
 	struct mtd_oob_ops ops;
 
 	if (log)
-		msg("rewrite page\n");
+		pr_info("rewrite page\n");
 
 	ops.mode      = MTD_OPS_RAW; /* No ECC */
 	ops.len       = mtd->writesize;
@@ -137,7 +138,7 @@ static int rewrite_page(int log)
 
 	err = mtd_write_oob(mtd, offset, &ops);
 	if (err || ops.retlen != mtd->writesize) {
-		msg("error: write_oob failed (%d)\n", err);
+		pr_info("error: write_oob failed (%d)\n", err);
 		if (!err)
 			err = -EIO;
 	}
@@ -154,7 +155,7 @@ static int read_page(int log)
 	struct mtd_ecc_stats oldstats;
 
 	if (log)
-		msg("read_page\n");
+		pr_info("read_page\n");
 
 	/* Saving last mtd stats */
 	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
@@ -164,7 +165,7 @@ static int read_page(int log)
 		err = mtd->ecc_stats.corrected - oldstats.corrected;
 
 	if (err < 0 || read != mtd->writesize) {
-		msg("error: read failed at %#llx\n", (long long)offset);
+		pr_info("error: read failed at %#llx\n", (long long)offset);
 		if (err >= 0)
 			err = -EIO;
 	}
@@ -178,11 +179,11 @@ static int verify_page(int log)
 	unsigned i, errs = 0;
 
 	if (log)
-		msg("verify_page\n");
+		pr_info("verify_page\n");
 
 	for (i = 0; i < mtd->writesize; i++) {
 		if (rbuffer[i] != hash(i+seed)) {
-			msg("Error: page offset %u, expected %02x, got %02x\n",
+			pr_info("Error: page offset %u, expected %02x, got %02x\n",
 				i, hash(i+seed), rbuffer[i]);
 			errs++;
 		}
@@ -207,13 +208,13 @@ static int insert_biterror(unsigned byte)
 		for (bit = 7; bit >= 0; bit--) {
 			if (CBIT(wbuffer[byte], bit)) {
 				BCLR(wbuffer[byte], bit);
-				msg("Inserted biterror @ %u/%u\n", byte, bit);
+				pr_info("Inserted biterror @ %u/%u\n", byte, bit);
 				return 0;
 			}
 		}
 		byte++;
 	}
-	msg("biterror: Failed to find a '1' bit\n");
+	pr_info("biterror: Failed to find a '1' bit\n");
 	return -EIO;
 }
 
@@ -225,7 +226,7 @@ static int incremental_errors_test(void)
 	unsigned i;
 	unsigned errs_per_subpage = 0;
 
-	msg("incremental biterrors test\n");
+	pr_info("incremental biterrors test\n");
 
 	for (i = 0; i < mtd->writesize; i++)
 		wbuffer[i] = hash(i+seed);
@@ -242,9 +243,9 @@ static int incremental_errors_test(void)
 
 		err = read_page(1);
 		if (err > 0)
-			msg("Read reported %d corrected bit errors\n", err);
+			pr_info("Read reported %d corrected bit errors\n", err);
 		if (err < 0) {
-			msg("After %d biterrors per subpage, read reported error %d\n",
+			pr_info("After %d biterrors per subpage, read reported error %d\n",
 				errs_per_subpage, err);
 			err = 0;
 			goto exit;
@@ -252,11 +253,11 @@ static int incremental_errors_test(void)
 
 		err = verify_page(1);
 		if (err) {
-			msg("ECC failure, read data is incorrect despite read success\n");
+			pr_info("ECC failure, read data is incorrect despite read success\n");
 			goto exit;
 		}
 
-		msg("Successfully corrected %d bit errors per subpage\n",
+		pr_info("Successfully corrected %d bit errors per subpage\n",
 			errs_per_subpage);
 
 		for (i = 0; i < subcount; i++) {
@@ -288,7 +289,7 @@ static int overwrite_test(void)
 
 	memset(bitstats, 0, sizeof(bitstats));
 
-	msg("overwrite biterrors test\n");
+	pr_info("overwrite biterrors test\n");
 
 	for (i = 0; i < mtd->writesize; i++)
 		wbuffer[i] = hash(i+seed);
@@ -306,18 +307,18 @@ static int overwrite_test(void)
 		err = read_page(0);
 		if (err >= 0) {
 			if (err >= MAXBITS) {
-				msg("Implausible number of bit errors corrected\n");
+				pr_info("Implausible number of bit errors corrected\n");
 				err = -EIO;
 				break;
 			}
 			bitstats[err]++;
 			if (err > max_corrected) {
 				max_corrected = err;
-				msg("Read reported %d corrected bit errors\n",
+				pr_info("Read reported %d corrected bit errors\n",
 					err);
 			}
 		} else { /* err < 0 */
-			msg("Read reported error %d\n", err);
+			pr_info("Read reported error %d\n", err);
 			err = 0;
 			break;
 		}
@@ -325,7 +326,7 @@ static int overwrite_test(void)
 		err = verify_page(0);
 		if (err) {
 			bitstats[max_corrected] = opno;
-			msg("ECC failure, read data is incorrect despite read success\n");
+			pr_info("ECC failure, read data is incorrect despite read success\n");
 			break;
 		}
 
@@ -334,9 +335,9 @@ static int overwrite_test(void)
 
 	/* At this point bitstats[0] contains the number of ops with no bit
 	 * errors, bitstats[1] the number of ops with 1 bit error, etc. */
-	msg("Bit error histogram (%d operations total):\n", opno);
+	pr_info("Bit error histogram (%d operations total):\n", opno);
 	for (i = 0; i < max_corrected; i++)
-		msg("Page reads with %3d corrected bit errors: %d\n",
+		pr_info("Page reads with %3d corrected bit errors: %d\n",
 			i, bitstats[i]);
 
 exit:
@@ -347,36 +348,35 @@ static int __init mtd_nandbiterrs_init(void)
 {
 	int err = 0;
 
-	msg("\n");
-	msg("==================================================\n");
-	msg("MTD device: %d\n", dev);
+	printk(KERN_INFO "\n==================================================\n");
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		msg("error: cannot get MTD device\n");
+		pr_info("error: cannot get MTD device\n");
 		goto exit_mtddev;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		msg("this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		err = -ENODEV;
 		goto exit_nand;
 	}
 
-	msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
+	pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
 		(unsigned long long)mtd->size, mtd->erasesize,
 		mtd->writesize, mtd->oobsize);
 
 	subsize  = mtd->writesize >> mtd->subpage_sft;
 	subcount = mtd->writesize / subsize;
 
-	msg("Device uses %d subpages of %d bytes\n", subcount, subsize);
+	pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);
 
 	offset     = page_offset * mtd->writesize;
 	eraseblock = mtd_div_by_eb(offset, mtd);
 
-	msg("Using page=%u, offset=%llu, eraseblock=%u\n",
+	pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",
 		page_offset, offset, eraseblock);
 
 	wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
@@ -409,8 +409,8 @@ static int __init mtd_nandbiterrs_init(void)
 		goto exit_error;
 
 	err = -EIO;
-	msg("finished successfully.\n");
-	msg("==================================================\n");
+	pr_info("finished successfully.\n");
+	printk(KERN_INFO "==================================================\n");
 
 exit_error:
 	kfree(rbuffer);
-- 
1.7.4.1




From Thomas.Betker at rohde-schwarz.com  Tue Oct  2 10:19:10 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Tue, 2 Oct 2012 16:19:10 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
Message-ID: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>

Hello all, 

I have encountered multiple times a deadlock between two JFFS2 threads:

INFO: task jffs2_gcd_mtd5:54 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
jffs2_gcd_mtd5  D c023be78     0    54      2 0x00000000
Backtrace:
Function entered at [<c023babc>] from [<c023c0c0>]  __schedule
Function entered at [<c023c03c>] from [<c023c140>]  schedule
Function entered at [<c023c0c4>] from [<c005ee64>]  io_schedule
 r6:c7942380 r5:c0414a50 r4:c541bd34 r3:00000001
Function entered at [<c005ee54>] from [<c023a328>]  sleep_on_page
Function entered at [<c023a2cc>] from [<c005ee44>]  __wait_on_bit_lock
Function entered at [<c005edd8>] from [<c005f3f0>]  __lock_page
 r6:c7411728 r5:00000083 r4:c034d720
Function entered at [<c005f2fc>] from [<c005f4b8>]  do_read_cache_page
Function entered at [<c005f498>] from [<c0108990>]  read_cache_page_async
Function entered at [<c0108968>] from [<c0105834>]  jffs2_gc_fetch_page
 r4:c74115f8 r3:c541be60
Function entered at [<c0104fa8>] from [<c01064e4>] 
jffs2_garbage_collect_live
Function entered at [<c0105e1c>] from [<c0107820>] 
jffs2_garbage_collect_pass
Function entered at [<c01076dc>] from [<c0033198>] 
jffs2_garbage_collect_thread
Function entered at [<c0033108>] from [<c001d5f0>]  kthread
 r7:00000013 r6:c001d5f0 r5:c0033108 r4:c79b9d84

INFO: task scp:158 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
scp             D c023be78     0   158    157 0x00000000
Backtrace:
Function entered at [<c023babc>] from [<c023c0c0>]  __schedule
Function entered at [<c023c03c>] from [<c023c314>]  schedule
Function entered at [<c023c2ec>] from [<c023afac>] 
schedule_preempt_disabled
 r4:c74115f8 r3:00000000
Function entered at [<c023ae3c>] from [<c023b0d4>]  __mutex_lock_slowpath
Function entered at [<c023b0c0>] from [<c00fd640>]  mutex_lock
 r4:c7411640 r3:00000001
Function entered at [<c00fd3e8>] from [<c005e53c>]  jffs2_write_begin
Function entered at [<c005e454>] from [<c0060110>] 
generic_file_buffered_write
Function entered at [<c005fce0>] from [<c00601ac>] 
__generic_file_aio_write
Function entered at [<c006015c>] from [<c0086a18>]  generic_file_aio_write
 r8:fffffdee r7:c54fbf10 r6:c54fbf70 r5:c54fbe90 r4:c54fd0c0
Function entered at [<c008696c>] from [<c00873a0>]  do_sync_write
 r8:00001000 r7:c54fbf70 r6:017969f8 r5:c54fd0c0 r4:00001000
Function entered at [<c00872e4>] from [<c0087624>]  vfs_write
 r8:00001000 r7:00000000 r6:00083000 r5:017969f8 r4:c54fd0c0
Function entered at [<c00875e0>] from [<c000dec0>]  sys_write
 r8:c000e044 r7:00000004 r6:0000a114 r5:00001000 r4:00000000

The target system is an SoC with a dual ARMv7 (Cortex-A9), and we are 
running the long-term 3.4.11 kernel (whose fs/jffs2/ seems to be pretty 
close to the latest mainline kernel). The deadlock occurred when using scp 
to copy files from a host system to the target system.

The GC thread hangs in lock_page(page), the write thread hangs in the 
first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:

jffs2_garbage_collect_live
    mutex_lock(&f->sem)                         (A)
    jffs2_garbage_collect_dnode [inlined]
        jffs2_gc_fetch_page
            read_cache_page_async
                do_read_cache_page
                    lock_page(page) [inlined]
                        __lock_page             (B) ***

jffs2_write_begin
    grab_cache_page_write_begin
        find_lock_page
            lock_page(page)                     (B)
    mutex_lock(&f->sem)                         (A) ***

I have manually analyzed the stacks and confirmed that both threads sit on 
the theme 'struct page'.

Is this a known problem? And more importantly, is there a solution for it?

Best regards,
Thomas Betker

-- 
Thomas Betker, Dept. 1GP1 
Rohde & Schwarz GmbH & Co. KG 
Postbox 80 14 69, 81614 Muenchen, Germany 



From richard at nod.at  Tue Oct  2 11:29:09 2012
From: richard at nod.at (Richard Weinberger)
Date: Tue,  2 Oct 2012 17:29:09 +0200
Subject: [PATCH] mtd-www: Add fastmap doc
Message-ID: <1349191749-5247-1-git-send-email-richard@nod.at>

Add documentation on fastmap to mtd-www.

Signed-off-by: Richard Weinberger <richard at nod.at>
---
 doc/ubi.xml | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/doc/ubi.xml b/doc/ubi.xml
index 6bea323..7fe01d0 100644
--- a/doc/ubi.xml
+++ b/doc/ubi.xml
@@ -46,6 +46,7 @@
 		</li>
 		</ol>
 	</li>
+	<li><a href="ubi.html#L_fastmap">Fastmap</a></li>
 	<li><a href="ubi.html#L_ubidoc">More documentation</a></li>
 </ol>
 
@@ -758,8 +759,12 @@ for detailed information.</p>
 <p>Unfortunately, UBI scales linearly in terms of flash size. UBI
 initialization time linearly depends on the number of physical eraseblocks on
 the flash. This means that the larger is the flash, the more time it takes for
-UBI to initialize (i.e., to attach the MTD device). The initialization time
-depends on the flash I/O speed and (slightly) on the CPU speed, because:</p>
+UBI to initialize (i.e., to attach the MTD device).
+Note: Starting with Linux v3.7 UBI offers an optional and experimental feature,
+called "fastmap", which allows attaching in nearly constant time,
+see <a href="ubi.html#L_fastmap">Fastmap</a>.
+The initialization time depends on the flash I/O speed and (slightly) on the
+CPU speed, because:</p>
 
 <ul>
 	<li>UBI scans the MTD device when attaching - it reads the erase EC and
@@ -1170,7 +1175,82 @@ means that all data has been written to the flash media), otherwise it selects
 the PEB with lower sequence number(<i>P<sub>1</sub></i>). Of course, UBI has to
 read the LEB contents in order to check the <code>CRC-32</code> checksum.</p>
 
-
+<h2><a name="L_fastmap">Fastmap</a></h2>
+<p>
+Fastmap is an experimental and optional UBI feature, which can be enabled
+by setting CONFIG_MTD_UBI_FASTMAP to 'y'.
+Once enabled UBI evaluates the module parameter
+"fm_autoconvert". If it is set to 1 (default is 0) UBI automatically enables
+fastmap for any attached image. This means UBI creates a new internal
+volume with the fastmap data such that next time the fast attach mode can be
+used.
+In the default configuration UBI will use the information stored in this
+fastmap volume to accelerate the attach procedure.
+If you want to test fastmap, set fm_autoconvert to 1 and attach a volume.</p>
+
+<h4><a name="L_fastmap_compat">Backwards compatibility</a></h4>
+<p>The fastmap on-disk data structure makes use of delete compatible volumes,
+therefore fastmap enabled images are fully backwards compatible with UBI
+implementaions which do not support fastmap. The kernel will remove the fastmap
+volumes and continue with scanning.
+This includes not only v3.6- but also v3.7+ with this option disabled.
+</p>
+
+<h4><a name="L_fastmap_tech">Technical design</a></h4>
+
+<p>A on-disk fastmap contains all information needed to attach the whole image,
+namely all erase counter values, a list of all PEBs and their state, a list of
+all volumes and their current EBA, ...
+To avoid too much writes of the fastmap it contains also a list of PEBs which
+may have changed and need a full scan while attaching.
+This list is called "fastmap pool" and has a fixed sized, 5% of the total
+amount of PEBs. Using this technique UBI needs to write the fastmap only if the
+pool contains no free PEBs. Otherwise it would have to write the fastmap each
+time when the EBA of a volume has changed.</p>
+
+<p>A fastmap consists of a super block (also known as anchor PEB) and payload
+data which can life on any PEB.
+The anchor PEB has to be located within the first 64 PEBs on the MTD device.
+It contains pointers to the remaining PEBs which carry the actual fastmap
+data. On modern NAND chips the whole fastmap fits into a single PEB.
+Hence, the anchor PEB points to itself.
+After loading the fastmap data, UBI attach information structure is created
+from it
+
+The attach process works as follows:
+<ol>
+	<li>UBI tries to find the fastmap anchor PEB,
+	if no anchor PEB was found UBI performs  traditional full scan</li>
+	<li>It follows the pointers stored in the anchor PEB and reads
+	the fastmap payload data</li>
+	<li>Then it performs a traditional scan only on PEBs in the pool
+	instead of all PEBs</li>
+</ol>
+If UBI detects that the used fastmap is invalid or corrupted it automatically
+falls back to scanning mode and performsa full scan.
+Using a CRC32 checksum and consistency checks of the internal UBI structures
+UBI is able to detect whether a fastmap is invalid or not.
+</p>
+
+<p>
+A fastmap is written to the devices each time the fastmap pool becomes full
+(no free PEBs are available), the volume layout changes or the image is
+detached. One may wonder why writing at detach time is needed.
+if UBI would not write a new fastmap at detach time all erase counter
+modifications since the last fastmap are lost.
+</p>
+
+<h4><a name="L_fastmap_overhead">Overhead</a></h4>
+<p>Is fastmap enabled UBI will reserve enough PEBs to carry two complete
+fastmaps. In practice on modern NAND chips two PEBs are reserved for fastmap.
+</p>
+<p>
+There is also some runtime overhead, to guarantee that the new fastmap is valid
+and conistent UBI has to take care that all IO which would cause EBA changes
+are blocked while attaching. Depending on flash Chip this can take up to one
+second. Therefore, fastmap makes only sense on fast and large flash devices
+where a full scan takes too long. E.g. On 4GiB NAND chips a full scan takes
+several seconds whereas a fast attach needs less than one second.</p>
 
 <h2><a name="L_ubidoc">More documentation</a></h2>
 
-- 
1.7.11.5



From dedekind1 at gmail.com  Tue Oct  2 12:11:09 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 02 Oct 2012 19:11:09 +0300
Subject: [GIT PULL] UBI changes for 3.7-rc1
In-Reply-To: <1349184941.2017.70.camel@sauron.fi.intel.com>
References: <1349184941.2017.70.camel@sauron.fi.intel.com>
Message-ID: <1349194269.2017.90.camel@sauron.fi.intel.com>

On Tue, 2012-10-02 at 16:35 +0300, Artem Bityutskiy wrote:
> Hi Linus,
> 
> please, pull UBI changes.
> 
> The following changes since commit 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d:
> 
>   Linux 3.6-rc4 (2012-09-01 10:39:58 -0700)
> 
> are available in the git repository at:

FYI, there will be the second pull request with another major
experimental UBI feature. I wanted to send it separately a bit later.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121002/4ccd9b5a/attachment.sig>

From joakim.tjernlund at transmode.se  Tue Oct  2 12:43:03 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Tue, 2 Oct 2012 18:43:03 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
Message-ID: <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>

linux-mtd-bounces at lists.infradead.org wrote on 2012/10/02 16:19:10:
>
> Hello all,
>
> I have encountered multiple times a deadlock between two JFFS2 threads:

[SNIP]

>
> The target system is an SoC with a dual ARMv7 (Cortex-A9), and we are
> running the long-term 3.4.11 kernel (whose fs/jffs2/ seems to be pretty
> close to the latest mainline kernel). The deadlock occurred when using scp
> to copy files from a host system to the target system.
>
> The GC thread hangs in lock_page(page), the write thread hangs in the
> first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:
>
> jffs2_garbage_collect_live
>     mutex_lock(&f->sem)                         (A)
>     jffs2_garbage_collect_dnode [inlined]
>         jffs2_gc_fetch_page
>             read_cache_page_async
>                 do_read_cache_page
>                     lock_page(page) [inlined]
>                         __lock_page             (B) ***
>
> jffs2_write_begin
>     grab_cache_page_write_begin
>         find_lock_page
>             lock_page(page)                     (B)
>     mutex_lock(&f->sem)                         (A) ***
>
> I have manually analyzed the stacks and confirmed that both threads sit on
> the theme 'struct page'.
>

hmm, not something I have seen but your analysis seems spot on. With any luck
you only need to move the mutex_lock in the write begin before lock_page. I
am only guessing now though.

 Jocke



From joakim.tjernlund at transmode.se  Tue Oct  2 14:04:36 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Tue, 2 Oct 2012 20:04:36 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
Message-ID: <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>

> >
> > Hello all,
> >
> > I have encountered multiple times a deadlock between two JFFS2 threads:
>
> [SNIP]
>
> >
> > The target system is an SoC with a dual ARMv7 (Cortex-A9), and we are
> > running the long-term 3.4.11 kernel (whose fs/jffs2/ seems to be pretty
> > close to the latest mainline kernel). The deadlock occurred when using scp
> > to copy files from a host system to the target system.
> >
> > The GC thread hangs in lock_page(page), the write thread hangs in the
> > first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:
> >
> > jffs2_garbage_collect_live
> >     mutex_lock(&f->sem)                         (A)
> >     jffs2_garbage_collect_dnode [inlined]
> >         jffs2_gc_fetch_page
> >             read_cache_page_async
> >                 do_read_cache_page
> >                     lock_page(page) [inlined]
> >                         __lock_page             (B) ***
> >
> > jffs2_write_begin
> >     grab_cache_page_write_begin
> >         find_lock_page
> >             lock_page(page)                     (B)
> >     mutex_lock(&f->sem)                         (A) ***
> >
> > I have manually analyzed the stacks and confirmed that both threads sit on
> > the theme 'struct page'.
> >
>
> hmm, not something I have seen but your analysis seems spot on. With any luck
> you only need to move the mutex_lock in the write begin before lock_page. I
> am only guessing now though.

I had a look at jffs2_write_begin() and it looks fishy:
It can write a hole frag sucessfully but still fail in:
	if (!PageUptodate(pg)) {
		mutex_lock(&f->sem);
		ret = jffs2_do_readpage_nolock(inode, pg);
		mutex_unlock(&f->sem);
		if (ret)
			goto out_page;
	}
which seems a bit strange.

Further up we have this:
		ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
		...
		ri.dsize = cpu_to_je32(pageofs - inode->i_size);
Why max(..) when pageofs  must be > inode->i_size for ri.dsize
to make sense?

 Jocke



From joakim.tjernlund at transmode.se  Tue Oct  2 14:54:59 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Tue, 2 Oct 2012 20:54:59 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
Message-ID: <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>



linux-mtd-bounces at lists.infradead.org wrote on 2012/10/02 20:04:36:

> From: Joakim Tjernlund <joakim.tjernlund at transmode.se>
> To:
> Cc: linux-mtd at lists.infradead.org, Thomas.Betker at rohde-schwarz.com
> Date: 2012/10/02 20:08
> Subject: Re: JFFS2 deadlock, kernel 3.4.11
> Sent by: linux-mtd-bounces at lists.infradead.org
>
> > >
> > > Hello all,
> > >
> > > I have encountered multiple times a deadlock between two JFFS2 threads:
> >
> > [SNIP]
> >
> > >
> > > The target system is an SoC with a dual ARMv7 (Cortex-A9), and we are
> > > running the long-term 3.4.11 kernel (whose fs/jffs2/ seems to be pretty
> > > close to the latest mainline kernel). The deadlock occurred when using scp
> > > to copy files from a host system to the target system.
> > >
> > > The GC thread hangs in lock_page(page), the write thread hangs in the
> > > first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:
> > >
> > > jffs2_garbage_collect_live
> > >     mutex_lock(&f->sem)                         (A)
> > >     jffs2_garbage_collect_dnode [inlined]
> > >         jffs2_gc_fetch_page
> > >             read_cache_page_async
> > >                 do_read_cache_page
> > >                     lock_page(page) [inlined]
> > >                         __lock_page             (B) ***
> > >
> > > jffs2_write_begin
> > >     grab_cache_page_write_begin
> > >         find_lock_page
> > >             lock_page(page)                     (B)
> > >     mutex_lock(&f->sem)                         (A) ***
> > >
> > > I have manually analyzed the stacks and confirmed that both threads sit on
> > > the theme 'struct page'.
> > >
> >
> > hmm, not something I have seen but your analysis seems spot on. With any luck
> > you only need to move the mutex_lock in the write begin before lock_page. I
> > am only guessing now though.
>
> I had a look at jffs2_write_begin() and it looks fishy:
> It can write a hole frag sucessfully but still fail in:
>    if (!PageUptodate(pg)) {
>       mutex_lock(&f->sem);
>       ret = jffs2_do_readpage_nolock(inode, pg);
>       mutex_unlock(&f->sem);
>       if (ret)
>          goto out_page;
>    }
> which seems a bit strange.
>
> Further up we have this:
>       ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
>       ...
>       ri.dsize = cpu_to_je32(pageofs - inode->i_size);
> Why max(..) when pageofs  must be > inode->i_size for ri.dsize
> to make sense?

So maybe this will help(not even compile tested), don't know if jffs2_reserve_space()
can be called with f->sem held.
If this is bad, then perhaps move pg = grab_cache_page_write_begin(mapping, index, flags)
to later in this function somehow?

diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index db3889b..fb58622 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -142,9 +142,12 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
        uint32_t pageofs = index << PAGE_CACHE_SHIFT;
        int ret = 0;

+       mutex_lock(&f->sem);
        pg = grab_cache_page_write_begin(mapping, index, flags);
-       if (!pg)
+       if (!pg) {
+               mutex_unlock(&f->sem);
                return -ENOMEM;
+       }
        *pagep = pg;

        jffs2_dbg(1, "%s()\n", __func__);
@@ -164,7 +167,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                if (ret)
                        goto out_page;

-               mutex_lock(&f->sem);
                memset(&ri, 0, sizeof(ri));

                ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +193,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                if (IS_ERR(fn)) {
                        ret = PTR_ERR(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +207,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                        jffs2_mark_node_obsolete(c, fn->raw);
                        jffs2_free_full_dnode(fn);
                        jffs2_complete_reservation(c);
-                       mutex_unlock(&f->sem);
                        goto out_page;
                }
                jffs2_complete_reservation(c);
                inode->i_size = pageofs;
-               mutex_unlock(&f->sem);
        }

        /*
@@ -220,18 +219,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
         * case of a short-copy.
         */
        if (!PageUptodate(pg)) {
-               mutex_lock(&f->sem);
                ret = jffs2_do_readpage_nolock(inode, pg);
-               mutex_unlock(&f->sem);
                if (ret)
                        goto out_page;
        }
+       mutex_unlock(&f->sem);
        jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
        return ret;

 out_page:
        unlock_page(pg);
        page_cache_release(pg);
+       mutex_unlock(&f->sem);
        return ret;
 }




From zajec5 at gmail.com  Tue Oct  2 16:10:38 2012
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 2 Oct 2012 22:10:38 +0200
Subject: [PATCH 6/6] bcm47xxnflash: enable BCM4706 driver
In-Reply-To: <1348746947-2349-6-git-send-email-zajec5@gmail.com>
References: <1348746947-2349-1-git-send-email-zajec5@gmail.com>
 <1348746947-2349-6-git-send-email-zajec5@gmail.com>
Message-ID: <CACna6rynQ4tLDrhCtGGXeULgBYr900zf6mVPXRoqyCi+M6xfiQ@mail.gmail.com>

2012/9/27 Rafa? Mi?ecki <zajec5 at gmail.com>:
> Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>

Any news on that? Chance for 3.7 merge window maybe?

-- 
Rafa?


From arnd.bergmann at linaro.org  Tue Oct  2 16:47:49 2012
From: arnd.bergmann at linaro.org (Arnd Bergmann)
Date: Tue, 2 Oct 2012 20:47:49 +0000
Subject: [PATCH 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <Pine.LNX.4.64.1210021602250.15778@axis700.grange>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <201210021354.01247.arnd@arndb.de>
 <Pine.LNX.4.64.1210021602250.15778@axis700.grange>
Message-ID: <201210022047.50064.arnd.bergmann@linaro.org>

On Tuesday 02 October 2012, Guennadi Liakhovetski wrote:
> > 
> > Since you are also adding dma-engine support, I would suggest you specify
> > a "dmas" and "dma-names" property as well, so the device can find the
> > right dma channel. The code might not do that yet while you're still
> > sorting out the dependencies (and the sh dmaengine code is not yet
> > converted to DT), but I think it would be good to nail down the binding
> > for this device.
> 
> Have DMA DT bindings been accepted yet, are they fixed? Wouldn't it be 
> better to wait until patches appear in a tree, at least with high 
> probability heading towards the mainline, or have they already?
> 

I think they ended up not getting scheduled for 3.7, which is a bit disappointing
after we got an agreement on the binding.  However, I am rather confident that
we won't change the binding again, at least I don't see how they would change
in a way that would impact the binding document for a device using a DMA channel.

	Arnd


From artem.bityutskiy at linux.intel.com  Wed Oct  3 04:25:45 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 11:25:45 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1348674710-102885-1-git-send-email-richard@nod.at>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
Message-ID: <1349252745.2017.120.camel@sauron.fi.intel.com>

On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> UBI Fastmap is an optional feature which stores the physical to
> logical eraseblock relations in a checkpoint (called fastmap) to reduce
> the initialization time of UBI. The current init time of UBI is
> proportional to the number of physical erase blocks on the FLASH
> device. With fastmap enabled the scan time is limited to a fixed
> number of blocks.

Aiaiai complains and linux-next build fails :-( Last time I forgot to
enable the fastmap kbuild option so aiaiai checked with that option
disabled. Now I enabled it with a simple hack (default n -> default y)
and here are aiaiai's complaints - there is a build failure for
ARCH=i386.

I should improve aiaiai to automatically enable new Kconfig features, or
at least warn about them. This is not the first time someone sends a new
driver which is default off, and I forget to enable it :-(


dedekind at blue:~/git/maintaining$ ../aiaiai/aiaiai-concat-mboxes ../linux-ubi/00* | ./verify ../linux-ubi gen -c 55393ba1bdedc5ded79b34b4cc08898a7776cddb
Tested the patch(es) on top of the following commits:
e4e9957 Quick fixes - applied by aiaiai
55393ba UBI: fix trivial typo 'it' => 'is'
cf38aca UBI: load after mtd device drivers
719bb84 UBI: print less

--------------------------------------------------------------------------------

Successfully built configuration "arm-omap2plus_defconfig,arm,arm-unknown-linux-gnueabi-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------
Failed to build the following commit for configuration "i386_defconfig" (architecture i386)":

88f4a02 UBI: Wire-up fastmap

drivers/mtd/nand/r852.c:571:6: warning: no previous prototype for ?r852_engine_disable? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:581:6: warning: no previous prototype for ?r852_card_update_present? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:596:6: warning: no previous prototype for ?r852_update_card_detect? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:610:9: warning: no previous prototype for ?r852_media_type_show? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:625:6: warning: no previous prototype for ?r852_update_media_status? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:654:5: warning: no previous prototype for ?r852_register_nand_device? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:692:6: warning: no previous prototype for ?r852_unregister_nand_device? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:706:6: warning: no previous prototype for ?r852_card_detect_work? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:845:6: warning: no previous prototype for ?r852_probe? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:986:6: warning: no previous prototype for ?r852_remove? [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:1017:6: warning: no previous prototype for ?r852_shutdown? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:44:9: warning: no previous prototype for ?sm_attr_show? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:57:25: warning: no previous prototype for ?sm_create_sysfs_attributes? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:110:6: warning: no previous prototype for ?sm_delete_sysfs_attributes? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:575:5: warning: no previous prototype for ?sm_get_media_info? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:882:18: warning: no previous prototype for ?sm_get_zone? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:903:6: warning: no previous prototype for ?sm_cache_init? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:913:6: warning: no previous prototype for ?sm_cache_put? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:921:5: warning: no previous prototype for ?sm_cache_get? [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:932:5: warning: no previous prototype for ?sm_cache_flush? [-Wmissing-prototypes]
ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!
make[2]: *** [__modpost] Error 1

--------------------------------------------------------------------------------
Failed to build the following commit for configuration "ia64_defconfig" (architecture ia64)":

88f4a02 UBI: Wire-up fastmap

drivers/mtd/nand/r852.c:381:5: warning: no previous prototype for 'r852_wait' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:410:5: warning: no previous prototype for 'r852_ready' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:421:6: warning: no previous prototype for 'r852_ecc_hwctl' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:453:5: warning: no previous prototype for 'r852_ecc_calculate' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:485:5: warning: no previous prototype for 'r852_ecc_correct' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:553:6: warning: no previous prototype for 'r852_engine_enable' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:571:6: warning: no previous prototype for 'r852_engine_disable' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:581:6: warning: no previous prototype for 'r852_card_update_present' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:596:6: warning: no previous prototype for 'r852_update_card_detect' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:610:9: warning: no previous prototype for 'r852_media_type_show' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:625:6: warning: no previous prototype for 'r852_update_media_status' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:654:5: warning: no previous prototype for 'r852_register_nand_device' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:692:6: warning: no previous prototype for 'r852_unregister_nand_device' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:706:6: warning: no previous prototype for 'r852_card_detect_work' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:845:6: warning: no previous prototype for 'r852_probe' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:986:6: warning: no previous prototype for 'r852_remove' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:1017:6: warning: no previous prototype for 'r852_shutdown' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:1028:12: warning: 'r852_suspend' defined but not used [-Wunused-function]
drivers/mtd/nand/r852.c:1049:12: warning: 'r852_resume' defined but not used [-Wunused-function]
WARNING: modpost: Found 1 section mismatch(es).
ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!
make[2]: *** [__modpost] Error 1

--------------------------------------------------------------------------------

Successfully built configuration "m68k-m5208evb_defconfig,m68k,m68k-linux-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------
Failed to build the following commit for configuration "mips64_defconfig" (architecture mips)":

88f4a02 UBI: Wire-up fastmap

drivers/mtd/nand/r852.c:571:6: warning: no previous prototype for 'r852_engine_disable' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:581:6: warning: no previous prototype for 'r852_card_update_present' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:596:6: warning: no previous prototype for 'r852_update_card_detect' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:610:9: warning: no previous prototype for 'r852_media_type_show' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:625:6: warning: no previous prototype for 'r852_update_media_status' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:654:5: warning: no previous prototype for 'r852_register_nand_device' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:692:6: warning: no previous prototype for 'r852_unregister_nand_device' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:706:6: warning: no previous prototype for 'r852_card_detect_work' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:845:6: warning: no previous prototype for 'r852_probe' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:986:6: warning: no previous prototype for 'r852_remove' [-Wmissing-prototypes]
drivers/mtd/nand/r852.c:1017:6: warning: no previous prototype for 'r852_shutdown' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:44:9: warning: no previous prototype for 'sm_attr_show' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:57:25: warning: no previous prototype for 'sm_create_sysfs_attributes' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:110:6: warning: no previous prototype for 'sm_delete_sysfs_attributes' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:575:5: warning: no previous prototype for 'sm_get_media_info' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:882:18: warning: no previous prototype for 'sm_get_zone' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:903:6: warning: no previous prototype for 'sm_cache_init' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:913:6: warning: no previous prototype for 'sm_cache_put' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:921:5: warning: no previous prototype for 'sm_cache_get' [-Wmissing-prototypes]
drivers/mtd/sm_ftl.c:932:5: warning: no previous prototype for 'sm_cache_flush' [-Wmissing-prototypes]
ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!
make[2]: *** [__modpost] Error 1

--------------------------------------------------------------------------------

Successfully built configuration "mips-bcm63xx_defconfig,mips,mips-linux-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------

Successfully built configuration "ppc32_defconfig,powerpc,powerpc-linux-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------

Successfully built configuration "ppc64_defconfig,powerpc,powerpc64-linux-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------

Successfully built configuration "x86_64_defconfig,x86_64,", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/ubi/fastmap.c:1012 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1012:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1017:7-11: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1027 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1027:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1033 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1033:1-3: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:1077 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:1479 ubi_update_fastmap() error: we previously assumed 'tmp_e' could be null (see line 1463) [smatch]
+drivers/mtd/ubi/fastmap.c:925 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:925:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:926 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:926:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:933 ubi_scan_fastmap() error: double free of 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:933:8-12: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:934 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:934:8-10: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:940 ubi_scan_fastmap() error: dereferencing freed memory 'fmsb' [smatch]
+drivers/mtd/ubi/fastmap.c:940:21-25: ERROR: reference preceded by free on line 918 [coccinelle]
+drivers/mtd/ubi/fastmap.c:944 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:944:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:956 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:956:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:959 ubi_scan_fastmap() error: dereferencing freed memory 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:959:3-5: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:967 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:967:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:976 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:976:9-11: ERROR: reference preceded by free on line 919 [coccinelle]
+drivers/mtd/ubi/fastmap.c:988 ubi_scan_fastmap() error: double free of 'fm' [smatch]
+drivers/mtd/ubi/fastmap.c:988:10-12: ERROR: reference preceded by free on line 919 [coccinelle]
@@ @@
+drivers/mtd/ubi/wl.c:284:3-9: preceding lock on line 282 [coccinelle]

--------------------------------------------------------------------------------

checkpatch.pl has some complaints:

--------------------------------------------------------------------------------

checkpatch.pl results for patch "[PATCH 07/10] UBI: Add fastmap stuff to attach.c"

WARNING:LONG_LINE: line over 80 characters
#115: FILE: drivers/mtd/ubi/attach.c:1008:
+                               ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it",

total: 0 errors, 1 warnings, 550 lines checked

--------------------------------------------------------------------------------

checkpatch.pl results for the entire squashed patch-set

WARNING:LONG_LINE: line over 80 characters
#987: FILE: drivers/mtd/ubi/attach.c:1008:
+                               ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it",

total: 0 errors, 1 warnings, 3708 lines checked

--------------------------------------------------------------------------------

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/58fc6d81/attachment-0001.sig>

From richard at nod.at  Wed Oct  3 04:36:25 2012
From: richard at nod.at (Richard Weinberger)
Date: Wed, 3 Oct 2012 10:36:25 +0200
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1349252745.2017.120.camel@sauron.fi.intel.com>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
Message-ID: <20121003103625.0bbff63c@spider.haslach.nod.at>

Am Wed, 03 Oct 2012 11:25:45 +0300
schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:

> On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> > UBI Fastmap is an optional feature which stores the physical to
> > logical eraseblock relations in a checkpoint (called fastmap) to
> > reduce the initialization time of UBI. The current init time of UBI
> > is proportional to the number of physical erase blocks on the FLASH
> > device. With fastmap enabled the scan time is limited to a fixed
> > number of blocks.
> 
> Aiaiai complains and linux-next build fails :-( Last time I forgot to
> enable the fastmap kbuild option so aiaiai checked with that option
> disabled. Now I enabled it with a simple hack (default n -> default y)
> and here are aiaiai's complaints - there is a build failure for
> ARCH=i386.

Build fix for linux-next is on the way into your inbox.
I'm currently looking at the aiaiai output.

Thanks,
//richard


From artem.bityutskiy at linux.intel.com  Wed Oct  3 04:43:14 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 11:43:14 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <20121003103625.0bbff63c@spider.haslach.nod.at>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
Message-ID: <1349253794.2017.124.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 10:36 +0200, Richard Weinberger wrote:
> Am Wed, 03 Oct 2012 11:25:45 +0300
> schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:
> 
> > On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> > > UBI Fastmap is an optional feature which stores the physical to
> > > logical eraseblock relations in a checkpoint (called fastmap) to
> > > reduce the initialization time of UBI. The current init time of UBI
> > > is proportional to the number of physical erase blocks on the FLASH
> > > device. With fastmap enabled the scan time is limited to a fixed
> > > number of blocks.
> > 
> > Aiaiai complains and linux-next build fails :-( Last time I forgot to
> > enable the fastmap kbuild option so aiaiai checked with that option
> > disabled. Now I enabled it with a simple hack (default n -> default y)
> > and here are aiaiai's complaints - there is a build failure for
> > ARCH=i386.
> 
> Build fix for linux-next is on the way into your inbox.
> I'm currently looking at the aiaiai output.

I've taken a quick look - you call 'kfree(fm)' 16 times in that
function. Even if we get everything correctly, we should probably change
that anyway with goto's.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/7e27066a/attachment.sig>

From artem.bityutskiy at linux.intel.com  Wed Oct  3 04:44:45 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 11:44:45 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <20121003103625.0bbff63c@spider.haslach.nod.at>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
Message-ID: <1349253885.2017.125.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 10:36 +0200, Richard Weinberger wrote:
> Am Wed, 03 Oct 2012 11:25:45 +0300
> schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:
> 
> > On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> > > UBI Fastmap is an optional feature which stores the physical to
> > > logical eraseblock relations in a checkpoint (called fastmap) to
> > > reduce the initialization time of UBI. The current init time of UBI
> > > is proportional to the number of physical erase blocks on the FLASH
> > > device. With fastmap enabled the scan time is limited to a fixed
> > > number of blocks.
> > 
> > Aiaiai complains and linux-next build fails :-( Last time I forgot to
> > enable the fastmap kbuild option so aiaiai checked with that option
> > disabled. Now I enabled it with a simple hack (default n -> default y)
> > and here are aiaiai's complaints - there is a build failure for
> > ARCH=i386.
> 
> Build fix for linux-next is on the way into your inbox.
> I'm currently looking at the aiaiai output.

OK, I see, goto out is missing after line 919. Please, send a short fix
- I'll squash it in. But general error-path rework is needed for this
function, may be separately.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/17bfcfe6/attachment.sig>

From richard at nod.at  Wed Oct  3 05:03:20 2012
From: richard at nod.at (Richard Weinberger)
Date: Wed, 03 Oct 2012 11:03:20 +0200
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1349253885.2017.125.camel@sauron.fi.intel.com>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
 <1349253885.2017.125.camel@sauron.fi.intel.com>
Message-ID: <506BFF58.4060106@nod.at>

On 03.10.2012 10:44, Artem Bityutskiy wrote:
> On Wed, 2012-10-03 at 10:36 +0200, Richard Weinberger wrote:
>> Am Wed, 03 Oct 2012 11:25:45 +0300
>> schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:
>>
>>> On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
>>>> UBI Fastmap is an optional feature which stores the physical to
>>>> logical eraseblock relations in a checkpoint (called fastmap) to
>>>> reduce the initialization time of UBI. The current init time of UBI
>>>> is proportional to the number of physical erase blocks on the FLASH
>>>> device. With fastmap enabled the scan time is limited to a fixed
>>>> number of blocks.
>>>
>>> Aiaiai complains and linux-next build fails :-( Last time I forgot to
>>> enable the fastmap kbuild option so aiaiai checked with that option
>>> disabled. Now I enabled it with a simple hack (default n -> default y)
>>> and here are aiaiai's complaints - there is a build failure for
>>> ARCH=i386.
>>
>> Build fix for linux-next is on the way into your inbox.
>> I'm currently looking at the aiaiai output.
>
> OK, I see, goto out is missing after line 919. Please, send a short fix
> - I'll squash it in. But general error-path rework is needed for this
> function, may be separately.
>

Yeah, it looks like all issues reported by aiaiai are caused by the missing goto.
Can you deal with the patch below or do you want me to send it using git send-email?

Thanks,
//richard

---
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index be73a1d..adcb2e4 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -917,6 +917,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
  		ret = UBI_BAD_FASTMAP;
  		kfree(fmsb);
  		kfree(fm);
+		goto out;
  	}

  	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);



From artem.bityutskiy at linux.intel.com  Wed Oct  3 05:30:59 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 12:30:59 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <506BFF58.4060106@nod.at>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
 <1349253885.2017.125.camel@sauron.fi.intel.com> <506BFF58.4060106@nod.at>
Message-ID: <1349256659.2017.128.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 11:03 +0200, Richard Weinberger wrote:
> Yeah, it looks like all issues reported by aiaiai are caused by the missing goto.
> Can you deal with the patch below or do you want me to send it using git send-email?

I'll apply it. But please, re-work the error handling in that function
separately.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/48929f16/attachment.sig>

From richard at nod.at  Wed Oct  3 05:32:29 2012
From: richard at nod.at (Richard Weinberger)
Date: Wed, 03 Oct 2012 11:32:29 +0200
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1349256659.2017.128.camel@sauron.fi.intel.com>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
 <1349253885.2017.125.camel@sauron.fi.intel.com> <506BFF58.4060106@nod.at>
 <1349256659.2017.128.camel@sauron.fi.intel.com>
Message-ID: <506C062D.8080608@nod.at>

On 03.10.2012 11:30, Artem Bityutskiy wrote:
> On Wed, 2012-10-03 at 11:03 +0200, Richard Weinberger wrote:
>> Yeah, it looks like all issues reported by aiaiai are caused by the missing goto.
>> Can you deal with the patch below or do you want me to send it using git send-email?
>
> I'll apply it. But please, re-work the error handling in that function
> separately.
>

Okay, but not now during the merge window.
Is this fine for you?

Thanks,
//richard


From artem.bityutskiy at linux.intel.com  Wed Oct  3 07:05:02 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 14:05:02 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <20121003103625.0bbff63c@spider.haslach.nod.at>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
Message-ID: <1349262302.2017.141.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 10:36 +0200, Richard Weinberger wrote:
> Am Wed, 03 Oct 2012 11:25:45 +0300
> schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:
> 
> > On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> > > UBI Fastmap is an optional feature which stores the physical to
> > > logical eraseblock relations in a checkpoint (called fastmap) to
> > > reduce the initialization time of UBI. The current init time of UBI
> > > is proportional to the number of physical erase blocks on the FLASH
> > > device. With fastmap enabled the scan time is limited to a fixed
> > > number of blocks.
> > 
> > Aiaiai complains and linux-next build fails :-( Last time I forgot to
> > enable the fastmap kbuild option so aiaiai checked with that option
> > disabled. Now I enabled it with a simple hack (default n -> default y)
> > and here are aiaiai's complaints - there is a build failure for
> > ARCH=i386.
> 
> Build fix for linux-next is on the way into your inbox.
> I'm currently looking at the aiaiai output.

It did not help. I still get:

ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!

Please, see branch 'linux-next' in UBI to see what I actually tested.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/b800fb9f/attachment-0001.sig>

From dedekind1 at gmail.com  Wed Oct  3 07:18:52 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 14:18:52 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1349262302.2017.141.camel@sauron.fi.intel.com>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
 <1349262302.2017.141.camel@sauron.fi.intel.com>
Message-ID: <1349263132.2017.146.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 14:05 +0300, Artem Bityutskiy wrote:
> On Wed, 2012-10-03 at 10:36 +0200, Richard Weinberger wrote:
> > Am Wed, 03 Oct 2012 11:25:45 +0300
> > schrieb Artem Bityutskiy <artem.bityutskiy at linux.intel.com>:
> > 
> > > On Wed, 2012-09-26 at 17:51 +0200, Richard Weinberger wrote:
> > > > UBI Fastmap is an optional feature which stores the physical to
> > > > logical eraseblock relations in a checkpoint (called fastmap) to
> > > > reduce the initialization time of UBI. The current init time of UBI
> > > > is proportional to the number of physical erase blocks on the FLASH
> > > > device. With fastmap enabled the scan time is limited to a fixed
> > > > number of blocks.
> > > 
> > > Aiaiai complains and linux-next build fails :-( Last time I forgot to
> > > enable the fastmap kbuild option so aiaiai checked with that option
> > > disabled. Now I enabled it with a simple hack (default n -> default y)
> > > and here are aiaiai's complaints - there is a build failure for
> > > ARCH=i386.
> > 
> > Build fix for linux-next is on the way into your inbox.
> > I'm currently looking at the aiaiai output.
> 
> It did not help. I still get:
> 
> ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
> ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
> ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!
> 
> Please, see branch 'linux-next' in UBI to see what I actually tested.

And aiaiai has another correct complaint:

+drivers/mtd/ubi/fastmap.c:1078 ubi_scan_fastmap() warn: possible memory leak of 'fm' [smatch]

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/2c407097/attachment.sig>

From dedekind1 at gmail.com  Wed Oct  3 08:13:05 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 03 Oct 2012 15:13:05 +0300
Subject: UBI: Fastmap request for inclusion (v19)
In-Reply-To: <1349262302.2017.141.camel@sauron.fi.intel.com>
References: <1348674710-102885-1-git-send-email-richard@nod.at>
 <1349252745.2017.120.camel@sauron.fi.intel.com>
 <20121003103625.0bbff63c@spider.haslach.nod.at>
 <1349262302.2017.141.camel@sauron.fi.intel.com>
Message-ID: <1349266385.20373.0.camel@sauron.fi.intel.com>

On Wed, 2012-10-03 at 14:05 +0300, Artem Bityutskiy wrote:
> ERROR: "ubi_update_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
> ERROR: "ubi_scan_fastmap" [drivers/mtd/ubi/ubi.ko] undefined!
> ERROR: "ubi_calc_fm_size" [drivers/mtd/ubi/ubi.ko] undefined!
> 
> Please, see branch 'linux-next' in UBI to see what I actually tested.

Sorry, I did not apply your patch correctly, now it builds without
issues.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121003/70c40d53/attachment.sig>

From avinashphilip at ti.com  Wed Oct  3 10:29:45 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 3 Oct 2012 19:59:45 +0530
Subject: [PATCH 0/4] mtd: nand: OMAP: Add support to use ELM as error
 correction module
Message-ID: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>

Adds support to use ELM as BCH 4 & 8 bit error correction module and
adds support for single shot read_page and write_page functions

Platforms containing the ELM module can be used to correct errors
reported by BCH 4, 8 & 16 bit ECC scheme. For now only 4 & 8 bit
support is added.

BCH 4 & 8 bit error detection support is already available in mainline
kernel and works with software error correction.

This series is based on top of [1] &[2]

1. linux-next/master
2. linux-omap-dt/for_3.7/dts_part2

Nand driver tested for BCH 4 & 8 bit error correction per sector.
This being tested by introducing bit errors at multiple sectors inside page.

Philip, Avinash (4):
  mtd: nand: omap2: Update nerrors using ecc.strength
  mtd: devices: elm: Add support for ELM error correction
  ARM: OMAP2: gpmc: Add support for BCH ECC scheme
  mtd: nand: omap2: Add data correction support

 arch/arm/mach-omap2/gpmc.c                   |  120 +++++++-
 arch/arm/plat-omap/include/plat/gpmc.h       |    1 +
 drivers/mtd/devices/Makefile                 |    4 +-
 drivers/mtd/devices/elm.c                    |  446 ++++++++++++++++++++++++++
 drivers/mtd/nand/omap2.c                     |  368 +++++++++++++++++++--
 include/linux/platform_data/elm.h            |   64 ++++
 include/linux/platform_data/mtd-nand-omap2.h |    1 +
 7 files changed, 958 insertions(+), 46 deletions(-)
 create mode 100644 drivers/mtd/devices/elm.c
 create mode 100644 include/linux/platform_data/elm.h



From avinashphilip at ti.com  Wed Oct  3 10:29:46 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 3 Oct 2012 19:59:46 +0530
Subject: [PATCH 1/4] mtd: nand: omap2: Update nerrors using ecc.strength
In-Reply-To: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1349274589-11389-2-git-send-email-avinashphilip@ti.com>

Update number of errors using nand ecc strength.
Also add macro definitions BCH8_ERROR_MAX & BCH4_ERROR_MAX

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
---
:100644 100644 5b31386... af511a9... M	drivers/mtd/nand/omap2.c
 drivers/mtd/nand/omap2.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..af511a9 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -111,6 +111,9 @@
 #define	ECCCLEAR			0x100
 #define	ECC1				0x1
 
+#define BCH8_MAX_ERROR		8	/* upto 8 bit coorectable */
+#define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */
+
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -1034,7 +1037,7 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 						   mtd);
 	struct nand_chip *chip = mtd->priv;
 
-	nerrors = (info->nand.ecc.bytes == 13) ? 8 : 4;
+	nerrors = info->nand.ecc.strength;
 	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
 	/*
 	 * Program GPMC to perform correction on one 512-byte sector at a time.
@@ -1129,13 +1132,14 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 #ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = 8;
+	const int hw_errors = BCH8_MAX_ERROR;
 #else
-	const int hw_errors = 4;
+	const int hw_errors = BCH4_MAX_ERROR;
 #endif
 	info->bch = NULL;
 
-	max_errors = (ecc_opt == OMAP_ECC_BCH8_CODE_HW) ? 8 : 4;
+	max_errors = (ecc_opt == OMAP_ECC_BCH8_CODE_HW) ?
+		BCH8_MAX_ERROR : BCH4_MAX_ERROR;
 	if (max_errors != hw_errors) {
 		pr_err("cannot configure %d-bit BCH ecc, only %d-bit supported",
 		       max_errors, hw_errors);
-- 
1.7.0.4



From avinashphilip at ti.com  Wed Oct  3 10:29:47 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 3 Oct 2012 19:59:47 +0530
Subject: [PATCH 2/4] mtd: devices: elm: Add support for ELM error correction
In-Reply-To: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1349274589-11389-3-git-send-email-avinashphilip@ti.com>

Platforms containing the ELM module can be used to correct errors
reported by BCH 4, 8 & 16 bit ECC scheme. For now only 4 & 8 bit
support is added.

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
Cc: Grant Likely <grant.likely at secretlab.ca>
Cc: Rob Herring <rob.herring at calxeda.com>
Cc: Rob Landley <rob at landley.net>
---
:000000 100644 0000000... b88ee83... A	Documentation/devicetree/bindings/mtd/elm.txt
:100644 100644 395733a... 0f6a94b... M	drivers/mtd/devices/Makefile
:000000 100644 0000000... 802b572... A	drivers/mtd/devices/elm.c
:000000 100644 0000000... eb53163... A	include/linux/platform_data/elm.h
 Documentation/devicetree/bindings/mtd/elm.txt |   18 +
 drivers/mtd/devices/Makefile                  |    4 +-
 drivers/mtd/devices/elm.c                     |  440 +++++++++++++++++++++++++
 include/linux/platform_data/elm.h             |   60 ++++
 4 files changed, 521 insertions(+), 1 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/elm.txt b/Documentation/devicetree/bindings/mtd/elm.txt
new file mode 100644
index 0000000..b88ee83
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/elm.txt
@@ -0,0 +1,18 @@
+Error location module
+
+Required properties:
+- compatible: Must be "ti,elm"
+- reg: physical base address and size of the registers map.
+- interrupts: Interrupt number for the elm.
+- interrupt-parent: The parent interrupt controller
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the elm
+
+Example:
+elm: elm at 0 {
+	compatible	= "ti,elm";
+	reg = <0x48080000 0x2000>;
+	interrupt-parent = <&intc>;
+	interrupts = <4>;
+};
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 395733a..0f6a94b 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,8 +17,10 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
+obj-$(CONFIG_MTD_NAND_OMAP2)	+= elm.o
 obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
 obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
 
-CFLAGS_docg3.o			+= -I$(src)
\ No newline at end of file
+
+CFLAGS_docg3.o			+= -I$(src)
diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
new file mode 100644
index 0000000..802b572
--- /dev/null
+++ b/drivers/mtd/devices/elm.c
@@ -0,0 +1,440 @@
+/*
+ * Error Location Module
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_data/elm.h>
+
+#define ELM_IRQSTATUS			0x018
+#define ELM_IRQENABLE			0x01c
+#define ELM_LOCATION_CONFIG		0x020
+#define ELM_PAGE_CTRL			0x080
+#define ELM_SYNDROME_FRAGMENT_0		0x400
+#define ELM_SYNDROME_FRAGMENT_6		0x418
+#define ELM_LOCATION_STATUS		0x800
+#define ELM_ERROR_LOCATION_0		0x880
+
+/* ELM Interrupt Status Register */
+#define INTR_STATUS_PAGE_VALID		BIT(8)
+
+/* ELM Interrupt Enable Register */
+#define INTR_EN_PAGE_MASK		BIT(8)
+
+/* ELM Location Configuration Register */
+#define ECC_BCH_LEVEL_MASK		0x3
+
+/* ELM syndrome */
+#define ELM_SYNDROME_VALID		BIT(16)
+
+/* ELM_LOCATION_STATUS Register */
+#define ECC_CORRECTABLE_MASK		BIT(8)
+#define ECC_NB_ERRORS_MASK		0x1f
+
+/* ELM_ERROR_LOCATION_0-15 Registers */
+#define ECC_ERROR_LOCATION_MASK		0x1fff
+
+#define ELM_ECC_SIZE			0x7ff
+
+#define SYNDROME_FRAGMENT_REG_SIZE	0x40
+#define ERROR_LOCATION_SIZE		0x100
+#define MAX_BCH_ELM_ERROR		16
+#define ELM_FRAGMENT_REG		7
+
+typedef u32 syn_t[ELM_FRAGMENT_REG];
+typedef u32 elm_error_t[MAX_BCH_ELM_ERROR];
+
+struct elm_info {
+	struct device *dev;
+	void __iomem *elm_base;
+	struct completion elm_completion;
+	struct list_head list;
+	enum bch_ecc bch_type;
+};
+
+static LIST_HEAD(elm_devices);
+
+static void elm_write_reg(void *offset, u32 val)
+{
+	writel(val, offset);
+}
+
+static u32 elm_read_reg(void *offset)
+{
+	return readl(offset);
+}
+
+/**
+ * elm_config - Configure ELM module
+ * @info:	elm info
+ */
+static void elm_config(struct elm_info *info)
+{
+	u32 reg_val;
+
+	reg_val = (info->bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
+	elm_write_reg(info->elm_base + ELM_LOCATION_CONFIG, reg_val);
+}
+
+/**
+ * elm_configure_page_mode - Enable/Disable page mode
+ * @info:	elm info
+ * @index:	index number of syndrome fragment vector
+ * @enable:	enable/disable flag for page mode
+ *
+ * Enable page mode for syndrome fragment index
+ */
+static void elm_configure_page_mode(struct elm_info *info, int index,
+		bool enable)
+{
+	u32 reg_val;
+
+	reg_val = elm_read_reg(info->elm_base + ELM_PAGE_CTRL);
+	if (enable)
+		reg_val |= BIT(index);	/* enable page mode */
+	else
+		reg_val &= ~BIT(index);	/* disable page mode */
+
+	elm_write_reg(info->elm_base + ELM_PAGE_CTRL, reg_val);
+}
+
+static void rearrange_bch4(u8 *syndrome)
+{
+	/*
+	 * BCH4 has 52 bit used for ecc, but OOB stored with
+	 * nibble 0 appended, removes appended 0 nibble
+	 */
+	u64 *dst = (u64 *)syndrome;
+	*dst >>= 4;
+}
+
+/**
+ * elm_reverse_eccdata - Reverse ecc data
+ * @info:	elm info
+ * @ecc_data:	buffer for calculated ecc
+ * @syndrome:	buffer for syndrome polynomial
+ *
+ * ecc_data has to be reversed for syndrome vector
+ */
+static void elm_reverse_eccdata(struct elm_info *info, u8 *ecc_data,
+		u8 *syndrome)
+{
+	int i;
+	int bch_size = info->bch_type ? BCH8_ECC_OOB_BYTES : BCH4_SIZE;
+
+	for (i = 0; i < bch_size; i++)
+		syndrome[bch_size - 1 - i] = ecc_data[i];
+
+	/*
+	 * syndrome polynomial to be rearranged for BCH 4 ecc scheme as 52
+	 * bits being used and 4 bits being appended in syndrome vector
+	 */
+	if (info->bch_type == BCH4_ECC)
+		rearrange_bch4(syndrome);
+}
+
+/**
+ * elm_load_syndrome - Load ELM syndrome reg
+ * @info:	elm info
+ * @index:	syndrome fragment index
+ * @syndrome:	Syndrome polynomial
+ *
+ * Load syndrome fragment registers with syndrome polynomial
+ */
+static void elm_load_syndrome(struct elm_info *info, int index, u8 *syndrome)
+{
+	int i;
+	int max = info->bch_type ? BCH8_SYNDROME_SIZE : BCH4_SYNDROME_SIZE;
+	void *syn_frag_base = info->elm_base + ELM_SYNDROME_FRAGMENT_0;
+	syn_t *syn_fragment;
+	u32 reg_val;
+
+	elm_configure_page_mode(info, index, true);
+	syn_fragment = syn_frag_base + SYNDROME_FRAGMENT_REG_SIZE * index;
+
+	for (i = 0; i < max; i++) {
+		reg_val = syndrome[0] | syndrome[1] << 8 | syndrome[2] << 16 |
+			syndrome[3] << 24;
+		elm_write_reg(*syn_fragment + i, reg_val);
+		/* Update syndrome polynomial pointer */
+		syndrome += 4;
+	}
+}
+
+/**
+ * elm_start_processing - start elm syndrome processing
+ * @info:	elm info
+ * @err_vec:	elm error vectors
+ *
+ * Set syndrome valid bit for syndrome fragment registers for which
+ * elm syndrome fragment registers are loaded. This enables elm module
+ * to start processing syndrome vectors.
+ */
+static void elm_start_processing(struct elm_info *info,
+		struct elm_errorvec *err_vec)
+{
+	int i;
+	void *offset;
+	u32 reg_val;
+
+	/*
+	 * Set syndrome vector valid so that ELM module will process it for
+	 * vectors error is reported
+	 */
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+		if (err_vec[i].error_reported) {
+			offset = info->elm_base + ELM_SYNDROME_FRAGMENT_6 + i *
+				SYNDROME_FRAGMENT_REG_SIZE;
+			reg_val = elm_read_reg(offset);
+			reg_val |= ELM_SYNDROME_VALID;
+			elm_write_reg(offset, reg_val);
+		}
+	}
+}
+
+/**
+ * elm_error_correction - locate correctable error position
+ * @info:	elm info
+ * @err_vec:	elm error vectors
+ *
+ * On completion of processing by elm module, error location status
+ * register updated with correctable/uncorrectable error information.
+ * In case of correctable errors, number of errors located from
+ * elm location status register & read the these many positions from
+ * elm error location register.
+ */
+static void elm_error_correction(struct elm_info *info,
+		struct elm_errorvec *err_vec)
+{
+	int i, j, errors = 0;
+	void *err_loc_base = info->elm_base + ELM_ERROR_LOCATION_0;
+	elm_error_t *err_loc;
+	void *offset;
+	u32 reg_val;
+
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+		/* check error reported */
+		if (err_vec[i].error_reported) {
+			offset = info->elm_base + ELM_LOCATION_STATUS +
+				i * ERROR_LOCATION_SIZE;
+			reg_val = elm_read_reg(offset);
+			/* check correctable error or not */
+			if (reg_val & ECC_CORRECTABLE_MASK) {
+				err_loc = err_loc_base +
+					i * ERROR_LOCATION_SIZE;
+				/* read count of correctable errors */
+				err_vec[i].error_count = reg_val &
+					ECC_NB_ERRORS_MASK;
+
+				/* update the error locations in error vector */
+				for (j = 0; j < err_vec[i].error_count; j++) {
+
+					reg_val = elm_read_reg(*err_loc + j);
+					err_vec[i].error_loc[j] = reg_val &
+						ECC_ERROR_LOCATION_MASK;
+				}
+
+				errors += err_vec[i].error_count;
+			} else {
+				err_vec[i].error_uncorrectable++;
+			}
+
+			/* clearing interrupts for processed error vectors */
+			elm_write_reg(info->elm_base + ELM_IRQSTATUS, BIT(i));
+
+			/* disable page mode */
+			elm_configure_page_mode(info, i, false);
+		}
+	}
+
+	return;
+}
+
+/**
+ * elm_decode_bch_error_page - Locate error position
+ * @info:	elm info
+ * @ecc_calc:	calculated ECC bytes from GPMC
+ * @err_vec:	elm error vectors
+ *
+ * Called with one or greater reported and is vectors with error reported
+ * is updated in err_vec[].error_reported
+ */
+void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
+		struct elm_errorvec *err_vec)
+{
+	int i;
+	u8 syndrome[BCH_MAX_ECC_BYTES_PER_SECTOR] = {0}, *syn_p;
+	struct elm_info *info = dev_get_drvdata(dev);
+	u32 reg_val;
+
+	/* enable page mode interrupt */
+	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
+	elm_write_reg(info->elm_base + ELM_IRQSTATUS,
+			reg_val & INTR_STATUS_PAGE_VALID);
+	elm_write_reg(info->elm_base + ELM_IRQENABLE, INTR_EN_PAGE_MASK);
+
+	syn_p = syndrome;
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+		if (err_vec[i].error_reported) {
+			elm_reverse_eccdata(info, ecc_calc, syn_p);
+			elm_load_syndrome(info, i, syn_p);
+		}
+
+		ecc_calc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
+		syn_p += OOB_SECTOR_SIZE;
+	}
+
+	elm_start_processing(info, err_vec);
+
+	/*
+	 * In case of error reported, wait for ELM module to finish
+	 * locating error correction
+	 */
+	wait_for_completion(&info->elm_completion);
+
+	/* disable page mode interrupt */
+	reg_val = elm_read_reg(info->elm_base + ELM_IRQENABLE);
+	elm_write_reg(info->elm_base + ELM_IRQENABLE,
+			reg_val & ~INTR_EN_PAGE_MASK);
+	elm_error_correction(info, err_vec);
+}
+EXPORT_SYMBOL(elm_decode_bch_error_page);
+
+static irqreturn_t elm_isr(int this_irq, void *dev_id)
+{
+	u32 reg_val;
+	struct elm_info *info = dev_id;
+
+	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
+
+	/* all error vectors processed */
+	if (reg_val & INTR_STATUS_PAGE_VALID) {
+		elm_write_reg(info->elm_base + ELM_IRQSTATUS,
+				reg_val & INTR_STATUS_PAGE_VALID);
+		complete(&info->elm_completion);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+struct device *elm_request(enum bch_ecc bch_type)
+{
+	struct elm_info *info;
+
+	list_for_each_entry(info, &elm_devices, list) {
+		if (info && info->dev) {
+				info->bch_type = bch_type;
+				elm_config(info);
+				return info->dev;
+		}
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(elm_request);
+
+static int __devinit elm_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct resource *res, *irq;
+	struct elm_info *info;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	info->dev = &pdev->dev;
+
+	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irq) {
+		dev_err(&pdev->dev, "no irq resource defined\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		return -ENODEV;
+	}
+
+
+	info->elm_base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!info->elm_base)
+		return -EADDRNOTAVAIL;
+
+
+	ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0,
+			pdev->name, info);
+	if (ret) {
+		dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start);
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	if (pm_runtime_get_sync(&pdev->dev)) {
+		ret = -EINVAL;
+		pm_runtime_disable(&pdev->dev);
+		dev_err(&pdev->dev, "can't enable clock\n");
+		return ret;
+	}
+
+	init_completion(&info->elm_completion);
+	INIT_LIST_HEAD(&info->list);
+	list_add(&info->list, &elm_devices);
+	platform_set_drvdata(pdev, info);
+	return ret;
+}
+
+static int __devexit elm_remove(struct platform_device *pdev)
+{
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+
+#ifdef CONFIG_OF
+static const struct of_device_id elm_of_match[] = {
+	{ .compatible = "ti,elm" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, elm_of_match);
+#endif
+
+static struct platform_driver elm_driver = {
+	.driver		= {
+		.name	= "elm",
+		.of_match_table = of_match_ptr(elm_of_match),
+		.owner	= THIS_MODULE,
+	},
+	.probe		= elm_probe,
+	.remove		= __devexit_p(elm_remove),
+};
+
+module_platform_driver(elm_driver);
+
+MODULE_DESCRIPTION("ELM driver for BCH error correction");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_ALIAS("platform: elm");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
new file mode 100644
index 0000000..eb53163
--- /dev/null
+++ b/include/linux/platform_data/elm.h
@@ -0,0 +1,60 @@
+/*
+ * BCH Error Location Module
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ELM_H
+#define __ELM_H
+
+enum bch_ecc {
+	BCH4_ECC = 0,
+	BCH8_ECC,
+	BCH16_ECC,
+};
+
+/* ELM support 8 error syndrome process */
+#define ERROR_VECTOR_MAX		8
+#define OOB_SECTOR_SIZE			16
+
+#define BCH_MAX_ECC_BYTES_PER_SECTOR	(OOB_SECTOR_SIZE * ERROR_VECTOR_MAX)
+
+#define BCH8_ECC_OOB_BYTES		13
+/* RBL requires 14 byte even though BCH8 uses only 13 byte */
+#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
+#define BCH4_SIZE			7
+
+#define	BCH8_SYNDROME_SIZE		4	/* 13 bytes of ecc */
+#define	BCH4_SYNDROME_SIZE		2	/* 7 bytes of ecc */
+
+/**
+ * struct elm_errorvec - error vector for elm
+ * @error_reported:		set true for vectors error is reported
+ *
+ * @error_count:		number of correctable errors in the sector
+ * @error_uncorrectable:	number of uncorrectable errors
+ * @error_loc:			buffer for error location
+ *
+ */
+struct elm_errorvec {
+	bool error_reported;
+	int error_count;
+	int error_uncorrectable;
+	int error_loc[ERROR_VECTOR_MAX];
+};
+
+void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
+		struct elm_errorvec *err_vec);
+struct device *elm_request(enum bch_ecc bch_type);
+#endif /* __ELM_H */
-- 
1.7.0.4



From avinashphilip at ti.com  Wed Oct  3 10:29:48 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 3 Oct 2012 19:59:48 +0530
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1349274589-11389-4-git-send-email-avinashphilip@ti.com>

Add support for BCH ECC scheme to gpmc driver and also enabling multi
sector read/write. This helps in doing single shot NAND page read and
write.

ECC engine configurations
BCH 4 bit support
1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
13 and ecc_size1 as 1.

BCH 8 bit support
1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
26 and ecc_size1 as 2.

Note: For BCH8 ECC bytes set to 14 to make compatible with RBL.

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
---
:100644 100644 72428bd... c9bc3cf... M	arch/arm/mach-omap2/gpmc.c
:100644 100644 2e6e259... c916510... M	arch/arm/plat-omap/include/plat/gpmc.h
 arch/arm/mach-omap2/gpmc.c             |  120 +++++++++++++++++++++++++++++---
 arch/arm/plat-omap/include/plat/gpmc.h |    1 +
 2 files changed, 112 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 72428bd..c9bc3cf 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/mtd/nand.h>
 
 #include <asm/mach-types.h>
 #include <plat/gpmc.h>
@@ -83,6 +84,18 @@
 #define ENABLE_PREFETCH		(0x1 << 7)
 #define DMA_MPU_MODE		2
 
+/* GPMC ecc engine settings for read */
+#define BCH_WRAPMODE_1		1	/* BCH wrap mode 6 */
+#define BCH8R_ECC_SIZE0		0x1a	/* ecc_size0 = 26 */
+#define BCH8R_ECC_SIZE1		0x2	/* ecc_size1 = 2 */
+#define BCH4R_ECC_SIZE0		0xd	/* ecc_size0 = 13 */
+#define BCH4R_ECC_SIZE1		0x1	/* ecc_size1 = 1 4bit padding in BCH4 */
+
+/* GPMC ecc engine settings for write */
+#define BCH_WRAPMODE_6		6	/* BCH wrap mode 6 */
+#define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
+#define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
+
 /* XXX: Only NAND irq has been considered,currently these are the only ones used
  */
 #define	GPMC_NR_IRQ		2
@@ -1119,7 +1132,8 @@ EXPORT_SYMBOL_GPL(gpmc_init_hwecc_bch);
 int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
 			  int nerrors)
 {
-	unsigned int val;
+	unsigned int val, wr_mode;
+	unsigned int ecc_size1, ecc_size0;
 
 	/* check if ecc module is in use */
 	if (gpmc_ecc_used != -EINVAL)
@@ -1130,18 +1144,35 @@ int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
 	/* clear ecc and enable bits */
 	gpmc_write_reg(GPMC_ECC_CONTROL, 0x1);
 
-	/*
-	 * When using BCH, sector size is hardcoded to 512 bytes.
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
-	 */
-	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (32 << 22) | (0 << 12));
+	/*  When using BCH, sector size is hard coded to 512 bytes. */
+	if ((mode == NAND_ECC_READ) && (nsectors != 1)) {
+		/*
+		 * Here we are using wrapping mode 1 for reading, for
+		 * supporting multi sector reading.
+		 * Read mode, ECC engine enabled for valid ecc_size0 nibbles
+		 * & disabled for ecc_size1 nibbles.
+		 */
+		ecc_size0 = (nerrors == 8) ? BCH8R_ECC_SIZE0 : BCH4R_ECC_SIZE0;
+		ecc_size1 = (nerrors == 8) ? BCH8R_ECC_SIZE1 : BCH4R_ECC_SIZE1;
+		wr_mode = BCH_WRAPMODE_1;
+	} else {
+		/*
+		 * Here we are using wrapping mode 6 for writing,
+		 * ECC engine enabled for valid ecc_size0 nibbles
+		 * & disabled for ecc_size1 nibbles.
+		 */
+		ecc_size0 = BCH_ECC_SIZE0;
+		ecc_size1 = BCH_ECC_SIZE1;
+		wr_mode = BCH_WRAPMODE_6;
+	}
+
+	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (ecc_size1 << 22) |
+			(ecc_size0 << 12));
 
 	/* BCH configuration */
 	val = ((1                        << 16) | /* enable BCH */
 	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
-	       (0x06                     <<  8) | /* wrap mode = 6 */
+	       (wr_mode                  <<  8) | /* wrap mode = 6 or 1 */
 	       (dev_width                <<  7) | /* bus width */
 	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
 	       (cs                       <<  1) | /* ECC CS */
@@ -1154,6 +1185,77 @@ int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
 EXPORT_SYMBOL_GPL(gpmc_enable_hwecc_bch);
 
 /**
+ * gpmc_calculate_ecc_bch	- Generate ecc bytes per block of 512 data bytes for entire page
+ * @cs:  chip select number
+ * @dat: The pointer to data on which ECC is computed
+ * @ecc: The ECC output buffer
+ */
+int gpmc_calculate_ecc_bch(int cs, const u_char *dat, u_char *ecc)
+{
+	int i, eccbchtsel;
+	u32 nsectors, reg, bch_val1, bch_val2, bch_val3, bch_val4;
+
+	if (gpmc_ecc_used != cs)
+		return -EINVAL;
+
+	/* read number of sectors for ecc to be calculated */
+	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
+	/*
+	 * find BCH scheme used
+	 * 0 -> BCH4
+	 * 1 -> BCH8
+	 */
+	eccbchtsel = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 12) & 0x3);
+
+	/* update ecc bytes for entire page */
+	for (i = 0; i < nsectors; i++) {
+
+		reg = GPMC_ECC_BCH_RESULT_0 + 16 * i;
+
+		/* Read hw-computed remainder */
+		bch_val1 = gpmc_read_reg(reg + 0);
+		bch_val2 = gpmc_read_reg(reg + 4);
+		if (eccbchtsel) {
+			bch_val3 = gpmc_read_reg(reg + 8);
+			bch_val4 = gpmc_read_reg(reg + 12);
+		}
+
+		if (eccbchtsel) {
+			/* BCH8 ecc scheme */
+			*ecc++ = (bch_val4 & 0xFF);
+			*ecc++ = ((bch_val3 >> 24) & 0xFF);
+			*ecc++ = ((bch_val3 >> 16) & 0xFF);
+			*ecc++ = ((bch_val3 >> 8) & 0xFF);
+			*ecc++ = (bch_val3 & 0xFF);
+			*ecc++ = ((bch_val2 >> 24) & 0xFF);
+			*ecc++ = ((bch_val2 >> 16) & 0xFF);
+			*ecc++ = ((bch_val2 >> 8) & 0xFF);
+			*ecc++ = (bch_val2 & 0xFF);
+			*ecc++ = ((bch_val1 >> 24) & 0xFF);
+			*ecc++ = ((bch_val1 >> 16) & 0xFF);
+			*ecc++ = ((bch_val1 >> 8) & 0xFF);
+			*ecc++ = (bch_val1 & 0xFF);
+			/* 14th byte of ecc not used */
+			*ecc++ = 0;
+		} else {
+			/* BCH4 ecc scheme */
+			*ecc++ = ((bch_val2 >> 12) & 0xFF);
+			*ecc++ = ((bch_val2 >> 4) & 0xFF);
+			*ecc++ = (((bch_val2 & 0xF) << 4) |
+					((bch_val1 >> 28) & 0xF));
+			*ecc++ = ((bch_val1 >> 20) & 0xFF);
+			*ecc++ = ((bch_val1 >> 12) & 0xFF);
+			*ecc++ = ((bch_val1 >> 4) & 0xFF);
+			*ecc++ = ((bch_val1 & 0xF) << 4);
+		}
+	}
+
+	gpmc_ecc_used = -EINVAL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch);
+
+/**
  * gpmc_calculate_ecc_bch4 - Generate 7 ecc bytes per sector of 512 data bytes
  * @cs:  chip select number
  * @dat: The pointer to data on which ecc is computed
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 2e6e259..c916510 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -185,6 +185,7 @@ int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
 			  int nerrors);
 int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc);
 int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc);
+int gpmc_calculate_ecc_bch(int cs, const u_char *dat, u_char *ecc);
 #endif /* CONFIG_ARCH_OMAP3 */
 
 #endif
-- 
1.7.0.4



From avinashphilip at ti.com  Wed Oct  3 10:29:49 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 3 Oct 2012 19:59:49 +0530
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1349274589-11389-5-git-send-email-avinashphilip@ti.com>

ELM module can be used for error correction of BCH 4 & 8 bit. Also
support read & write page in one shot by adding custom read_page &
write_page methods. This helps in optimizing code.

New structure member "is_elm_used" is added to know the status of
whether the ELM module is used for error correction or not.

Note:
ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
with RBL ECC layout, even though the requirement was only 13 byte. This
results a common ecc layout across RBL, U-boot & Linux.

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
---
:100644 100644 af511a9... 8fd6ddb... M	drivers/mtd/nand/omap2.c
:100644 100644 1a68c1e... 5b7054e... M	include/linux/platform_data/mtd-nand-omap2.h
 drivers/mtd/nand/omap2.c                     |  359 +++++++++++++++++++++++---
 include/linux/platform_data/mtd-nand-omap2.h |    1 +
 2 files changed, 328 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index af511a9..8fd6ddb 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -30,6 +30,7 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
+#include <linux/platform_data/elm.h>
 
 #define	DRIVER_NAME	"omap2-nand"
 #define	OMAP_NAND_TIMEOUT_MS	5000
@@ -114,6 +115,12 @@
 #define BCH8_MAX_ERROR		8	/* upto 8 bit coorectable */
 #define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */
 
+#define SECTOR_BYTES		512
+/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
+#define BCH4_BIT_PAD		4
+#define BCH8_ECC_MAX		((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8)
+#define BCH4_ECC_MAX		((SECTOR_BYTES + BCH4_SIZE) * 8)
+
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -153,6 +160,8 @@ struct omap_nand_info {
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	struct bch_control             *bch;
 	struct nand_ecclayout           ecclayout;
+	bool				is_elm_used;
+	struct device			*elm_dev;
 #endif
 };
 
@@ -892,6 +901,138 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat,
 	return stat;
 }
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+/**
+ * omap_elm_correct_data - corrects page data area in case error reported
+ * @mtd:	MTD device structure
+ * @dat:	page data
+ * @read_ecc:	ecc read from nand flash
+ * @calc_ecc:	ecc read from HW ECC registers
+ *
+ * Check the read ecc vector from OOB area to see the page is flashed.
+ * If flashed, check any error reported by checking calculated ecc vector.
+ * For non error page, calculated ecc will be zero. For error pages,
+ * a non-zero valid syndrome polynomial reported in calculated ecc vector.
+ * Pass this non-zero syndrome polynomial to 'elm_decode_bch_error_page'
+ * with elm error vector updated for error reported sectors.
+ * On returning from this function, elm error vector updated with
+ * - number of correctable errors, error location if correctable.
+ * - if pages are non-correctable, updated with elm error vector
+ *   error uncorrectable.
+ */
+static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
+				u_char *read_ecc, u_char *calc_ecc)
+{
+	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
+			mtd);
+	int eccsteps = info->nand.ecc.steps;
+	int i , j, stat = 0;
+	int eccsize, eccflag, size;
+	struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
+	u_char *ecc_vec = calc_ecc;
+	enum bch_ecc type;
+	bool is_error_reported = false;
+
+	/* initialize elm error vector to zero */
+	memset(err_vec, 0, sizeof(err_vec));
+	if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
+		size = BCH8_SIZE;
+		eccsize = BCH8_ECC_OOB_BYTES;
+		type = BCH8_ECC;
+	} else {
+		size = BCH4_SIZE;
+		eccsize = BCH4_SIZE;
+		type = BCH4_ECC;
+	}
+
+	for (i = 0; i < eccsteps ; i++) {
+		eccflag = 0;	/* initialize eccflag */
+
+		for (j = 0; (j < eccsize); j++) {
+			if (read_ecc[j] != 0xFF) {
+				eccflag = 1;	/* data area is flashed */
+				break;
+			}
+		}
+
+		/* check calculated ecc if data area is flashed */
+		if (eccflag == 1) {
+			eccflag = 0;
+			/*
+			 * check any error reported, in case of error
+			 * non zero ecc reported.
+			 */
+			for (j = 0; (j < eccsize); j++) {
+				if (calc_ecc[j] != 0) {
+					/* non zero ecc, error present */
+					eccflag = 1;
+					break;
+				}
+			}
+		}
+
+		/* update elm error vector */
+		if (eccflag == 1) {
+			err_vec[i].error_reported = true;
+			is_error_reported = true;
+		}
+
+		/* update the ecc vector */
+		calc_ecc = calc_ecc + size;
+		read_ecc = read_ecc + size;
+	}
+
+	/* Check if any error reported */
+	if (!is_error_reported)
+		return 0;
+
+	/* decode BCH error using ELM module */
+	elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
+
+	for (i = 0; i < eccsteps; i++) {
+		if (err_vec[i].error_reported) {
+			for (j = 0; j < err_vec[i].error_count; j++) {
+				u32 bit_pos, byte_pos, error_max, pos;
+
+				if (type == BCH8_ECC)
+					error_max = BCH8_ECC_MAX;
+				else
+					error_max = BCH4_ECC_MAX;
+
+				if (info->nand.ecc.strength == BCH8_MAX_ERROR)
+					pos = err_vec[i].error_loc[j];
+				else
+					/* add 4 to take care 4 bit padding */
+					pos = err_vec[i].error_loc[j] +
+						BCH4_BIT_PAD;
+
+				/* calculate bit position of error */
+				bit_pos = pos % 8;
+				/* calculate byte position of error */
+				byte_pos = (error_max - pos - 1) / 8;
+
+				if (pos < error_max)
+					dat[byte_pos] ^= 1 << bit_pos;
+				/* else, not interested to correct ecc */
+			}
+
+			/* update number of correctable errors */
+			stat += err_vec[i].error_count;
+		}
+
+		/* update page data with sector size */
+		dat += info->nand.ecc.size;
+	}
+
+	for (i = 0; i < eccsteps; i++)
+		/* return error if uncorrectable error present */
+		if (err_vec[i].error_uncorrectable)
+			return -EINVAL;
+
+	return stat;
+}
+#endif
+
 /**
  * omap_calcuate_ecc - Generate non-inverted ECC bytes.
  * @mtd: MTD device structure
@@ -1039,14 +1180,45 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 
 	nerrors = info->nand.ecc.strength;
 	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	if (info->is_elm_used) {
+		/*
+		 * Program GPMC to perform correction on (steps * 512) byte
+		 * sector at a time.
+		 */
+		gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width,
+				info->nand.ecc.steps, nerrors);
+		return;
+	}
+#endif
 	/*
-	 * Program GPMC to perform correction on one 512-byte sector at a time.
-	 * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
-	 * gives a slight (5%) performance gain (but requires additional code).
+	 * Program GPMC to perform correction on one 512-byte sector at
+	 * a time.
 	 */
-	(void)gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width, 1, nerrors);
+	(void)gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width, 1,
+				nerrors);
 }
 
+
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+/**
+ * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
+ * @mtd:	MTD device structure
+ * @dat:	The pointer to data on which ecc is computed
+ * @ecc_code:	The ecc_code buffer
+ *
+ * support reading og BCH4/8 ecc vectors for the page
+ */
+static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
+				    u_char *ecc_code)
+{
+	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
+			mtd);
+
+	return gpmc_calculate_ecc_bch(info->gpmc_cs, dat, ecc_code);
+}
+#endif
+
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1121,6 +1293,90 @@ static void omap3_free_bch(struct mtd_info *mtd)
 	}
 }
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+/**
+ * omap_write_page_bch - BCH ecc based write page function for entire page
+ * @mtd:		mtd info structure
+ * @chip:		nand chip info structure
+ * @buf:		data buffer
+ * @oob_required:	must write chip->oob_poi to OOB
+ *
+ * Custom write page method evolved to support multi sector writing in one shot
+ */
+static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				  const uint8_t *buf, int oob_required)
+{
+	int i;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	/*
+	 * setting ecc vector with zero to support RBL compatibility.
+	 * RBL requires 14 byte of ecc with 14 byte as zero
+	 * even though BCH8 requires only 13 byte of ecc bytes.
+	 */
+	memset(ecc_calc, 0x0, chip->ecc.total);
+	chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+	chip->write_buf(mtd, buf, mtd->writesize);
+	chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
+}
+
+/**
+ * omap_read_page_bch - BCH ecc based page read function for entire page
+ * @mtd:		mtd info structure
+ * @chip:		nand chip info structure
+ * @buf:		buffer to store read data
+ * @oob_required:	caller requires OOB data read to chip->oob_poi
+ * @page:		page number to read
+ *
+ * For BCH ecc scheme, GPMC used for syndrome calculation and ELM module
+ * used for error correction.
+ * Custom method evolved to support ELM error correction. On reading page
+ * data area is read along with OOB data with ecc engine enabled. ecc vector
+ * updated after read of OOB data. For non error pages ecc vector reported as
+ * zero.
+ */
+static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *oob = &chip->oob_poi[eccpos[0]];
+	uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
+	int stat;
+
+	/* enable GPMC ecc engine */
+	chip->ecc.hwctl(mtd, NAND_ECC_READ);
+	/* read data */
+	chip->read_buf(mtd, buf, mtd->writesize);
+
+	/* read oob bytes */
+	chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
+	chip->read_buf(mtd, oob, chip->ecc.total);
+
+	/* calculate ecc bytes */
+	chip->ecc.calculate(mtd, buf, ecc_calc);
+
+	memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+
+	stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
+
+	if (stat < 0)
+		mtd->ecc_stats.failed++;
+	else
+		mtd->ecc_stats.corrected += stat;
+
+	return 0;
+}
+#endif
+
 /**
  * omap3_init_bch - Initialize BCH ECC
  * @mtd: MTD device structure
@@ -1146,35 +1402,62 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 		goto fail;
 	}
 
-	/* initialize GPMC BCH engine */
-	ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
-	if (ret)
-		goto fail;
-
-	/* software bch library is only used to detect and locate errors */
-	info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
-	if (!info->bch)
-		goto fail;
+	info->nand.ecc.size = 512;
+	info->nand.ecc.hwctl = omap3_enable_hwecc_bch;
+	info->nand.ecc.mode = NAND_ECC_HW;
+	info->nand.ecc.strength = hw_errors;
 
-	info->nand.ecc.size    = 512;
-	info->nand.ecc.hwctl   = omap3_enable_hwecc_bch;
-	info->nand.ecc.correct = omap3_correct_data_bch;
-	info->nand.ecc.mode    = NAND_ECC_HW;
+	if (info->is_elm_used && (mtd->writesize <= 4096)) {
+		enum bch_ecc bch_type;
 
-	/*
-	 * The number of corrected errors in an ecc block that will trigger
-	 * block scrubbing defaults to the ecc strength (4 or 8).
-	 * Set mtd->bitflip_threshold here to define a custom threshold.
-	 */
+		if (hw_errors == BCH8_MAX_ERROR) {
+			bch_type = BCH8_ECC;
+			info->nand.ecc.bytes = BCH8_SIZE;
+		} else {
+			bch_type = BCH4_ECC;
+			info->nand.ecc.bytes = BCH4_SIZE;
+		}
 
-	if (max_errors == 8) {
-		info->nand.ecc.strength  = 8;
-		info->nand.ecc.bytes     = 13;
-		info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
+		info->nand.ecc.correct = omap_elm_correct_data;
+		info->nand.ecc.calculate = omap3_calculate_ecc_bch;
+		info->nand.ecc.read_page = omap_read_page_bch;
+		info->nand.ecc.write_page = omap_write_page_bch;
+		info->elm_dev = elm_request(bch_type);
+		if (!info->elm_dev) {
+			pr_err("Request to elm module failed\n");
+			goto fail;
+		}
 	} else {
-		info->nand.ecc.strength  = 4;
-		info->nand.ecc.bytes     = 7;
-		info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
+
+		/* initialize GPMC BCH engine */
+		ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
+		if (ret)
+			goto fail;
+
+		/*
+		 * software bch library is only used to detect and
+		 * locateerrors
+		 */
+		info->bch = init_bch(13, max_errors,
+				0x201b /* hw polynomial */);
+		if (!info->bch)
+			goto fail;
+
+		info->nand.ecc.correct = omap3_correct_data_bch;
+
+		/*
+		 * The number of corrected errors in an ecc block that will
+		 * trigger block scrubbing defaults to the ecc strength (4 or 8)
+		 * Set mtd->bitflip_threshold here to define a custom threshold.
+		 */
+
+		if (max_errors == 8) {
+			info->nand.ecc.bytes = 13;
+			info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
+		} else {
+			info->nand.ecc.bytes = 7;
+			info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
+		}
 	}
 
 	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
@@ -1190,7 +1473,7 @@ fail:
  */
 static int omap3_init_bch_tail(struct mtd_info *mtd)
 {
-	int i, steps;
+	int i, steps, offset;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 	struct nand_ecclayout *layout = &info->ecclayout;
@@ -1212,11 +1495,20 @@ static int omap3_init_bch_tail(struct mtd_info *mtd)
 		goto fail;
 	}
 
+	/* ECC layout compatible with RBL for BCH8 */
+	if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE))
+		offset = 2;
+	else
+		offset = mtd->oobsize - layout->eccbytes;
 	/* put ecc bytes at oob tail */
 	for (i = 0; i < layout->eccbytes; i++)
-		layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i;
+		layout->eccpos[i] = offset + i;
+
+	if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE))
+		layout->oobfree[0].offset = 2 + layout->eccbytes * steps;
+	else
+		layout->oobfree[0].offset = 2;
 
-	layout->oobfree[0].offset = 2;
 	layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes;
 	info->nand.ecc.layout = layout;
 
@@ -1279,6 +1571,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
 
 	info->nand.options	= pdata->devsize;
 	info->nand.options	|= NAND_SKIP_BBTSCAN;
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	info->is_elm_used	= pdata->is_elm_used;
+#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 1a68c1e..5b7054e 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -28,6 +28,7 @@ struct omap_nand_platform_data {
 	int			devsize;
 	enum omap_ecc           ecc_opt;
 	struct gpmc_nand_regs	reg;
+	bool			is_elm_used;
 };
 
 /* minimum size for IO mapping */
-- 
1.7.0.4



From pmeerw at pmeerw.net  Wed Oct  3 11:10:46 2012
From: pmeerw at pmeerw.net (Peter Meerwald)
Date: Wed, 3 Oct 2012 17:10:46 +0200 (CEST)
Subject: [PATCH 2/4] mtd: devices: elm: Add support for ELM error
 correction
In-Reply-To: <1349274589-11389-3-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-3-git-send-email-avinashphilip@ti.com>
Message-ID: <alpine.DEB.2.01.1210031701440.32543@pmeerw.net>


some minor nitpicks below

> Platforms containing the ELM module can be used to correct errors
> reported by BCH 4, 8 & 16 bit ECC scheme. For now only 4 & 8 bit
> support is added.
> 
> Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
> Cc: Grant Likely <grant.likely at secretlab.ca>
> Cc: Rob Herring <rob.herring at calxeda.com>
> Cc: Rob Landley <rob at landley.net>
> ---
> :000000 100644 0000000... b88ee83... A	Documentation/devicetree/bindings/mtd/elm.txt
> :100644 100644 395733a... 0f6a94b... M	drivers/mtd/devices/Makefile
> :000000 100644 0000000... 802b572... A	drivers/mtd/devices/elm.c
> :000000 100644 0000000... eb53163... A	include/linux/platform_data/elm.h
>  Documentation/devicetree/bindings/mtd/elm.txt |   18 +
>  drivers/mtd/devices/Makefile                  |    4 +-
>  drivers/mtd/devices/elm.c                     |  440 +++++++++++++++++++++++++
>  include/linux/platform_data/elm.h             |   60 ++++
>  4 files changed, 521 insertions(+), 1 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/elm.txt b/Documentation/devicetree/bindings/mtd/elm.txt
> new file mode 100644
> index 0000000..b88ee83
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/elm.txt
> @@ -0,0 +1,18 @@
> +Error location module
> +
> +Required properties:
> +- compatible: Must be "ti,elm"
> +- reg: physical base address and size of the registers map.
> +- interrupts: Interrupt number for the elm.
> +- interrupt-parent: The parent interrupt controller
> +
> +Optional properties:
> +- ti,hwmods: Name of the hwmod associated to the elm
> +
> +Example:
> +elm: elm at 0 {
> +	compatible	= "ti,elm";
> +	reg = <0x48080000 0x2000>;
> +	interrupt-parent = <&intc>;
> +	interrupts = <4>;
> +};
> diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
> index 395733a..0f6a94b 100644
> --- a/drivers/mtd/devices/Makefile
> +++ b/drivers/mtd/devices/Makefile
> @@ -17,8 +17,10 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
>  obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
>  obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
>  obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
> +obj-$(CONFIG_MTD_NAND_OMAP2)	+= elm.o
>  obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
>  obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
>  obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
>  
> -CFLAGS_docg3.o			+= -I$(src)
> \ No newline at end of file
> +
> +CFLAGS_docg3.o			+= -I$(src)
> diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
> new file mode 100644
> index 0000000..802b572
> --- /dev/null
> +++ b/drivers/mtd/devices/elm.c
> @@ -0,0 +1,440 @@
> +/*
> + * Error Location Module
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/platform_data/elm.h>
> +
> +#define ELM_IRQSTATUS			0x018
> +#define ELM_IRQENABLE			0x01c
> +#define ELM_LOCATION_CONFIG		0x020
> +#define ELM_PAGE_CTRL			0x080
> +#define ELM_SYNDROME_FRAGMENT_0		0x400
> +#define ELM_SYNDROME_FRAGMENT_6		0x418
> +#define ELM_LOCATION_STATUS		0x800
> +#define ELM_ERROR_LOCATION_0		0x880
> +
> +/* ELM Interrupt Status Register */
> +#define INTR_STATUS_PAGE_VALID		BIT(8)
> +
> +/* ELM Interrupt Enable Register */
> +#define INTR_EN_PAGE_MASK		BIT(8)
> +
> +/* ELM Location Configuration Register */
> +#define ECC_BCH_LEVEL_MASK		0x3
> +
> +/* ELM syndrome */
> +#define ELM_SYNDROME_VALID		BIT(16)
> +
> +/* ELM_LOCATION_STATUS Register */
> +#define ECC_CORRECTABLE_MASK		BIT(8)
> +#define ECC_NB_ERRORS_MASK		0x1f
> +
> +/* ELM_ERROR_LOCATION_0-15 Registers */
> +#define ECC_ERROR_LOCATION_MASK		0x1fff
> +
> +#define ELM_ECC_SIZE			0x7ff
> +
> +#define SYNDROME_FRAGMENT_REG_SIZE	0x40
> +#define ERROR_LOCATION_SIZE		0x100
> +#define MAX_BCH_ELM_ERROR		16
> +#define ELM_FRAGMENT_REG		7
> +
> +typedef u32 syn_t[ELM_FRAGMENT_REG];
> +typedef u32 elm_error_t[MAX_BCH_ELM_ERROR];
> +
> +struct elm_info {
> +	struct device *dev;
> +	void __iomem *elm_base;
> +	struct completion elm_completion;
> +	struct list_head list;
> +	enum bch_ecc bch_type;
> +};
> +
> +static LIST_HEAD(elm_devices);
> +
> +static void elm_write_reg(void *offset, u32 val)
> +{
> +	writel(val, offset);
> +}
> +
> +static u32 elm_read_reg(void *offset)
> +{
> +	return readl(offset);
> +}
> +
> +/**
> + * elm_config - Configure ELM module
> + * @info:	elm info
> + */
> +static void elm_config(struct elm_info *info)
> +{
> +	u32 reg_val;
> +
> +	reg_val = (info->bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
> +	elm_write_reg(info->elm_base + ELM_LOCATION_CONFIG, reg_val);
> +}
> +
> +/**
> + * elm_configure_page_mode - Enable/Disable page mode
> + * @info:	elm info
> + * @index:	index number of syndrome fragment vector
> + * @enable:	enable/disable flag for page mode
> + *
> + * Enable page mode for syndrome fragment index
> + */
> +static void elm_configure_page_mode(struct elm_info *info, int index,
> +		bool enable)
> +{
> +	u32 reg_val;
> +
> +	reg_val = elm_read_reg(info->elm_base + ELM_PAGE_CTRL);
> +	if (enable)
> +		reg_val |= BIT(index);	/* enable page mode */
> +	else
> +		reg_val &= ~BIT(index);	/* disable page mode */
> +
> +	elm_write_reg(info->elm_base + ELM_PAGE_CTRL, reg_val);
> +}
> +
> +static void rearrange_bch4(u8 *syndrome)
> +{
> +	/*
> +	 * BCH4 has 52 bit used for ecc, but OOB stored with
> +	 * nibble 0 appended, removes appended 0 nibble
> +	 */
> +	u64 *dst = (u64 *)syndrome;
> +	*dst >>= 4;
> +}
> +
> +/**
> + * elm_reverse_eccdata - Reverse ecc data
> + * @info:	elm info
> + * @ecc_data:	buffer for calculated ecc
> + * @syndrome:	buffer for syndrome polynomial
> + *
> + * ecc_data has to be reversed for syndrome vector
> + */
> +static void elm_reverse_eccdata(struct elm_info *info, u8 *ecc_data,
> +		u8 *syndrome)
> +{
> +	int i;
> +	int bch_size = info->bch_type ? BCH8_ECC_OOB_BYTES : BCH4_SIZE;
> +
> +	for (i = 0; i < bch_size; i++)
> +		syndrome[bch_size - 1 - i] = ecc_data[i];
> +
> +	/*
> +	 * syndrome polynomial to be rearranged for BCH 4 ecc scheme as 52
> +	 * bits being used and 4 bits being appended in syndrome vector
> +	 */
> +	if (info->bch_type == BCH4_ECC)
> +		rearrange_bch4(syndrome);
> +}
> +
> +/**
> + * elm_load_syndrome - Load ELM syndrome reg
> + * @info:	elm info
> + * @index:	syndrome fragment index
> + * @syndrome:	Syndrome polynomial
> + *
> + * Load syndrome fragment registers with syndrome polynomial
> + */
> +static void elm_load_syndrome(struct elm_info *info, int index, u8 *syndrome)
> +{
> +	int i;
> +	int max = info->bch_type ? BCH8_SYNDROME_SIZE : BCH4_SYNDROME_SIZE;
> +	void *syn_frag_base = info->elm_base + ELM_SYNDROME_FRAGMENT_0;
> +	syn_t *syn_fragment;
> +	u32 reg_val;
> +
> +	elm_configure_page_mode(info, index, true);
> +	syn_fragment = syn_frag_base + SYNDROME_FRAGMENT_REG_SIZE * index;
> +
> +	for (i = 0; i < max; i++) {
> +		reg_val = syndrome[0] | syndrome[1] << 8 | syndrome[2] << 16 |
> +			syndrome[3] << 24;
> +		elm_write_reg(*syn_fragment + i, reg_val);
> +		/* Update syndrome polynomial pointer */
> +		syndrome += 4;
> +	}
> +}
> +
> +/**
> + * elm_start_processing - start elm syndrome processing
> + * @info:	elm info
> + * @err_vec:	elm error vectors
> + *
> + * Set syndrome valid bit for syndrome fragment registers for which
> + * elm syndrome fragment registers are loaded. This enables elm module
> + * to start processing syndrome vectors.
> + */
> +static void elm_start_processing(struct elm_info *info,
> +		struct elm_errorvec *err_vec)
> +{
> +	int i;
> +	void *offset;
> +	u32 reg_val;
> +
> +	/*
> +	 * Set syndrome vector valid so that ELM module will process it for
> +	 * vectors error is reported
> +	 */
> +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
> +		if (err_vec[i].error_reported) {
> +			offset = info->elm_base + ELM_SYNDROME_FRAGMENT_6 + i *
> +				SYNDROME_FRAGMENT_REG_SIZE;
> +			reg_val = elm_read_reg(offset);
> +			reg_val |= ELM_SYNDROME_VALID;
> +			elm_write_reg(offset, reg_val);
> +		}
> +	}
> +}
> +
> +/**
> + * elm_error_correction - locate correctable error position
> + * @info:	elm info
> + * @err_vec:	elm error vectors
> + *
> + * On completion of processing by elm module, error location status
> + * register updated with correctable/uncorrectable error information.
> + * In case of correctable errors, number of errors located from
> + * elm location status register & read the these many positions from

should probably be: "... & read the positions from ..."?

> + * elm error location register.
> + */
> +static void elm_error_correction(struct elm_info *info,
> +		struct elm_errorvec *err_vec)
> +{
> +	int i, j, errors = 0;
> +	void *err_loc_base = info->elm_base + ELM_ERROR_LOCATION_0;
> +	elm_error_t *err_loc;
> +	void *offset;
> +	u32 reg_val;
> +
> +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
> +		/* check error reported */
> +		if (err_vec[i].error_reported) {
> +			offset = info->elm_base + ELM_LOCATION_STATUS +
> +				i * ERROR_LOCATION_SIZE;
> +			reg_val = elm_read_reg(offset);
> +			/* check correctable error or not */
> +			if (reg_val & ECC_CORRECTABLE_MASK) {
> +				err_loc = err_loc_base +
> +					i * ERROR_LOCATION_SIZE;
> +				/* read count of correctable errors */
> +				err_vec[i].error_count = reg_val &
> +					ECC_NB_ERRORS_MASK;
> +
> +				/* update the error locations in error vector */
> +				for (j = 0; j < err_vec[i].error_count; j++) {
> +
> +					reg_val = elm_read_reg(*err_loc + j);
> +					err_vec[i].error_loc[j] = reg_val &
> +						ECC_ERROR_LOCATION_MASK;
> +				}
> +
> +				errors += err_vec[i].error_count;
> +			} else {
> +				err_vec[i].error_uncorrectable++;
> +			}

extra braces above

> +
> +			/* clearing interrupts for processed error vectors */
> +			elm_write_reg(info->elm_base + ELM_IRQSTATUS, BIT(i));
> +
> +			/* disable page mode */
> +			elm_configure_page_mode(info, i, false);
> +		}
> +	}
> +
> +	return;
> +}
> +
> +/**
> + * elm_decode_bch_error_page - Locate error position
> + * @info:	elm info

should be dev, not info

> + * @ecc_calc:	calculated ECC bytes from GPMC
> + * @err_vec:	elm error vectors
> + *
> + * Called with one or greater reported and is vectors with error reported
> + * is updated in err_vec[].error_reported
> + */

I do not understand the statement "Called with one ..."

> +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
> +		struct elm_errorvec *err_vec)
> +{
> +	int i;
> +	u8 syndrome[BCH_MAX_ECC_BYTES_PER_SECTOR] = {0}, *syn_p;
> +	struct elm_info *info = dev_get_drvdata(dev);
> +	u32 reg_val;
> +
> +	/* enable page mode interrupt */
> +	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
> +	elm_write_reg(info->elm_base + ELM_IRQSTATUS,
> +			reg_val & INTR_STATUS_PAGE_VALID);
> +	elm_write_reg(info->elm_base + ELM_IRQENABLE, INTR_EN_PAGE_MASK);
> +
> +	syn_p = syndrome;
> +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
> +		if (err_vec[i].error_reported) {
> +			elm_reverse_eccdata(info, ecc_calc, syn_p);
> +			elm_load_syndrome(info, i, syn_p);
> +		}
> +
> +		ecc_calc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
> +		syn_p += OOB_SECTOR_SIZE;
> +	}
> +
> +	elm_start_processing(info, err_vec);
> +
> +	/*
> +	 * In case of error reported, wait for ELM module to finish
> +	 * locating error correction
> +	 */
> +	wait_for_completion(&info->elm_completion);
> +
> +	/* disable page mode interrupt */
> +	reg_val = elm_read_reg(info->elm_base + ELM_IRQENABLE);
> +	elm_write_reg(info->elm_base + ELM_IRQENABLE,
> +			reg_val & ~INTR_EN_PAGE_MASK);
> +	elm_error_correction(info, err_vec);
> +}
> +EXPORT_SYMBOL(elm_decode_bch_error_page);
> +
> +static irqreturn_t elm_isr(int this_irq, void *dev_id)
> +{
> +	u32 reg_val;
> +	struct elm_info *info = dev_id;
> +
> +	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
> +
> +	/* all error vectors processed */
> +	if (reg_val & INTR_STATUS_PAGE_VALID) {
> +		elm_write_reg(info->elm_base + ELM_IRQSTATUS,
> +				reg_val & INTR_STATUS_PAGE_VALID);
> +		complete(&info->elm_completion);
> +		return IRQ_HANDLED;
> +	}
> +
> +	return IRQ_NONE;
> +}
> +
> +struct device *elm_request(enum bch_ecc bch_type)
> +{
> +	struct elm_info *info;
> +
> +	list_for_each_entry(info, &elm_devices, list) {
> +		if (info && info->dev) {
> +				info->bch_type = bch_type;
> +				elm_config(info);
> +				return info->dev;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(elm_request);
> +
> +static int __devinit elm_probe(struct platform_device *pdev)
> +{
> +	int ret = 0;
> +	struct resource *res, *irq;
> +	struct elm_info *info;
> +
> +	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> +	if (!info) {
> +		dev_err(&pdev->dev, "failed to allocate memory\n");
> +		return -ENOMEM;
> +	}
> +
> +	info->dev = &pdev->dev;
> +
> +	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +	if (!irq) {
> +		dev_err(&pdev->dev, "no irq resource defined\n");
> +		return -ENODEV;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "no memory resource defined\n");
> +		return -ENODEV;
> +	}
> +
> +
> +	info->elm_base = devm_request_and_ioremap(&pdev->dev, res);
> +	if (!info->elm_base)
> +		return -EADDRNOTAVAIL;
> +
> +
> +	ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0,
> +			pdev->name, info);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start);
> +		return ret;
> +	}
> +
> +	pm_runtime_enable(&pdev->dev);
> +	if (pm_runtime_get_sync(&pdev->dev)) {
> +		ret = -EINVAL;
> +		pm_runtime_disable(&pdev->dev);
> +		dev_err(&pdev->dev, "can't enable clock\n");
> +		return ret;
> +	}
> +
> +	init_completion(&info->elm_completion);
> +	INIT_LIST_HEAD(&info->list);
> +	list_add(&info->list, &elm_devices);
> +	platform_set_drvdata(pdev, info);
> +	return ret;
> +}
> +
> +static int __devexit elm_remove(struct platform_device *pdev)
> +{
> +	pm_runtime_put_sync(&pdev->dev);
> +	pm_runtime_disable(&pdev->dev);
> +	platform_set_drvdata(pdev, NULL);
> +	return 0;
> +}
> +
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id elm_of_match[] = {
> +	{ .compatible = "ti,elm" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, elm_of_match);
> +#endif
> +
> +static struct platform_driver elm_driver = {
> +	.driver		= {
> +		.name	= "elm",
> +		.of_match_table = of_match_ptr(elm_of_match),
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= elm_probe,
> +	.remove		= __devexit_p(elm_remove),
> +};
> +
> +module_platform_driver(elm_driver);
> +
> +MODULE_DESCRIPTION("ELM driver for BCH error correction");
> +MODULE_AUTHOR("Texas Instruments");
> +MODULE_ALIAS("platform: elm");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
> new file mode 100644
> index 0000000..eb53163
> --- /dev/null
> +++ b/include/linux/platform_data/elm.h
> @@ -0,0 +1,60 @@
> +/*
> + * BCH Error Location Module
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef __ELM_H
> +#define __ELM_H
> +
> +enum bch_ecc {
> +	BCH4_ECC = 0,
> +	BCH8_ECC,
> +	BCH16_ECC,
> +};
> +
> +/* ELM support 8 error syndrome process */
> +#define ERROR_VECTOR_MAX		8
> +#define OOB_SECTOR_SIZE			16
> +
> +#define BCH_MAX_ECC_BYTES_PER_SECTOR	(OOB_SECTOR_SIZE * ERROR_VECTOR_MAX)
> +
> +#define BCH8_ECC_OOB_BYTES		13
> +/* RBL requires 14 byte even though BCH8 uses only 13 byte */

not sure what RBL is?

> +#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
> +#define BCH4_SIZE			7
> +
> +#define	BCH8_SYNDROME_SIZE		4	/* 13 bytes of ecc */
> +#define	BCH4_SYNDROME_SIZE		2	/* 7 bytes of ecc */
> +
> +/**
> + * struct elm_errorvec - error vector for elm
> + * @error_reported:		set true for vectors error is reported
> + *
> + * @error_count:		number of correctable errors in the sector
> + * @error_uncorrectable:	number of uncorrectable errors
> + * @error_loc:			buffer for error location
> + *
> + */
> +struct elm_errorvec {
> +	bool error_reported;
> +	int error_count;
> +	int error_uncorrectable;
> +	int error_loc[ERROR_VECTOR_MAX];
> +};
> +
> +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
> +		struct elm_errorvec *err_vec);
> +struct device *elm_request(enum bch_ecc bch_type);
> +#endif /* __ELM_H */
> 

-- 

Peter Meerwald
+43-664-2444418 (mobile)


From thomas.petazzoni at free-electrons.com  Wed Oct  3 14:14:47 2012
From: thomas.petazzoni at free-electrons.com (Thomas Petazzoni)
Date: Wed, 3 Oct 2012 20:14:47 +0200
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <1349191749-5247-1-git-send-email-richard@nod.at>
References: <1349191749-5247-1-git-send-email-richard@nod.at>
Message-ID: <20121003201447.18ad7d2e@skate>

Richard,

Here is a quick review, with only minor comments.

On Tue,  2 Oct 2012 17:29:09 +0200, Richard Weinberger wrote:

> +<h2><a name="L_fastmap">Fastmap</a></h2>
> +<p>
> +Fastmap is an experimental and optional UBI feature, which can be enabled
> +by setting CONFIG_MTD_UBI_FASTMAP to 'y'.
> +Once enabled UBI evaluates the module parameter
> +"fm_autoconvert". If it is set to 1 (default is 0) UBI automatically enables
> +fastmap for any attached image. This means UBI creates a new internal
> +volume with the fastmap data such that next time the fast attach mode can be
> +used.
> +In the default configuration UBI will use the information stored in this
> +fastmap volume to accelerate the attach procedure.
> +If you want to test fastmap, set fm_autoconvert to 1 and attach a volume.</p>

It would probably be good to explain what happens when
fm_autoconvert=0. I guess that images are then not automatically
converted, but then how does one creates a new image that has the
fastmap feature built-in? I haven't followed the whole discussion, are
changes to mtd-utils tools like ubinize planned?

> +<h4><a name="L_fastmap_compat">Backwards compatibility</a></h4>
> +<p>The fastmap on-disk data structure makes use of delete compatible volumes,
> +therefore fastmap enabled images are fully backwards compatible with UBI

backwards -> backward (but I'm not 100%, I'm not a native speaker)

> +implementaions which do not support fastmap. The kernel will remove the fastmap

implementations

> +volumes and continue with scanning.
> +This includes not only v3.6- but also v3.7+ with this option disabled.
> +</p>
> +
> +<h4><a name="L_fastmap_tech">Technical design</a></h4>
> +
> +<p>A on-disk fastmap contains all information needed to attach the whole image,
> +namely all erase counter values, a list of all PEBs and their state, a list of
> +all volumes and their current EBA, ...
> +To avoid too much writes of the fastmap it contains also a list of PEBs which

it also contains

> +may have changed and need a full scan while attaching.
> +This list is called "fastmap pool" and has a fixed sized, 5% of the total
> +amount of PEBs. Using this technique UBI needs to write the fastmap only if the
> +pool contains no free PEBs. Otherwise it would have to write the fastmap each
> +time when the EBA of a volume has changed.</p>

each time when the EBA -> each time the EBA

> +<p>A fastmap consists of a super block (also known as anchor PEB) and payload
> +data which can life on any PEB.

life -> live.

> +The anchor PEB has to be located within the first 64 PEBs on the MTD device.
> +It contains pointers to the remaining PEBs which carry the actual fastmap
> +data. On modern NAND chips the whole fastmap fits into a single PEB.
> +Hence, the anchor PEB points to itself.
> +After loading the fastmap data, UBI attach information structure is created
> +from it

Nitpick: missing dot at end of sentence.

> +The attach process works as follows:
> +<ol>
> +	<li>UBI tries to find the fastmap anchor PEB,
> +	if no anchor PEB was found UBI performs  traditional full scan</li>
> +	<li>It follows the pointers stored in the anchor PEB and reads
> +	the fastmap payload data</li>
> +	<li>Then it performs a traditional scan only on PEBs in the pool
> +	instead of all PEBs</li>
> +</ol>
> +If UBI detects that the used fastmap is invalid or corrupted it automatically
> +falls back to scanning mode and performsa full scan.

performsa -> performs a

> +Using a CRC32 checksum and consistency checks of the internal UBI structures
> +UBI is able to detect whether a fastmap is invalid or not.
> +</p>
> +
> +<p>
> +A fastmap is written to the devices each time the fastmap pool becomes full
> +(no free PEBs are available), the volume layout changes or the image is
> +detached. One may wonder why writing at detach time is needed.
> +if UBI would not write a new fastmap at detach time all erase counter
> +modifications since the last fastmap are lost.

"since the last fastmap write" maybe?

> +</p>
> +
> +<h4><a name="L_fastmap_overhead">Overhead</a></h4>
> +<p>Is fastmap enabled UBI will reserve enough PEBs to carry two complete
> +fastmaps.

If fastmap is enabled UBI ...

> In practice on modern NAND chips two PEBs are reserved for fastmap.
> +</p>
> +<p>
> +There is also some runtime overhead, to guarantee that the new fastmap is valid
> +and conistent UBI has to take care that all IO which would cause EBA changes

consistent

> +are blocked while attaching. Depending on flash Chip this can take up to one

flash Chip -> flash chips

> +second. Therefore, fastmap makes only sense on fast and large flash devices
> +where a full scan takes too long. E.g. On 4GiB NAND chips a full scan takes
> +several seconds whereas a fast attach needs less than one second.</p>
>  
>  <h2><a name="L_ubidoc">More documentation</a></h2>
>  

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From ivan.djelic at parrot.com  Wed Oct  3 14:54:58 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Wed, 3 Oct 2012 20:54:58 +0200
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
Message-ID: <20121003185458.GA27502@parrot.com>

On Wed, Oct 03, 2012 at 03:29:48PM +0100, Philip, Avinash wrote:
> Add support for BCH ECC scheme to gpmc driver and also enabling multi
> sector read/write. This helps in doing single shot NAND page read and
> write.
> 
> ECC engine configurations
> BCH 4 bit support
> 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
> 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
> 13 and ecc_size1 as 1.
> 
> BCH 8 bit support
> 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
> 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
> 26 and ecc_size1 as 2.
> 
> Note: For BCH8 ECC bytes set to 14 to make compatible with RBL.
> 

Hi Philip,

I have a few comments/questions below,

(...)
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 72428bd..c9bc3cf 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -24,6 +24,7 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
> +#include <linux/mtd/nand.h>
>  
>  #include <asm/mach-types.h>
>  #include <plat/gpmc.h>
> @@ -83,6 +84,18 @@
>  #define ENABLE_PREFETCH		(0x1 << 7)
>  #define DMA_MPU_MODE		2
>  
> +/* GPMC ecc engine settings for read */
> +#define BCH_WRAPMODE_1		1	/* BCH wrap mode 6 */

Comment should say "mode 1".

(...)
>  /**
> + * gpmc_calculate_ecc_bch	- Generate ecc bytes per block of 512 data bytes for entire page
> + * @cs:  chip select number
> + * @dat: The pointer to data on which ECC is computed
> + * @ecc: The ECC output buffer
> + */
> +int gpmc_calculate_ecc_bch(int cs, const u_char *dat, u_char *ecc)
> +{
> +	int i, eccbchtsel;
> +	u32 nsectors, reg, bch_val1, bch_val2, bch_val3, bch_val4;
> +
> +	if (gpmc_ecc_used != cs)
> +		return -EINVAL;
> +
> +	/* read number of sectors for ecc to be calculated */
> +	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
> +	/*
> +	 * find BCH scheme used
> +	 * 0 -> BCH4
> +	 * 1 -> BCH8
> +	 */
> +	eccbchtsel = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 12) & 0x3);
> +
> +	/* update ecc bytes for entire page */
> +	for (i = 0; i < nsectors; i++) {
> +
> +		reg = GPMC_ECC_BCH_RESULT_0 + 16 * i;
> +
> +		/* Read hw-computed remainder */
> +		bch_val1 = gpmc_read_reg(reg + 0);
> +		bch_val2 = gpmc_read_reg(reg + 4);
> +		if (eccbchtsel) {
> +			bch_val3 = gpmc_read_reg(reg + 8);
> +			bch_val4 = gpmc_read_reg(reg + 12);
> +		}
> +
> +		if (eccbchtsel) {
> +			/* BCH8 ecc scheme */
> +			*ecc++ = (bch_val4 & 0xFF);
> +			*ecc++ = ((bch_val3 >> 24) & 0xFF);
> +			*ecc++ = ((bch_val3 >> 16) & 0xFF);
> +			*ecc++ = ((bch_val3 >> 8) & 0xFF);
> +			*ecc++ = (bch_val3 & 0xFF);
> +			*ecc++ = ((bch_val2 >> 24) & 0xFF);
> +			*ecc++ = ((bch_val2 >> 16) & 0xFF);
> +			*ecc++ = ((bch_val2 >> 8) & 0xFF);
> +			*ecc++ = (bch_val2 & 0xFF);
> +			*ecc++ = ((bch_val1 >> 24) & 0xFF);
> +			*ecc++ = ((bch_val1 >> 16) & 0xFF);
> +			*ecc++ = ((bch_val1 >> 8) & 0xFF);
> +			*ecc++ = (bch_val1 & 0xFF);
> +			/* 14th byte of ecc not used */
> +			*ecc++ = 0;
> +		} else {
> +			/* BCH4 ecc scheme */
> +			*ecc++ = ((bch_val2 >> 12) & 0xFF);
> +			*ecc++ = ((bch_val2 >> 4) & 0xFF);
> +			*ecc++ = (((bch_val2 & 0xF) << 4) |
> +					((bch_val1 >> 28) & 0xF));
> +			*ecc++ = ((bch_val1 >> 20) & 0xFF);
> +			*ecc++ = ((bch_val1 >> 12) & 0xFF);
> +			*ecc++ = ((bch_val1 >> 4) & 0xFF);
> +			*ecc++ = ((bch_val1 & 0xF) << 4);
> +		}
> +	}
> +
> +	gpmc_ecc_used = -EINVAL;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch);

Here you introduce a function very similar to gpmc_calculate_ecc_bch4 and
gpmc_calculate_ecc_bch8, but without the added benefit (IMHO) of the constant
polynomial that allows to get an ecc sequence of 0xFFs for a buffer filled with
0xFFs. Why ?
If using the ELM prevents you from reusing gpmc_calculate_ecc_bch[48], could you explain in which way ?

Best regards,
--
Ivan


From ivan.djelic at parrot.com  Wed Oct  3 15:20:45 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Wed, 3 Oct 2012 21:20:45 +0200
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
Message-ID: <20121003192044.GB27502@parrot.com>

On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
> ELM module can be used for error correction of BCH 4 & 8 bit. Also
> support read & write page in one shot by adding custom read_page &
> write_page methods. This helps in optimizing code.
> 
> New structure member "is_elm_used" is added to know the status of
> whether the ELM module is used for error correction or not.
> 
> Note:
> ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
> with RBL ECC layout, even though the requirement was only 13 byte. This
> results a common ecc layout across RBL, U-boot & Linux.
> 

See a few comments below,

(...)
> +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
> +                               u_char *read_ecc, u_char *calc_ecc)
> +{
> +       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> +                       mtd);
> +       int eccsteps = info->nand.ecc.steps;
> +       int i , j, stat = 0;
> +       int eccsize, eccflag, size;
> +       struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
> +       u_char *ecc_vec = calc_ecc;
> +       enum bch_ecc type;
> +       bool is_error_reported = false;
> +
> +       /* initialize elm error vector to zero */
> +       memset(err_vec, 0, sizeof(err_vec));
> +       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
> +               size = BCH8_SIZE;
> +               eccsize = BCH8_ECC_OOB_BYTES;
> +               type = BCH8_ECC;
> +       } else {
> +               size = BCH4_SIZE;
> +               eccsize = BCH4_SIZE;
> +               type = BCH4_ECC;
> +       }
> +
> +       for (i = 0; i < eccsteps ; i++) {
> +               eccflag = 0;    /* initialize eccflag */
> +
> +               for (j = 0; (j < eccsize); j++) {
> +                       if (read_ecc[j] != 0xFF) {
> +                               eccflag = 1;    /* data area is flashed */

Just a reminder: this way of checking if a page has been programmed is not robust to bitflips,
so you may get into trouble with UBIFS on a fairly recent device.

(...)
> @@ -1039,14 +1180,45 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
> 
>         nerrors = info->nand.ecc.strength;
>         dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +       if (info->is_elm_used) {
> +               /*
> +                * Program GPMC to perform correction on (steps * 512) byte
> +                * sector at a time.
> +                */
> +               gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width,
> +                               info->nand.ecc.steps, nerrors);
> +               return;
> +       }
> +#endif
>         /*
> -        * Program GPMC to perform correction on one 512-byte sector at a time.
> -        * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
> -        * gives a slight (5%) performance gain (but requires additional code).
> +        * Program GPMC to perform correction on one 512-byte sector at
> +        * a time.

Why removing the comment about 4-sector perf gain ? :-)

(...)
> @@ -1146,35 +1402,62 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
>                 goto fail;
>         }
> 
> -       /* initialize GPMC BCH engine */
> -       ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
> -       if (ret)
> -               goto fail;
> -
> -       /* software bch library is only used to detect and locate errors */
> -       info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
> -       if (!info->bch)
> -               goto fail;
> +       info->nand.ecc.size = 512;
> +       info->nand.ecc.hwctl = omap3_enable_hwecc_bch;
> +       info->nand.ecc.mode = NAND_ECC_HW;
> +       info->nand.ecc.strength = hw_errors;
> 
> -       info->nand.ecc.size    = 512;
> -       info->nand.ecc.hwctl   = omap3_enable_hwecc_bch;
> -       info->nand.ecc.correct = omap3_correct_data_bch;
> -       info->nand.ecc.mode    = NAND_ECC_HW;
> +       if (info->is_elm_used && (mtd->writesize <= 4096)) {
> +               enum bch_ecc bch_type;
> 
> -       /*
> -        * The number of corrected errors in an ecc block that will trigger
> -        * block scrubbing defaults to the ecc strength (4 or 8).
> -        * Set mtd->bitflip_threshold here to define a custom threshold.
> -        */
> +               if (hw_errors == BCH8_MAX_ERROR) {
> +                       bch_type = BCH8_ECC;
> +                       info->nand.ecc.bytes = BCH8_SIZE;
> +               } else {
> +                       bch_type = BCH4_ECC;
> +                       info->nand.ecc.bytes = BCH4_SIZE;
> +               }
> 
> -       if (max_errors == 8) {
> -               info->nand.ecc.strength  = 8;
> -               info->nand.ecc.bytes     = 13;
> -               info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
> +               info->nand.ecc.correct = omap_elm_correct_data;
> +               info->nand.ecc.calculate = omap3_calculate_ecc_bch;
> +               info->nand.ecc.read_page = omap_read_page_bch;
> +               info->nand.ecc.write_page = omap_write_page_bch;
> +               info->elm_dev = elm_request(bch_type);
> +               if (!info->elm_dev) {
> +                       pr_err("Request to elm module failed\n");
> +                       goto fail;
> +               }
>         } else {
> -               info->nand.ecc.strength  = 4;
> -               info->nand.ecc.bytes     = 7;
> -               info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
> +
> +               /* initialize GPMC BCH engine */
> +               ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
> +               if (ret)
> +                       goto fail;
> +
> +               /*
> +                * software bch library is only used to detect and
> +                * locateerrors

s/locateerrors/locate errors/

BTW, did you check that your patch does not break the software BCH case (i.e. no ELM) ?

BR,
--
Ivan


From bas at bmail.ru  Wed Oct  3 15:30:29 2012
From: bas at bmail.ru (kyak)
Date: Wed, 3 Oct 2012 23:30:29 +0400 (MSK)
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
Message-ID: <alpine.LNX.2.02.1210032322590.1375@bas>

Hi,

Consider the following sequence of commands:

cd ~
mkdir -p /tmp/wtf/wtf1
chmod u-r /tmp/wtf
mkfs.ubifs -m 4096 -e 516096 -c 4095 -d /tmp/wtf/wtf1 -o mytest.img
Error: output file cannot be in the UBIFS root directory

mytest.img is not inside /tmp/wtf/wtf1, but mkfs.ubifs fails because 
/tmp/wtf is not readable.
It seems that implementation of in_path(..) in mkfs.ubifs.c is not quite 
correct to handle this type of situations.

If you are wondering, my /home is not readable, and this prevents me from 
building any ubifs image inside of /home/user.

Thanks in advance.


From marex at denx.de  Wed Oct  3 20:18:25 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 4 Oct 2012 02:18:25 +0200
Subject: RFC : attach ubi in readonly mode
In-Reply-To: <4F2BE3C1.8000104@parrot.com>
References: <4F2BE3C1.8000104@parrot.com>
Message-ID: <201210040218.25801.marex@denx.de>

Dear Matthieu CASTET,

> Hi,
> 
> it could be interesting to attach ubi in read-only mode (for example
> getting ubi volume info without altering flash).
> 
> A solution to do that could be to add an argument to UBI_IOCATT ioctl.
> 
> Another solution should be to have a way to switch MTD_WRITEABLE flags.
> 
> What do you think a that ?
> 
> 
> PS : attached a proof of concept for solution 1

Did you get any further with this patches? Is it now possible to safely mount 
UBIFS in read-only mode in some way please?

Thanks!

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Thu Oct  4 00:18:18 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 3 Oct 2012 21:18:18 -0700
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <20121003201447.18ad7d2e@skate>
References: <1349191749-5247-1-git-send-email-richard@nod.at>
 <20121003201447.18ad7d2e@skate>
Message-ID: <CAN8TOE-BsjD_hhD+diL6dKd=+mTa-vwB7P86UQMBacefk6gspw@mail.gmail.com>

Hi,

I made a quick read of your review.

On Wed, Oct 3, 2012 at 11:14 AM, Thomas Petazzoni
<thomas.petazzoni at free-electrons.com> wrote:
> On Tue,  2 Oct 2012 17:29:09 +0200, Richard Weinberger wrote:
>> +<h4><a name="L_fastmap_compat">Backwards compatibility</a></h4>
>> +<p>The fastmap on-disk data structure makes use of delete compatible volumes,
>> +therefore fastmap enabled images are fully backwards compatible with UBI
>
> backwards -> backward (but I'm not 100%, I'm not a native speaker)

I am a native speaker, and I'm not really sure. There's not any great,
reliable source I can find, but it looks like either is acceptable:

http://itknowledgeexchange.techtarget.com/writing-for-business/backward-compatible-or-backwards-compatible/

>> +<p>A on-disk fastmap contains all information needed to attach the whole image,
>> +namely all erase counter values, a list of all PEBs and their state, a list of
>> +all volumes and their current EBA, ...
>> +To avoid too much writes of the fastmap it contains also a list of PEBs which
>
> it also contains

I would also suggest:

s/too much/too many/
s/fastmap/fastmap,/

Brian


From linus.walleij at linaro.org  Thu Oct  4 03:28:29 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu,  4 Oct 2012 09:28:29 +0200
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
Message-ID: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>

The Nomadik NAND driver is really just a subset of the existing
FSMC driver, so let's switch over to using that driver instead,
since it handles more variants of this chip. The callbacks for
setting up the chip is doing stuff now handled by the FSMC
driver.

Cc: Alessandro Rubini <rubini at unipv.it>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
I'm requesting Mike Turquette's ACK on this patch so I can merge
it through ARM SoC.
---
 arch/arm/configs/nhk8815_defconfig        |  2 +-
 arch/arm/mach-nomadik/board-nhk8815.c     | 64 ++++++++++++++-----------------
 arch/arm/mach-nomadik/include/mach/fsmc.h | 29 --------------
 drivers/clk/clk-nomadik.c                 |  1 +
 4 files changed, 30 insertions(+), 66 deletions(-)
 delete mode 100644 arch/arm/mach-nomadik/include/mach/fsmc.h

diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index bf123c5..9a8adfd 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -58,7 +58,7 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC_SMC=y
 CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_NOMADIK=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=y
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index bfa1eab..a105d1b 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/i2c.h>
@@ -36,7 +37,6 @@
 #include <plat/mtu.h>
 #include <plat/pincfg.h>
 
-#include <linux/platform_data/mtd-nomadik-nand.h>
 #include <mach/fsmc.h>
 
 #include "cpu-8815.h"
@@ -48,36 +48,18 @@
 /* These addresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
 	{
-		.name = "nand_addr",
-		.start = NAND_IO_ADDR,
-		.end = NAND_IO_ADDR + 0xfff,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.name = "nand_cmd",
-		.start = NAND_IO_CMD,
-		.end = NAND_IO_CMD + 0xfff,
+		.name = "nand_data",
+		.start = 0x40000000,
+		.end = 0x40000000 + SZ_16K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.name = "nand_data",
-		.start = NAND_IO_DATA,
-		.end = NAND_IO_DATA + 0xfff,
+		.name  = "fsmc_regs",
+		.start = NOMADIK_FSMC_BASE,
+		.end   = NOMADIK_FSMC_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
-	}
+	},
 };
 
-static int nhk8815_nand_init(void)
-{
-	/* FSMC setup for nand chip select (8-bit nand in 8815NHK) */
-	writel(0x0000000E, FSMC_PCR(0));
-	writel(0x000D0A00, FSMC_PMEM(0));
-	writel(0x00100A00, FSMC_PATT(0));
-
-	/* enable access to the chip select area */
-	writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0));
-
-	return 0;
-}
-
 /*
  * These partitions are the same as those used in the 2.6.20 release
  * shipped by the vendor; the first two partitions are mandated
@@ -111,20 +93,30 @@ static struct mtd_partition nhk8815_partitions[] = {
 	}
 };
 
-static struct nomadik_nand_platform_data nhk8815_nand_data = {
-	.parts		= nhk8815_partitions,
-	.nparts		= ARRAY_SIZE(nhk8815_partitions),
-	.options	= NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING,
-	.init		= nhk8815_nand_init,
+static struct fsmc_nand_timings nhk8815_nand_timings = {
+	.thiz	= 0,
+	.thold	= 0x10,
+	.twait	= 0x0A,
+	.tset	= 0,
+};
+
+static struct fsmc_nand_platform_data nhk8815_nand_platform_data = {
+	.nand_timings = &nhk8815_nand_timings,
+	.partitions = nhk8815_partitions,
+	.nr_partitions = ARRAY_SIZE(nhk8815_partitions),
+	.width = FSMC_NAND_BW8,
+	.ale_off = 0x1000000,
+	.cle_off = 0x800000,
 };
 
 static struct platform_device nhk8815_nand_device = {
-	.name		= "nomadik_nand",
-	.dev		= {
-		.platform_data = &nhk8815_nand_data,
+	.name = "fsmc-nand",
+	.id = -1,
+	.resource = nhk8815_nand_resources,
+	.num_resources = ARRAY_SIZE(nhk8815_nand_resources),
+	.dev = {
+		.platform_data = &nhk8815_nand_platform_data,
 	},
-	.resource	= nhk8815_nand_resources,
-	.num_resources	= ARRAY_SIZE(nhk8815_nand_resources),
 };
 
 /* These are the partitions for the OneNand device, different from above */
diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h
deleted file mode 100644
index 8c2c051..0000000
--- a/arch/arm/mach-nomadik/include/mach/fsmc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-
-/* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */
-
-#ifndef __ASM_ARCH_FSMC_H
-#define __ASM_ARCH_FSMC_H
-
-#include <mach/hardware.h>
-/*
- * Register list
- */
-
-/* bus control reg. and bus timing reg. for CS0..CS3 */
-#define FSMC_BCR(x)     (NOMADIK_FSMC_VA + (x << 3))
-#define FSMC_BTR(x)     (NOMADIK_FSMC_VA + (x << 3) + 0x04)
-
-/* PC-card and NAND:
- * PCR = control register
- * PMEM = memory timing
- * PATT = attribute timing
- * PIO = I/O timing
- * PECCR = ECC result
- */
-#define FSMC_PCR(x)     (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00)
-#define FSMC_PMEM(x)    (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08)
-#define FSMC_PATT(x)    (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c)
-#define FSMC_PIO(x)     (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10)
-#define FSMC_PECCR(x)   (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14)
-
-#endif /* __ASM_ARCH_FSMC_H */
diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c
index 517a8ff..6b4c70f 100644
--- a/drivers/clk/clk-nomadik.c
+++ b/drivers/clk/clk-nomadik.c
@@ -20,6 +20,7 @@ void __init nomadik_clk_init(void)
 	clk_register_clkdev(clk, NULL, "gpio.2");
 	clk_register_clkdev(clk, NULL, "gpio.3");
 	clk_register_clkdev(clk, NULL, "rng");
+	clk_register_clkdev(clk, NULL, "fsmc-nand");
 
 	/*
 	 * The 2.4 MHz TIMCLK reference clock is active at boot time, this is
-- 
1.7.11.4



From linus.walleij at linaro.org  Thu Oct  4 03:28:49 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu,  4 Oct 2012 09:28:49 +0200
Subject: [PATCH 2/2] mtd: delete nomadik_nand driver
Message-ID: <1349335729-13438-1-git-send-email-linus.walleij@linaro.org>

The nomadik_nand driver is really just a subset of the FSMC
NAND driver, and there are no users anymore so let's delete
it.

Cc: Alessandro Rubini <rubini at unipv.it>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
I'm seeking the MTD maintainer(s) ACK for this patch so I can
merge it through the ARM SoC tree just after switching the
platform to using the FSMC driver.
---
 drivers/mtd/nand/Kconfig                       |   6 -
 drivers/mtd/nand/Makefile                      |   1 -
 drivers/mtd/nand/nomadik_nand.c                | 235 -------------------------
 include/linux/platform_data/mtd-nomadik-nand.h |  16 --
 4 files changed, 258 deletions(-)
 delete mode 100644 drivers/mtd/nand/nomadik_nand.c
 delete mode 100644 include/linux/platform_data/mtd-nomadik-nand.h

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 598cd0a..ec4acae 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -515,12 +515,6 @@ config MTD_NAND_MXC
 	  This enables the driver for the NAND flash controller on the
 	  MXC processors.
 
-config MTD_NAND_NOMADIK
-	tristate "ST Nomadik 8815 NAND support"
-	depends on ARCH_NOMADIK
-	help
-	  Driver for the NAND flash controller on the Nomadik, with ECC.
-
 config MTD_NAND_SH_FLCTL
 	tristate "Support for NAND on Renesas SuperH FLCTL"
 	depends on SUPERH || ARCH_SHMOBILE
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4b4d87..4d4e33a 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -45,7 +45,6 @@ obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
-obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
 obj-$(CONFIG_MTD_NAND_BCM_UMI)		+= bcm_umi_nand.o nand_bcm_umi.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c
deleted file mode 100644
index 9ee0c4e..0000000
--- a/drivers/mtd/nand/nomadik_nand.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *  drivers/mtd/nand/nomadik_nand.c
- *
- *  Overview:
- *  	Driver for on-board NAND flash on Nomadik Platforms
- *
- * Copyright ?? 2007 STMicroelectronics Pvt. Ltd.
- * Author: Sachin Verma <sachin.verma at st.com>
- *
- * Copyright ?? 2009 Alessandro Rubini
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/platform_data/mtd-nomadik-nand.h>
-#include <mach/fsmc.h>
-
-#include <mtd/mtd-abi.h>
-
-struct nomadik_nand_host {
-	struct mtd_info		mtd;
-	struct nand_chip	nand;
-	void __iomem *data_va;
-	void __iomem *cmd_va;
-	void __iomem *addr_va;
-	struct nand_bbt_descr *bbt_desc;
-};
-
-static struct nand_ecclayout nomadik_ecc_layout = {
-	.eccbytes = 3 * 4,
-	.eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */
-		0x02, 0x03, 0x04,
-		0x12, 0x13, 0x14,
-		0x22, 0x23, 0x24,
-		0x32, 0x33, 0x34},
-	/* let's keep bytes 5,6,7 for us, just in case we change ECC algo */
-	.oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} },
-};
-
-static void nomadik_ecc_control(struct mtd_info *mtd, int mode)
-{
-	/* No need to enable hw ecc, it's on by default */
-}
-
-static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-	struct nand_chip *nand = mtd->priv;
-	struct nomadik_nand_host *host = nand->priv;
-
-	if (cmd == NAND_CMD_NONE)
-		return;
-
-	if (ctrl & NAND_CLE)
-		writeb(cmd, host->cmd_va);
-	else
-		writeb(cmd, host->addr_va);
-}
-
-static int nomadik_nand_probe(struct platform_device *pdev)
-{
-	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;
-	struct nomadik_nand_host *host;
-	struct mtd_info *mtd;
-	struct nand_chip *nand;
-	struct resource *res;
-	int ret = 0;
-
-	/* Allocate memory for the device structure (and zero it) */
-	host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL);
-	if (!host) {
-		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
-		return -ENOMEM;
-	}
-
-	/* Call the client's init function, if any */
-	if (pdata->init)
-		ret = pdata->init();
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Init function failed\n");
-		goto err;
-	}
-
-	/* ioremap three regions */
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
-	if (!res) {
-		ret = -EIO;
-		goto err_unmap;
-	}
-	host->addr_va = ioremap(res->start, resource_size(res));
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
-	if (!res) {
-		ret = -EIO;
-		goto err_unmap;
-	}
-	host->data_va = ioremap(res->start, resource_size(res));
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
-	if (!res) {
-		ret = -EIO;
-		goto err_unmap;
-	}
-	host->cmd_va = ioremap(res->start, resource_size(res));
-
-	if (!host->addr_va || !host->data_va || !host->cmd_va) {
-		ret = -ENOMEM;
-		goto err_unmap;
-	}
-
-	/* Link all private pointers */
-	mtd = &host->mtd;
-	nand = &host->nand;
-	mtd->priv = nand;
-	nand->priv = host;
-
-	host->mtd.owner = THIS_MODULE;
-	nand->IO_ADDR_R = host->data_va;
-	nand->IO_ADDR_W = host->data_va;
-	nand->cmd_ctrl = nomadik_cmd_ctrl;
-
-	/*
-	 * This stanza declares ECC_HW but uses soft routines. It's because
-	 * HW claims to make the calculation but not the correction. However,
-	 * I haven't managed to get the desired data out of it until now.
-	 */
-	nand->ecc.mode = NAND_ECC_SOFT;
-	nand->ecc.layout = &nomadik_ecc_layout;
-	nand->ecc.hwctl = nomadik_ecc_control;
-	nand->ecc.size = 512;
-	nand->ecc.bytes = 3;
-
-	nand->options = pdata->options;
-
-	/*
-	 * Scan to find existence of the device
-	 */
-	if (nand_scan(&host->mtd, 1)) {
-		ret = -ENXIO;
-		goto err_unmap;
-	}
-
-	mtd_device_register(&host->mtd, pdata->parts, pdata->nparts);
-
-	platform_set_drvdata(pdev, host);
-	return 0;
-
- err_unmap:
-	if (host->cmd_va)
-		iounmap(host->cmd_va);
-	if (host->data_va)
-		iounmap(host->data_va);
-	if (host->addr_va)
-		iounmap(host->addr_va);
- err:
-	kfree(host);
-	return ret;
-}
-
-/*
- * Clean up routine
- */
-static int nomadik_nand_remove(struct platform_device *pdev)
-{
-	struct nomadik_nand_host *host = platform_get_drvdata(pdev);
-	struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data;
-
-	if (pdata->exit)
-		pdata->exit();
-
-	if (host) {
-		nand_release(&host->mtd);
-		iounmap(host->cmd_va);
-		iounmap(host->data_va);
-		iounmap(host->addr_va);
-		kfree(host);
-	}
-	return 0;
-}
-
-static int nomadik_nand_suspend(struct device *dev)
-{
-	struct nomadik_nand_host *host = dev_get_drvdata(dev);
-	int ret = 0;
-	if (host)
-		ret = mtd_suspend(&host->mtd);
-	return ret;
-}
-
-static int nomadik_nand_resume(struct device *dev)
-{
-	struct nomadik_nand_host *host = dev_get_drvdata(dev);
-	if (host)
-		mtd_resume(&host->mtd);
-	return 0;
-}
-
-static const struct dev_pm_ops nomadik_nand_pm_ops = {
-	.suspend = nomadik_nand_suspend,
-	.resume = nomadik_nand_resume,
-};
-
-static struct platform_driver nomadik_nand_driver = {
-	.probe = nomadik_nand_probe,
-	.remove = nomadik_nand_remove,
-	.driver = {
-		.owner = THIS_MODULE,
-		.name = "nomadik_nand",
-		.pm = &nomadik_nand_pm_ops,
-	},
-};
-
-module_platform_driver(nomadik_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("ST Microelectronics (sachin.verma at st.com)");
-MODULE_DESCRIPTION("NAND driver for Nomadik Platform");
diff --git a/include/linux/platform_data/mtd-nomadik-nand.h b/include/linux/platform_data/mtd-nomadik-nand.h
deleted file mode 100644
index c3c8254..0000000
--- a/include/linux/platform_data/mtd-nomadik-nand.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_ARCH_NAND_H
-#define __ASM_ARCH_NAND_H
-
-struct nomadik_nand_platform_data {
-	struct mtd_partition *parts;
-	int nparts;
-	int options;
-	int (*init) (void);
-	int (*exit) (void);
-};
-
-#define NAND_IO_DATA	0x40000000
-#define NAND_IO_CMD	0x40800000
-#define NAND_IO_ADDR	0x41000000
-
-#endif				/* __ASM_ARCH_NAND_H */
-- 
1.7.11.4



From avinashphilip at ti.com  Thu Oct  4 03:49:14 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Thu, 4 Oct 2012 07:49:14 +0000
Subject: [PATCH 2/4] mtd: devices: elm: Add support for ELM error
 correction
In-Reply-To: <alpine.DEB.2.01.1210031701440.32543@pmeerw.net>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-3-git-send-email-avinashphilip@ti.com>
 <alpine.DEB.2.01.1210031701440.32543@pmeerw.net>
Message-ID: <518397C60809E147AF5323E0420B992E3E9B48A7@DBDE01.ent.ti.com>

On Wed, Oct 03, 2012 at 20:40:46, Peter Meerwald wrote:
> 
> some minor nitpicks below
> 
> > + *
> > + * On completion of processing by elm module, error location status
> > + * register updated with correctable/uncorrectable error information.
> > + * In case of correctable errors, number of errors located from
> > + * elm location status register & read the these many positions from
> 
> should probably be: "... & read the positions from ..."?

Ok I will correct it.

> 
> > + * elm error location register.
> > + */
> > +static void elm_error_correction(struct elm_info *info,
> > +		struct elm_errorvec *err_vec)
> > +{
> > +	int i, j, errors = 0;
> > +	void *err_loc_base = info->elm_base + ELM_ERROR_LOCATION_0;
> > +	elm_error_t *err_loc;
> > +	void *offset;
> > +	u32 reg_val;
> > +
> > +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
> > +		/* check error reported */
> > +		if (err_vec[i].error_reported) {
> > +			offset = info->elm_base + ELM_LOCATION_STATUS +
> > +				i * ERROR_LOCATION_SIZE;
> > +			reg_val = elm_read_reg(offset);
> > +			/* check correctable error or not */
> > +			if (reg_val & ECC_CORRECTABLE_MASK) {
> > +				err_loc = err_loc_base +
> > +					i * ERROR_LOCATION_SIZE;
> > +				/* read count of correctable errors */
> > +				err_vec[i].error_count = reg_val &
> > +					ECC_NB_ERRORS_MASK;
> > +
> > +				/* update the error locations in error vector */
> > +				for (j = 0; j < err_vec[i].error_count; j++) {
> > +
> > +					reg_val = elm_read_reg(*err_loc + j);
> > +					err_vec[i].error_loc[j] = reg_val &
> > +						ECC_ERROR_LOCATION_MASK;
> > +				}
> > +
> > +				errors += err_vec[i].error_count;
> > +			} else {
> > +				err_vec[i].error_uncorrectable++;
> > +			}
> 
> extra braces above

As per coding style
This does not apply if only one branch of a conditional statement is a single
statement; in the latter case use braces in both branches:

> 
> > +
> > +			/* clearing interrupts for processed error vectors */
> > +			elm_write_reg(info->elm_base + ELM_IRQSTATUS, BIT(i));
> > +
> > +			/* disable page mode */
> > +			elm_configure_page_mode(info, i, false);
> > +		}
> > +	}
> > +
> > +	return;
> > +}
> > +
> > +/**
> > + * elm_decode_bch_error_page - Locate error position
> > + * @info:	elm info
> 
> should be dev, not info

Ok I will correct it.

> 
> > + * @ecc_calc:	calculated ECC bytes from GPMC
> > + * @err_vec:	elm error vectors
> > + *
> > + * Called with one or greater reported and is vectors with error reported
> > + * is updated in err_vec[].error_reported
> > + */
> 
> I do not understand the statement "Called with one ..."

elm_decode_bch_error_page() API will called from nand driver if and only if
errors are present while reading page. Errors can be reported in one or
multiple error vectors.

I will reword it as.

Called with one or more error reported vectors & vectors with error reported
is updated in err_vec[].error_reported

> 
[snip]
> > +
> > +#define BCH8_ECC_OOB_BYTES		13
> > +/* RBL requires 14 byte even though BCH8 uses only 13 byte */
> 
> not sure what RBL is?

RBL stands for Rom boot Loader

> 
> > +#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
> > +#define BCH4_SIZE			7
> > +
> > +#define	BCH8_SYNDROME_SIZE		4	/* 13 bytes of ecc */
> > +#define	BCH4_SYNDROME_SIZE		2	/* 7 bytes of ecc */
> > +
> > +/**
> > + * struct elm_errorvec - error vector for elm
> > + * @error_reported:		set true for vectors error is reported
> > + *
> > + * @error_count:		number of correctable errors in the sector
> > + * @error_uncorrectable:	number of uncorrectable errors
> > + * @error_loc:			buffer for error location
> > + *
> > + */
> > +struct elm_errorvec {
> > +	bool error_reported;
> > +	int error_count;
> > +	int error_uncorrectable;
> > +	int error_loc[ERROR_VECTOR_MAX];
> > +};
> > +
> > +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
> > +		struct elm_errorvec *err_vec);
> > +struct device *elm_request(enum bch_ecc bch_type);
> > +#endif /* __ELM_H */
> > 
> 
> -- 
> 
> Peter Meerwald
> +43-664-2444418 (mobile)
> 



From avinashphilip at ti.com  Thu Oct  4 04:03:42 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Thu, 4 Oct 2012 08:03:42 +0000
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <20121003185458.GA27502@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
 <20121003185458.GA27502@parrot.com>
Message-ID: <518397C60809E147AF5323E0420B992E3E9B4902@DBDE01.ent.ti.com>

On Thu, Oct 04, 2012 at 00:24:58, Ivan Djelic wrote:
> On Wed, Oct 03, 2012 at 03:29:48PM +0100, Philip, Avinash wrote:
> > Add support for BCH ECC scheme to gpmc driver and also enabling multi
> > sector read/write. This helps in doing single shot NAND page read and
> > write.
> > 
> > ECC engine configurations
> > BCH 4 bit support
> > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
> > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
> > 13 and ecc_size1 as 1.
> > 
> > BCH 8 bit support
> > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
> > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
> > 26 and ecc_size1 as 2.
> > 
> > Note: For BCH8 ECC bytes set to 14 to make compatible with RBL.
> > 
> 
> Hi Philip,
> 
> I have a few comments/questions below,
> 
> (...)
> > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> > index 72428bd..c9bc3cf 100644
> > --- a/arch/arm/mach-omap2/gpmc.c
> > +++ b/arch/arm/mach-omap2/gpmc.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/io.h>
> >  #include <linux/module.h>
> >  #include <linux/interrupt.h>
> > +#include <linux/mtd/nand.h>
> >  
> >  #include <asm/mach-types.h>
> >  #include <plat/gpmc.h>
> > @@ -83,6 +84,18 @@
> >  #define ENABLE_PREFETCH		(0x1 << 7)
> >  #define DMA_MPU_MODE		2
> >  
> > +/* GPMC ecc engine settings for read */
> > +#define BCH_WRAPMODE_1		1	/* BCH wrap mode 6 */
> 
> Comment should say "mode 1".

Ok I will correct it.

> 
> (...)
> >  /**
> > + * gpmc_calculate_ecc_bch	- Generate ecc bytes per block of 512 data bytes for entire page
> > + * @cs:  chip select number
> > + * @dat: The pointer to data on which ECC is computed
> > + * @ecc: The ECC output buffer
> > + */
> > +int gpmc_calculate_ecc_bch(int cs, const u_char *dat, u_char *ecc)
> > +{
> > +	int i, eccbchtsel;
> > +	u32 nsectors, reg, bch_val1, bch_val2, bch_val3, bch_val4;
> > +
> > +	if (gpmc_ecc_used != cs)
> > +		return -EINVAL;
> > +
> > +	/* read number of sectors for ecc to be calculated */
> > +	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
> > +	/*
> > +	 * find BCH scheme used
> > +	 * 0 -> BCH4
> > +	 * 1 -> BCH8
> > +	 */
> > +	eccbchtsel = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 12) & 0x3);
> > +
> > +	/* update ecc bytes for entire page */
> > +	for (i = 0; i < nsectors; i++) {
> > +
> > +		reg = GPMC_ECC_BCH_RESULT_0 + 16 * i;
> > +
> > +		/* Read hw-computed remainder */
> > +		bch_val1 = gpmc_read_reg(reg + 0);
> > +		bch_val2 = gpmc_read_reg(reg + 4);
> > +		if (eccbchtsel) {
> > +			bch_val3 = gpmc_read_reg(reg + 8);
> > +			bch_val4 = gpmc_read_reg(reg + 12);
> > +		}
> > +
> > +		if (eccbchtsel) {
> > +			/* BCH8 ecc scheme */
> > +			*ecc++ = (bch_val4 & 0xFF);
> > +			*ecc++ = ((bch_val3 >> 24) & 0xFF);
> > +			*ecc++ = ((bch_val3 >> 16) & 0xFF);
> > +			*ecc++ = ((bch_val3 >> 8) & 0xFF);
> > +			*ecc++ = (bch_val3 & 0xFF);
> > +			*ecc++ = ((bch_val2 >> 24) & 0xFF);
> > +			*ecc++ = ((bch_val2 >> 16) & 0xFF);
> > +			*ecc++ = ((bch_val2 >> 8) & 0xFF);
> > +			*ecc++ = (bch_val2 & 0xFF);
> > +			*ecc++ = ((bch_val1 >> 24) & 0xFF);
> > +			*ecc++ = ((bch_val1 >> 16) & 0xFF);
> > +			*ecc++ = ((bch_val1 >> 8) & 0xFF);
> > +			*ecc++ = (bch_val1 & 0xFF);
> > +			/* 14th byte of ecc not used */
> > +			*ecc++ = 0;
> > +		} else {
> > +			/* BCH4 ecc scheme */
> > +			*ecc++ = ((bch_val2 >> 12) & 0xFF);
> > +			*ecc++ = ((bch_val2 >> 4) & 0xFF);
> > +			*ecc++ = (((bch_val2 & 0xF) << 4) |
> > +					((bch_val1 >> 28) & 0xF));
> > +			*ecc++ = ((bch_val1 >> 20) & 0xFF);
> > +			*ecc++ = ((bch_val1 >> 12) & 0xFF);
> > +			*ecc++ = ((bch_val1 >> 4) & 0xFF);
> > +			*ecc++ = ((bch_val1 & 0xF) << 4);
> > +		}
> > +	}
> > +
> > +	gpmc_ecc_used = -EINVAL;
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch);
> 
> Here you introduce a function very similar to gpmc_calculate_ecc_bch4 and
> gpmc_calculate_ecc_bch8, but without the added benefit (IMHO) of the constant
> polynomial that allows to get an ecc sequence of 0xFFs for a buffer filled with
> 0xFFs. Why ?

I don't exactly understand what we benefitted/achieve. In my observation,
this API does spare area also written with 0xFF if data area is 0xFFs.
So the area looks like erased page again.

> If using the ELM prevents you from reusing gpmc_calculate_ecc_bch[48], could you explain in which way ?

When using gpmc_calculate_ecc_bch[48], calculated ecc values modified.
The read sequence we following is
Read 512 byte -> read ECC bytes from spare area
Now the calculated ECC will be zero if no error is reported. In case of error, a syndrome
Polynomial is reported. In either case modifying will corrupt the data.

This is valid if we are writing a page with 0xFF also. But this time we were filling a valid
ecc in spare area not 0xFF as in gpmc_calculate_ecc_bch[48].

Additionally to make compatible with RBL ECC layout (14 byte), we were setting ecc[13] as zero.

Thanks
Avinash  

> 
> Best regards,
> --
> Ivan
> 



From hechtb at googlemail.com  Thu Oct  4 06:07:56 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Thu, 4 Oct 2012 12:07:56 +0200
Subject: [PATCH 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <201210022047.50064.arnd.bergmann@linaro.org>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <201210021354.01247.arnd@arndb.de>
 <Pine.LNX.4.64.1210021602250.15778@axis700.grange>
 <201210022047.50064.arnd.bergmann@linaro.org>
Message-ID: <CABYn4sz_KYQnmz9Ov=cSWEO+s2Hd_RCZpEV8fc6GFSrR9mnqVw@mail.gmail.com>

Hi Arnd, hi Guennadi,

2012/10/2 Arnd Bergmann <arnd.bergmann at linaro.org>:
> On Tuesday 02 October 2012, Guennadi Liakhovetski wrote:
>> >
>> > Since you are also adding dma-engine support, I would suggest you specify
>> > a "dmas" and "dma-names" property as well, so the device can find the
>> > right dma channel. The code might not do that yet while you're still
>> > sorting out the dependencies (and the sh dmaengine code is not yet
>> > converted to DT), but I think it would be good to nail down the binding
>> > for this device.

Ok good, so I will include these field in v2. The FLCTL has support
for 4 channels, 2 for data read/write and 2 for ECC read/write.
The driver currently supports only the data part. Should I include the
ECC part nevertheless?

Further would you prefer the naming
 - fifo0_rx fifo0_tx fifo1_rx fifo1_tx (close to the datasheet) or
 - data_rx data_tx ecc_rx ecc_tx

Then the dmas field:
If I get it right, we have 3 possible DMA controllers to use on the
sh7372 and we specify the mid/rid value as second argument?

So how about this to add to the docs:

dmas = <&dma1 0x83 /* fifo0_rx */
&dma1 0x83 /* fifo0_tx */
&dma2 0x83 /* fifo0_rx */
&dma2 0x83 /* fifo0_tx */
&dma3 0x83 /* fifo0_rx */
&dma3 0x83>; /* fifo0_tx */
dma-names = "fifo0_rx", "fifo0_tx", fifo0_rx", "fifo0_tx", fifo0_rx",
"fifo0_tx";

Many thanks for the help,

 Bastian


From hechtb at googlemail.com  Thu Oct  4 06:12:52 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Thu, 4 Oct 2012 12:12:52 +0200
Subject: [PATCH 1/2] mtd: sh_flctl: Add DMA capabilty
In-Reply-To: <Pine.LNX.4.64.1210021534570.15778@axis700.grange>
References: <1349183522-15321-1-git-send-email-hechtb@gmail.com>
 <1349183522-15321-2-git-send-email-hechtb@gmail.com>
 <Pine.LNX.4.64.1210021534570.15778@axis700.grange>
Message-ID: <CABYn4swdBX+verPTDKywC_U3xQboSSGFoezCkYth4PXVE1QcbQ@mail.gmail.com>

Hey Guennadi,

2012/10/2 Guennadi Liakhovetski <g.liakhovetski at gmx.de>:
> On Tue, 2 Oct 2012, Bastian Hecht wrote:
>
>> The code probes if DMA channels can get allocated and tears them down at
>> removal/failure if needed.
>> If available it uses them to transfer the data part (not ECC). On
>> failure we fall back to PIO mode.
>>
>> Based on Guennadi Liakhovetski's code from the sh_mmcif driver.
>>
>> Signed-off-by: Bastian Hecht <hechtb at gmail.com>
>
> Looks mostly good to me, just a couple of cosmetic remarks below. They are
> not critical, so, I won't be upset, if you fix them later:-) In any case
>
> Reviewed-by: Guennadi Liakhovetski <g.liakhovetski at gmx.de>

Great, will add that to the next version!

>> ---
>>  drivers/mtd/nand/sh_flctl.c  |  174 +++++++++++++++++++++++++++++++++++++++++-
>>  include/linux/mtd/sh_flctl.h |   12 +++
>>  2 files changed, 183 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
>> index 4fbfe96..0fead2a 100644
>> --- a/drivers/mtd/nand/sh_flctl.c
>> +++ b/drivers/mtd/nand/sh_flctl.c
>> @@ -24,10 +24,13 @@
>>  #include <linux/module.h>
>>  #include <linux/kernel.h>
>>  #include <linux/delay.h>
>> +#include <linux/dmaengine.h>
>> +#include <linux/dma-mapping.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/io.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/sh_dma.h>
>>  #include <linux/slab.h>
>>  #include <linux/string.h>
>>
>> @@ -106,6 +109,84 @@ static void wait_completion(struct sh_flctl *flctl)
>>       writeb(0x0, FLTRCR(flctl));
>>  }
>>
>> +static void flctl_dma_complete(void *param)
>> +{
>> +     struct sh_flctl *flctl = param;
>> +
>> +     complete(&flctl->dma_complete);
>
> I think I mentioned in the first review, that it is good to include
> headers everywhere, where they are needed and not rely on pulling them in
> via other headers. So, it would be good to also include complete.h here
> directly.

Ok sure, I will include that as well.

> [snip]



>> @@ -308,13 +462,23 @@ static enum flctl_ecc_res_t read_ecfiforeg
>>  static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
>>  {
>>       int i, len_4align;
>> -     unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
>> +     unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
>>       void *fifo_addr = (void *)FLDTFIFO(flctl);
>>
>>       len_4align = (rlen + 3) / 4;
>> +
>> +     for (i = 0; i < len_4align; i++)
>> +                     buf[i] = cpu_to_be32(buf[i]);
>
> indentation ran away here.

Ah nice, thanks for the hawk's eye ;)

> Thanks
> Guennadi

Thanks!
 Bastian


From avinashphilip at ti.com  Thu Oct  4 06:22:43 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Thu, 4 Oct 2012 10:22:43 +0000
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <20121003192044.GB27502@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
Message-ID: <518397C60809E147AF5323E0420B992E3E9B7FDF@DBDE01.ent.ti.com>

On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
> On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
> > ELM module can be used for error correction of BCH 4 & 8 bit. Also
> > support read & write page in one shot by adding custom read_page &
> > write_page methods. This helps in optimizing code.
> > 
> > New structure member "is_elm_used" is added to know the status of
> > whether the ELM module is used for error correction or not.
> > 
> > Note:
> > ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
> > with RBL ECC layout, even though the requirement was only 13 byte. This
> > results a common ecc layout across RBL, U-boot & Linux.
> > 
> 
> See a few comments below,
> 
> (...)
> > +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
> > +                               u_char *read_ecc, u_char *calc_ecc)
> > +{
> > +       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> > +                       mtd);
> > +       int eccsteps = info->nand.ecc.steps;
> > +       int i , j, stat = 0;
> > +       int eccsize, eccflag, size;
> > +       struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
> > +       u_char *ecc_vec = calc_ecc;
> > +       enum bch_ecc type;
> > +       bool is_error_reported = false;
> > +
> > +       /* initialize elm error vector to zero */
> > +       memset(err_vec, 0, sizeof(err_vec));
> > +       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
> > +               size = BCH8_SIZE;
> > +               eccsize = BCH8_ECC_OOB_BYTES;
> > +               type = BCH8_ECC;
> > +       } else {
> > +               size = BCH4_SIZE;
> > +               eccsize = BCH4_SIZE;
> > +               type = BCH4_ECC;
> > +       }
> > +
> > +       for (i = 0; i < eccsteps ; i++) {
> > +               eccflag = 0;    /* initialize eccflag */
> > +
> > +               for (j = 0; (j < eccsize); j++) {
> > +                       if (read_ecc[j] != 0xFF) {
> > +                               eccflag = 1;    /* data area is flashed */
> 
> Just a reminder: this way of checking if a page has been programmed is not robust to bitflips,
> so you may get into trouble with UBIFS on a fairly recent device.
> 
> (...)
> > @@ -1039,14 +1180,45 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
> > 
> >         nerrors = info->nand.ecc.strength;
> >         dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
> > +#ifdef CONFIG_MTD_NAND_OMAP_BCH
> > +       if (info->is_elm_used) {
> > +               /*
> > +                * Program GPMC to perform correction on (steps * 512) byte
> > +                * sector at a time.
> > +                */
> > +               gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width,
> > +                               info->nand.ecc.steps, nerrors);
> > +               return;
> > +       }
> > +#endif
> >         /*
> > -        * Program GPMC to perform correction on one 512-byte sector at a time.
> > -        * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
> > -        * gives a slight (5%) performance gain (but requires additional code).
> > +        * Program GPMC to perform correction on one 512-byte sector at
> > +        * a time.
> 
> Why removing the comment about 4-sector perf gain ? :-)

With this patch, support for reading 4 sectors (max 8) is available.
Hence I am removing it.

> 
> (...)
> > @@ -1146,35 +1402,62 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
> >                 goto fail;
> >         }
> > 
> > -       /* initialize GPMC BCH engine */
> > -       ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
> > -       if (ret)
> > -               goto fail;
> > -
> > -       /* software bch library is only used to detect and locate errors */
> > -       info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
> > -       if (!info->bch)
> > -               goto fail;
> > +       info->nand.ecc.size = 512;
> > +       info->nand.ecc.hwctl = omap3_enable_hwecc_bch;
> > +       info->nand.ecc.mode = NAND_ECC_HW;
> > +       info->nand.ecc.strength = hw_errors;
> > 
> > -       info->nand.ecc.size    = 512;
> > -       info->nand.ecc.hwctl   = omap3_enable_hwecc_bch;
> > -       info->nand.ecc.correct = omap3_correct_data_bch;
> > -       info->nand.ecc.mode    = NAND_ECC_HW;
> > +       if (info->is_elm_used && (mtd->writesize <= 4096)) {
> > +               enum bch_ecc bch_type;
> > 
> > -       /*
> > -        * The number of corrected errors in an ecc block that will trigger
> > -        * block scrubbing defaults to the ecc strength (4 or 8).
> > -        * Set mtd->bitflip_threshold here to define a custom threshold.
> > -        */
> > +               if (hw_errors == BCH8_MAX_ERROR) {
> > +                       bch_type = BCH8_ECC;
> > +                       info->nand.ecc.bytes = BCH8_SIZE;
> > +               } else {
> > +                       bch_type = BCH4_ECC;
> > +                       info->nand.ecc.bytes = BCH4_SIZE;
> > +               }
> > 
> > -       if (max_errors == 8) {
> > -               info->nand.ecc.strength  = 8;
> > -               info->nand.ecc.bytes     = 13;
> > -               info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
> > +               info->nand.ecc.correct = omap_elm_correct_data;
> > +               info->nand.ecc.calculate = omap3_calculate_ecc_bch;
> > +               info->nand.ecc.read_page = omap_read_page_bch;
> > +               info->nand.ecc.write_page = omap_write_page_bch;
> > +               info->elm_dev = elm_request(bch_type);
> > +               if (!info->elm_dev) {
> > +                       pr_err("Request to elm module failed\n");
> > +                       goto fail;
> > +               }
> >         } else {
> > -               info->nand.ecc.strength  = 4;
> > -               info->nand.ecc.bytes     = 7;
> > -               info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
> > +
> > +               /* initialize GPMC BCH engine */
> > +               ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
> > +               if (ret)
> > +                       goto fail;
> > +
> > +               /*
> > +                * software bch library is only used to detect and
> > +                * locateerrors
> 
> s/locateerrors/locate errors/

Ok I will correct it.

> 
> BTW, did you check that your patch does not break the software BCH case (i.e. no ELM) ?

I had checked in AM335x-evm software BCH without ELM. So this patch set is not breaking
software BCH functionality.

Thanks
Avinash


> 
> BR,
> --
> Ivan
> 



From richard at nod.at  Thu Oct  4 06:48:46 2012
From: richard at nod.at (Richard Weinberger)
Date: Thu, 04 Oct 2012 12:48:46 +0200
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <20121003201447.18ad7d2e@skate>
References: <1349191749-5247-1-git-send-email-richard@nod.at>
 <20121003201447.18ad7d2e@skate>
Message-ID: <506D698E.6010704@nod.at>

Thomas, Brian,

Thanks for your comments!
I'll send an updated version very soon.

On 03.10.2012 20:14, Thomas Petazzoni wrote:
> It would probably be good to explain what happens when
> fm_autoconvert=0. I guess that images are then not automatically
> converted, but then how does one creates a new image that has the
> fastmap feature built-in? I haven't followed the whole discussion, are
> changes to mtd-utils tools like ubinize planned?

Yeah, support for ubinize is planned.
But first kernel implementation has to be stable, tested (!) and accepted.
By putting fastmap into mainline we hope that many interested users test
fastmap in real world scenarios and give us feedback.

Thanks,
//richard



From richard at nod.at  Thu Oct  4 06:52:10 2012
From: richard at nod.at (Richard Weinberger)
Date: Thu,  4 Oct 2012 12:52:10 +0200
Subject: [PATCH] mtd-www: Add fastmap doc
Message-ID: <1349347930-32422-1-git-send-email-richard@nod.at>

Add documentation on fastmap to mtd-www.

Signed-off-by: Richard Weinberger <richard at nod.at>
---
 doc/ubi.xml | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/doc/ubi.xml b/doc/ubi.xml
index 6bea323..7fe01d0 100644
--- a/doc/ubi.xml
+++ b/doc/ubi.xml
@@ -46,6 +46,7 @@
 		</li>
 		</ol>
 	</li>
+	<li><a href="ubi.html#L_fastmap">Fastmap</a></li>
 	<li><a href="ubi.html#L_ubidoc">More documentation</a></li>
 </ol>
 
@@ -758,8 +759,12 @@ for detailed information.</p>
 <p>Unfortunately, UBI scales linearly in terms of flash size. UBI
 initialization time linearly depends on the number of physical eraseblocks on
 the flash. This means that the larger is the flash, the more time it takes for
-UBI to initialize (i.e., to attach the MTD device). The initialization time
-depends on the flash I/O speed and (slightly) on the CPU speed, because:</p>
+UBI to initialize (i.e., to attach the MTD device).
+Note: Starting with Linux v3.7 UBI offers an optional and experimental feature,
+called "fastmap", which allows attaching in nearly constant time,
+see <a href="ubi.html#L_fastmap">Fastmap</a>.
+The initialization time depends on the flash I/O speed and (slightly) on the
+CPU speed, because:</p>
 
 <ul>
 	<li>UBI scans the MTD device when attaching - it reads the erase EC and
@@ -1170,7 +1175,82 @@ means that all data has been written to the flash media), otherwise it selects
 the PEB with lower sequence number(<i>P<sub>1</sub></i>). Of course, UBI has to
 read the LEB contents in order to check the <code>CRC-32</code> checksum.</p>
 
-
+<h2><a name="L_fastmap">Fastmap</a></h2>
+<p>
+Fastmap is an experimental and optional UBI feature, which can be enabled
+by setting CONFIG_MTD_UBI_FASTMAP to 'y'.
+Once enabled UBI evaluates the module parameter
+"fm_autoconvert". If it is set to 1 (default is 0) UBI automatically enables
+fastmap for any attached image. This means UBI creates a new internal
+volume with the fastmap data such that next time the fast attach mode can be
+used.
+In the default configuration UBI will use the information stored in this
+fastmap volume to accelerate the attach procedure.
+If you want to test fastmap, set fm_autoconvert to 1 and attach a volume.</p>
+
+<h4><a name="L_fastmap_compat">Backwards compatibility</a></h4>
+<p>The fastmap on-disk data structure makes use of delete compatible volumes,
+therefore fastmap enabled images are fully backwards compatible with UBI
+implementaions which do not support fastmap. The kernel will remove the fastmap
+volumes and continue with scanning.
+This includes not only v3.6- but also v3.7+ with this option disabled.
+</p>
+
+<h4><a name="L_fastmap_tech">Technical design</a></h4>
+
+<p>A on-disk fastmap contains all information needed to attach the whole image,
+namely all erase counter values, a list of all PEBs and their state, a list of
+all volumes and their current EBA, ...
+To avoid too much writes of the fastmap it contains also a list of PEBs which
+may have changed and need a full scan while attaching.
+This list is called "fastmap pool" and has a fixed sized, 5% of the total
+amount of PEBs. Using this technique UBI needs to write the fastmap only if the
+pool contains no free PEBs. Otherwise it would have to write the fastmap each
+time when the EBA of a volume has changed.</p>
+
+<p>A fastmap consists of a super block (also known as anchor PEB) and payload
+data which can life on any PEB.
+The anchor PEB has to be located within the first 64 PEBs on the MTD device.
+It contains pointers to the remaining PEBs which carry the actual fastmap
+data. On modern NAND chips the whole fastmap fits into a single PEB.
+Hence, the anchor PEB points to itself.
+After loading the fastmap data, UBI attach information structure is created
+from it
+
+The attach process works as follows:
+<ol>
+	<li>UBI tries to find the fastmap anchor PEB,
+	if no anchor PEB was found UBI performs  traditional full scan</li>
+	<li>It follows the pointers stored in the anchor PEB and reads
+	the fastmap payload data</li>
+	<li>Then it performs a traditional scan only on PEBs in the pool
+	instead of all PEBs</li>
+</ol>
+If UBI detects that the used fastmap is invalid or corrupted it automatically
+falls back to scanning mode and performsa full scan.
+Using a CRC32 checksum and consistency checks of the internal UBI structures
+UBI is able to detect whether a fastmap is invalid or not.
+</p>
+
+<p>
+A fastmap is written to the devices each time the fastmap pool becomes full
+(no free PEBs are available), the volume layout changes or the image is
+detached. One may wonder why writing at detach time is needed.
+if UBI would not write a new fastmap at detach time all erase counter
+modifications since the last fastmap are lost.
+</p>
+
+<h4><a name="L_fastmap_overhead">Overhead</a></h4>
+<p>Is fastmap enabled UBI will reserve enough PEBs to carry two complete
+fastmaps. In practice on modern NAND chips two PEBs are reserved for fastmap.
+</p>
+<p>
+There is also some runtime overhead, to guarantee that the new fastmap is valid
+and conistent UBI has to take care that all IO which would cause EBA changes
+are blocked while attaching. Depending on flash Chip this can take up to one
+second. Therefore, fastmap makes only sense on fast and large flash devices
+where a full scan takes too long. E.g. On 4GiB NAND chips a full scan takes
+several seconds whereas a fast attach needs less than one second.</p>
 
 <h2><a name="L_ubidoc">More documentation</a></h2>
 
-- 
1.7.11.5



From ivan.djelic at parrot.com  Thu Oct  4 08:04:05 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Thu, 4 Oct 2012 14:04:05 +0200
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <518397C60809E147AF5323E0420B992E3E9B4902@DBDE01.ent.ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
 <20121003185458.GA27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B4902@DBDE01.ent.ti.com>
Message-ID: <20121004120405.GA28840@parrot.com>

On Thu, Oct 04, 2012 at 09:03:42AM +0100, Philip, Avinash wrote:
(...)
> > > +int gpmc_calculate_ecc_bch(int cs, const u_char *dat, u_char *ecc)
> > > +{
> > > +	int i, eccbchtsel;
> > > +	u32 nsectors, reg, bch_val1, bch_val2, bch_val3, bch_val4;
> > > +
> > > +	if (gpmc_ecc_used != cs)
> > > +		return -EINVAL;
> > > +
> > > +	/* read number of sectors for ecc to be calculated */
> > > +	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
> > > +	/*
> > > +	 * find BCH scheme used
> > > +	 * 0 -> BCH4
> > > +	 * 1 -> BCH8
> > > +	 */
> > > +	eccbchtsel = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 12) & 0x3);
> > > +
> > > +	/* update ecc bytes for entire page */
> > > +	for (i = 0; i < nsectors; i++) {
> > > +
> > > +		reg = GPMC_ECC_BCH_RESULT_0 + 16 * i;
> > > +
> > > +		/* Read hw-computed remainder */
> > > +		bch_val1 = gpmc_read_reg(reg + 0);
> > > +		bch_val2 = gpmc_read_reg(reg + 4);
> > > +		if (eccbchtsel) {
> > > +			bch_val3 = gpmc_read_reg(reg + 8);
> > > +			bch_val4 = gpmc_read_reg(reg + 12);
> > > +		}
> > > +
> > > +		if (eccbchtsel) {
> > > +			/* BCH8 ecc scheme */
> > > +			*ecc++ = (bch_val4 & 0xFF);
> > > +			*ecc++ = ((bch_val3 >> 24) & 0xFF);
> > > +			*ecc++ = ((bch_val3 >> 16) & 0xFF);
> > > +			*ecc++ = ((bch_val3 >> 8) & 0xFF);
> > > +			*ecc++ = (bch_val3 & 0xFF);
> > > +			*ecc++ = ((bch_val2 >> 24) & 0xFF);
> > > +			*ecc++ = ((bch_val2 >> 16) & 0xFF);
> > > +			*ecc++ = ((bch_val2 >> 8) & 0xFF);
> > > +			*ecc++ = (bch_val2 & 0xFF);
> > > +			*ecc++ = ((bch_val1 >> 24) & 0xFF);
> > > +			*ecc++ = ((bch_val1 >> 16) & 0xFF);
> > > +			*ecc++ = ((bch_val1 >> 8) & 0xFF);
> > > +			*ecc++ = (bch_val1 & 0xFF);
> > > +			/* 14th byte of ecc not used */
> > > +			*ecc++ = 0;
> > > +		} else {
> > > +			/* BCH4 ecc scheme */
> > > +			*ecc++ = ((bch_val2 >> 12) & 0xFF);
> > > +			*ecc++ = ((bch_val2 >> 4) & 0xFF);
> > > +			*ecc++ = (((bch_val2 & 0xF) << 4) |
> > > +					((bch_val1 >> 28) & 0xF));
> > > +			*ecc++ = ((bch_val1 >> 20) & 0xFF);
> > > +			*ecc++ = ((bch_val1 >> 12) & 0xFF);
> > > +			*ecc++ = ((bch_val1 >> 4) & 0xFF);
> > > +			*ecc++ = ((bch_val1 & 0xF) << 4);
> > > +		}
> > > +	}
> > > +
> > > +	gpmc_ecc_used = -EINVAL;
> > > +	return 0;
> > > +}
> > > +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch);
> > 
> > Here you introduce a function very similar to gpmc_calculate_ecc_bch4 and
> > gpmc_calculate_ecc_bch8, but without the added benefit (IMHO) of the constant
> > polynomial that allows to get an ecc sequence of 0xFFs for a buffer filled with
> > 0xFFs. Why ?
> 
> I don't exactly understand what we benefitted/achieve. In my observation,
> this API does spare area also written with 0xFF if data area is 0xFFs.
> So the area looks like erased page again.

Precisely. It means you can read the page with ECC enabled without having to check if
the page has been programmed; it also enables bitflip correction on erased pages.

> > If using the ELM prevents you from reusing gpmc_calculate_ecc_bch[48], could you explain in which way ?
> 
> When using gpmc_calculate_ecc_bch[48], calculated ecc values modified.
> The read sequence we following is
> Read 512 byte -> read ECC bytes from spare area
> Now the calculated ECC will be zero if no error is reported. In case of error, a syndrome
> Polynomial is reported. In either case modifying will corrupt the data.

It is still possible to retrieve your original error syndrome, even using the technique transforming ECC on erased pages into 0xFFs.
But I guess you're not interested if you need RBL compatibility.

BR,
--
Ivan


From plagnioj at jcrosoft.com  Thu Oct  4 09:14:16 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu,  4 Oct 2012 15:14:16 +0200
Subject: [PATCH 1/1] mtd: st fsmc_nand: pass the ale and cmd resource via
 resource
Message-ID: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>

Do not use the platform_data to pass resource and be smart in the drivers.
Just pass it via resource

Switch to devm_request_and_ioremap at the sametime

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Vipin Kumar <vipin.kumar at st.com>
Cc: linux-mtd at lists.infradead.org
---
 .../devicetree/bindings/mtd/fsmc-nand.txt          |   12 +++---
 arch/arm/boot/dts/spear13xx.dtsi                   |   10 ++---
 arch/arm/boot/dts/spear300.dtsi                    |    8 ++--
 arch/arm/boot/dts/spear310.dtsi                    |    8 ++--
 arch/arm/boot/dts/spear320.dtsi                    |    8 ++--
 arch/arm/boot/dts/spear600.dtsi                    |    8 ++--
 arch/arm/mach-u300/core.c                          |   14 ++++++-
 drivers/mtd/nand/fsmc_nand.c                       |   44 +++++---------------
 include/linux/mtd/fsmc.h                           |    3 --
 9 files changed, 49 insertions(+), 66 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
index e2c663b..e3ea32e 100644
--- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
@@ -3,9 +3,7 @@
 Required properties:
 - compatible : "st,spear600-fsmc-nand"
 - reg : Address range of the mtd chip
-- reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
-- st,ale-off : Chip specific offset to ALE
-- st,cle-off : Chip specific offset to CLE
+- reg-names: Should contain the reg names "fsmc_regs", "nand_data", "nand_addr" and "nand_cmd"
 
 Optional properties:
 - bank-width : Width (in bytes) of the device.  If not present, the width
@@ -19,10 +17,10 @@ Example:
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0xd1800000 0x1000	/* FSMC Register */
-		       0xd2000000 0x4000>;	/* NAND Base */
-		reg-names = "fsmc_regs", "nand_data";
-		st,ale-off = <0x20000>;
-		st,cle-off = <0x10000>;
+		       0xd2000000 0x0010	/* NAND Base DATA */
+		       0xd2020000 0x0010	/* NAND Base ADDR */
+		       0xd2010000 0x0010>;	/* NAND Base CMD */
+		reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 
 		bank-width = <1>;
 		nand-skip-bbtscan;
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index f7b84ac..14a6d15 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -104,15 +104,15 @@
 			compatible = "st,spear600-fsmc-nand";
 			#address-cells = <1>;
 			#size-cells = <1>;
-			reg = <0xb0000000 0x1000	/* FSMC Register */
-			       0xb0800000 0x0010>;	/* NAND Base */
-			reg-names = "fsmc_regs", "nand_data";
+			reg = <0xb0000000 0x1000	/* FSMC Register*/
+			       0xb0800000 0x0010	/* NAND Base DATA */
+			       0xb0820000 0x0010	/* NAND Base ADDR */
+			       0xb0810000 0x0010>;	/* NAND Base CMD */
+			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 			interrupts = <0 20 0x4
 				      0 21 0x4
 				      0 22 0x4
 				      0 23 0x4>;
-			st,ale-off = <0x20000>;
-			st,cle-off = <0x10000>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
index ed3627c..bc43638 100644
--- a/arch/arm/boot/dts/spear300.dtsi
+++ b/arch/arm/boot/dts/spear300.dtsi
@@ -38,10 +38,10 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0x94000000 0x1000	/* FSMC Register */
-			       0x80000000 0x0010>;	/* NAND Base */
-			reg-names = "fsmc_regs", "nand_data";
-			st,ale-off = <0x20000>;
-			st,cle-off = <0x10000>;
+			       0x80000000 0x0010	/* NAND Base DATA */
+			       0x80020000 0x0010	/* NAND Base ADDR */
+			       0x80010000 0x0010>;	/* NAND Base CMD */
+			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
index 62fc4fb..7840e52 100644
--- a/arch/arm/boot/dts/spear310.dtsi
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -32,10 +32,10 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0x44000000 0x1000	/* FSMC Register */
-			       0x40000000 0x0010>;	/* NAND Base */
-			reg-names = "fsmc_regs", "nand_data";
-			st,ale-off = <0x10000>;
-			st,cle-off = <0x20000>;
+			       0x40000000 0x0010	/* NAND Base DATA */
+			       0x40020000 0x0010	/* NAND Base ADDR */
+			       0x40010000 0x0010>;	/* NAND Base CMD */
+			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
index 1f49d69..5ad8206 100644
--- a/arch/arm/boot/dts/spear320.dtsi
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -38,10 +38,10 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0x4c000000 0x1000	/* FSMC Register */
-			       0x50000000 0x0010>;	/* NAND Base */
-			reg-names = "fsmc_regs", "nand_data";
-			st,ale-off = <0x20000>;
-			st,cle-off = <0x10000>;
+			       0x50000000 0x0010	/* NAND Base DATA */
+			       0x50020000 0x0010	/* NAND Base ADDR */
+			       0x50010000 0x0010>;	/* NAND Base CMD */
+			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
index a3c36e4..4ecc66f 100644
--- a/arch/arm/boot/dts/spear600.dtsi
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -67,10 +67,10 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0xd1800000 0x1000	/* FSMC Register */
-			       0xd2000000 0x4000>;	/* NAND Base */
-			reg-names = "fsmc_regs", "nand_data";
-			st,ale-off = <0x20000>;
-			st,cle-off = <0x10000>;
+			       0xd2000000 0x0010	/* NAND Base DATA */
+			       0xd2020000 0x0010	/* NAND Base ADDR */
+			       0xd2010000 0x0010>;	/* NAND Base CMD */
+			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index ef6f602..527bcc2 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -252,6 +252,18 @@ static struct resource rtc_resources[] = {
  */
 static struct resource fsmc_resources[] = {
 	{
+		.name  = "nand_addr",
+		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
+		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name  = "nand_cmd",
+		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
+		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
 		.name  = "nand_data",
 		.start = U300_NAND_CS0_PHYS_BASE,
 		.end   = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
@@ -1496,8 +1508,6 @@ static struct fsmc_nand_platform_data nand_platform_data = {
 	.nr_partitions = ARRAY_SIZE(u300_partitions),
 	.options = NAND_SKIP_BBTSCAN,
 	.width = FSMC_NAND_BW8,
-	.ale_off = PLAT_NAND_ALE,
-	.cle_off = PLAT_NAND_CLE,
 };
 
 static struct platform_device nand_device = {
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 38d2624..cb86450 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -876,8 +876,6 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 			return -EINVAL;
 		}
 	}
-	of_property_read_u32(np, "st,ale-off", &pdata->ale_off);
-	of_property_read_u32(np, "st,cle-off", &pdata->cle_off);
 	if (of_get_property(np, "nand-skip-bbtscan", NULL))
 		pdata->options = NAND_SKIP_BBTSCAN;
 
@@ -935,41 +933,28 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	if (!res)
 		return -EINVAL;
 
-	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
-				pdev->name)) {
-		dev_err(&pdev->dev, "Failed to get memory data resourse\n");
-		return -ENOENT;
-	}
-
-	host->data_pa = (dma_addr_t)res->start;
-	host->data_va = devm_ioremap(&pdev->dev, res->start,
-			resource_size(res));
+	host->data_va = devm_request_and_ioremap(&pdev->dev, res);
 	if (!host->data_va) {
 		dev_err(&pdev->dev, "data ioremap failed\n");
 		return -ENOMEM;
 	}
+	host->data_pa = (dma_addr_t)res->start;
 
-	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off,
-			resource_size(res), pdev->name)) {
-		dev_err(&pdev->dev, "Failed to get memory ale resourse\n");
-		return -ENOENT;
-	}
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
+	if (!res)
+		return -EINVAL;
 
-	host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off,
-			resource_size(res));
+	host->addr_va = devm_request_and_ioremap(&pdev->dev, res);
 	if (!host->addr_va) {
 		dev_err(&pdev->dev, "ale ioremap failed\n");
 		return -ENOMEM;
 	}
 
-	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off,
-			resource_size(res), pdev->name)) {
-		dev_err(&pdev->dev, "Failed to get memory cle resourse\n");
-		return -ENOENT;
-	}
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
+	if (!res)
+		return -EINVAL;
 
-	host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off,
-			resource_size(res));
+	host->cmd_va = devm_request_and_ioremap(&pdev->dev, res);
 	if (!host->cmd_va) {
 		dev_err(&pdev->dev, "ale ioremap failed\n");
 		return -ENOMEM;
@@ -979,14 +964,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	if (!res)
 		return -EINVAL;
 
-	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
-			pdev->name)) {
-		dev_err(&pdev->dev, "Failed to get memory regs resourse\n");
-		return -ENOENT;
-	}
-
-	host->regs_va = devm_ioremap(&pdev->dev, res->start,
-			resource_size(res));
+	host->regs_va = devm_request_and_ioremap(&pdev->dev, res);
 	if (!host->regs_va) {
 		dev_err(&pdev->dev, "regs ioremap failed\n");
 		return -ENOMEM;
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index b200292..d6ed61e 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -155,9 +155,6 @@ struct fsmc_nand_platform_data {
 	unsigned int		width;
 	unsigned int		bank;
 
-	/* CLE, ALE offsets */
-	unsigned int		cle_off;
-	unsigned int		ale_off;
 	enum access_mode	mode;
 
 	void			(*select_bank)(uint32_t bank, uint32_t busw);
-- 
1.7.10.4



From Thomas.Betker at rohde-schwarz.com  Thu Oct  4 10:20:16 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Thu, 4 Oct 2012 16:20:16 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
Message-ID: <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>

Hello Joakim,

(sorry if the indentation is wrong, I have not yet found out how to do 
this in Lotus Notes):

[Joakim Tjernlund]
So maybe this will help(not even compile tested), don't know if 
jffs2_reserve_space()
can be called with f->sem held.
If this is bad, then perhaps move pg = 
grab_cache_page_write_begin(mapping, index, flags)
to later in this function somehow?
[/Joakim Tjernlund]

jffs2_reserve_space() must not be called with f->sem held because it 
acquires c->alloc_sem.

So I have moved mutex_lock(&f->sem) and grab_cache_page_write_begin() 
after jffs2_reserve_space(). Attached is my 3.4.11 patch (which is based 
on your patch) for review; I hope it is not mangled by Lotus Notes ...

The first tests (with proof of locking correctness enabled) were fine. The 
main tests will run until tomorrow evening, though; last time, it took me 
all day to reproduce the deadlock, and I want to be reasonably sure that 
it is gone -- and that no new deadlocks were introduced.

Best regards,
Thomas

-------------- next part --------------
A non-text attachment was scrubbed...
Name: jffs2_write_begin.patch
Type: application/octet-stream
Size: 2123 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121004/ada43f3b/attachment.obj>

From dedekind1 at gmail.com  Thu Oct  4 11:05:21 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 04 Oct 2012 18:05:21 +0300
Subject: UBIFS Recovery Issue: 'grab_empty_leb: could not find an empty
 LEB'
In-Reply-To: <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
References: <CAP+RiCC1afVbKAZESMcZGd1G3+7aKuLTQGggOEFGZxQM6o+QQA@mail.gmail.com>
 <1346413469.9709.44.camel@sauron.fi.intel.com>
 <CAP+RiCBRopbShAGf_fWCvK2R=uPPR1j4Pz12JfJxdEMUjwofNw@mail.gmail.com>
 <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
Message-ID: <1349363121.20373.69.camel@sauron.fi.intel.com>

On Mon, 2012-09-17 at 08:34 -0500, Brent Taylor wrote:
> Artem,
>    I was finally able to capture the issue again with linux version
> 3.5.1, and I now have a 64MB mtd image for you to look at.  The issue
> occurred in the root filesystem this time.  Let me know what's the
> best way to get this image to you.  The image was retrieved from a NOR
> flash chip instead of a NAND flash chip, but I've seen the error on
> both which leads me to believe it's not a flash driver issue and it's
> something in the UBIFS subsystem.  If there is more data you need from
> me to help track this down, just let me know.

Well, I do not have any service where you can upload it to. If it
compresses well, may be e-mail would work. Otherwise you'd need to give
me an URL where to download from.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121004/46b99227/attachment-0001.sig>

From dedekind1 at gmail.com  Thu Oct  4 11:43:09 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 04 Oct 2012 18:43:09 +0300
Subject: [PATCH] [MTD] slram: Invalid checking of absolute end address
In-Reply-To: <CAHODtZQEbc8d-U+MWY=dkZUfAJ-z0xOXMUXSWgg8Zotmicz0Ww@mail.gmail.com>
References: <CAHODtZT6UP4BCHuugpSr6q2=KoTDiGuW_hG_fqjWG7cXcTE35A@mail.gmail.com>
 <CAHODtZQEbc8d-U+MWY=dkZUfAJ-z0xOXMUXSWgg8Zotmicz0Ww@mail.gmail.com>
Message-ID: <1349365389.20373.72.camel@sauron.fi.intel.com>

On Thu, 2012-09-20 at 16:49 +0200, Jiri Engelthaler wrote:
> Fixed parsing end absolute address
> Signed-off-by: Jiri Engelthaler <engycz at gmail.com>
> ---
> --- linux-3.2.28/drivers/mtd/devices/slram.c	2012-08-19 19:15:38.000000000 +0200
> +++ linux-3.2.28.mod/drivers/mtd/devices/slram.c	2012-09-19
> 18:29:28.012740703 +0200
> @@ -266,7 +266,7 @@ static int parse_cmdline(char *devname,
> 
>  	if (*(szlength) != '+') {
>  		devlength = simple_strtoul(szlength, &buffer, 0);
> -		devlength = handle_unit(devlength, buffer) - devstart;
> +		devlength = handle_unit(devlength, buffer);
>  		if (devlength < devstart)
>  			goto err_out;

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121004/799cd904/attachment.sig>

From joakim.tjernlund at transmode.se  Thu Oct  4 12:15:46 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Thu, 4 Oct 2012 18:15:46 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
Message-ID: <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>

Thomas.Betker at rohde-schwarz.com wrote on 2012/10/04 16:20:16:
>
> Hello Joakim,
>
> (sorry if the indentation is wrong, I have not yet found out how to do
> this in Lotus Notes):

Try Reply With Internet-style History (We use Notes here too)

>
> [Joakim Tjernlund]
> So maybe this will help(not even compile tested), don't know if
> jffs2_reserve_space()
> can be called with f->sem held.
> If this is bad, then perhaps move pg =
> grab_cache_page_write_begin(mapping, index, flags)
> to later in this function somehow?
> [/Joakim Tjernlund]
>
> jffs2_reserve_space() must not be called with f->sem held because it
> acquires c->alloc_sem.

hmm, are you sure? Did it fail?
As far as I can see jffs2_garbage_collect_live() does this.

>
> So I have moved mutex_lock(&f->sem) and grab_cache_page_write_begin()
> after jffs2_reserve_space(). Attached is my 3.4.11 patch (which is based
> on your patch) for review; I hope it is not mangled by Lotus Notes ...

don't have time to look ATM

>
> The first tests (with proof of locking correctness enabled) were fine. The
> main tests will run until tomorrow evening, though; last time, it took me
> all day to reproduce the deadlock, and I want to be reasonably sure that
> it is gone -- and that no new deadlocks were introduced.
>
> Best regards,
> Thomas
>
> [attachment "jffs2_write_begin.patch" deleted by Joakim Tjernlund/Transmode]



From dedekind1 at gmail.com  Thu Oct  4 12:16:56 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 04 Oct 2012 19:16:56 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
Message-ID: <1349367416.20373.75.camel@sauron.fi.intel.com>

On Fri, 2012-09-21 at 17:41 +0200, Marcus Prebble wrote:
> Hi,
> 
> We are working on a project using UBI/UBIFS and I have run into a
> problem with mkfs.ubifs which I am hoping someone can advise on.
> Apologies if I have already missed the answer to this in the archives
> somewhere.
> 
> A requirement of the project is to take an image of the root filesystem
> (/) which is implemented as a static UBI read only volume. Obviously its
> not possible to unmount /, but it seems to be possible to re-mount the
> UBI volume, read only, onto another location e.g. /tmp/mnt/new_rootfs.
> 
> The problem arises when running mkfs.ubifs is that it fails saying that
> the output file cannot be in the UBIFS root directory.
> This sounds like a reasonable constraint if the output file really was
> in the root, but this is not the case for us seeing root is mounted
> somewhere belowtmp. To give a concrete example of the command we are
> running:
> 
> mkfs.ubifs --output=/tmp/rootfs.img  --leb-size=129024
> --root=/tmp/rootfs_mnt --min-io-size=2048 --max-leb-cnt=147 
> 
> Where /dev/ubi0_11 is mounted read-only on both / and /tmp/rootfs_mnt/.
> 
> Having a look at the source for mkfs.ubifs it seems that the function
> in_path(..) is the problem - it works up the directory tree using ../
> until it either reaches the top_dir (/) or the inode number/dev match in
> which case it fails. It doesn't seem that this section of code has
> changed in the latest version of mtd-utils (we are running 1.4.3-2) and
> I wonder if this is a bug in in_path(..) or a genuine safeguard against
> screwing something up? I suspect the former for when I disabled this
> check in mkfs.ubifs.c the resulting image was completely OK.

Well, obviously this is a safeguard check. If your source FS is
in /a/path/, and the output image file is /a/path/image, then we will
loop forever reading /a/path/image and writing the output
to /a/path/image.

In your case 'tmp' is a tmpfs, right? This is obviously a bug then. You
should probably analyze it and send a fix.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121004/17b23f9b/attachment.sig>

From Thomas.Betker at rohde-schwarz.com  Thu Oct  4 12:51:58 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Thu, 4 Oct 2012 18:51:58 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
 <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
Message-ID: <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>

Hello Joakim:

> Try Reply With Internet-style History (We use Notes here too)

Got it. Thanks!

> > jffs2_reserve_space() must not be called with f->sem held because it
> > acquires c->alloc_sem.
> 
> hmm, are you sure? Did it fail?
> As far as I can see jffs2_garbage_collect_live() does this.

jffs2_reserve_space() does mutex_lock(&c->alloc_sem) first thing, and 
README.Locking says "Never attempt to allocate space or lock alloc_sem 
with any f->sem held.". So I didn't even try; yes, I am a coward. (:-) 
Also, all the code I checked carefully releases f->sem before calling 
jffs2_reserve_space().

jffs2_garbage_collect_live() doesn't call jffs2_reserve_space() directly. 
Is it called indirectly somehow?

> > So I have moved mutex_lock(&f->sem) and grab_cache_page_write_begin()
> > after jffs2_reserve_space(). Attached is my 3.4.11 patch (which is 
based
> > on your patch) for review; I hope it is not mangled by Lotus Notes ...
> 
> don't have time to look ATM

Okay. When the tests succeed, I will simply mail it to the list as a 
regular patch, for general review.

Best regards,
Thomas



From monstr at monstr.eu  Thu Oct  4 13:40:16 2012
From: monstr at monstr.eu (Michal Simek)
Date: Thu,  4 Oct 2012 19:40:16 +0200
Subject: [PATCH] mtd: m25p80: Add support for Numonyx N25Q128
Message-ID: <1349372416-16925-1-git-send-email-monstr@monstr.eu>

From: Wendy Liang <wendy.liang at petalogix.com>

Add the id and sector mappings for SPI flash chips.

Signed-off-by: Wendy Liang <wendy.liang at petalogix.com>
Signed-off-by: Michal Simek <monstr at monstr.eu>
CC: David Woodhouse <dwmw2 at infradead.org>
CC: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
CC: Mike Frysinger <vapier at gentoo.org>
CC: linux-mtd at lists.infradead.org
---
 drivers/mtd/devices/m25p80.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5d0d68c..cad89f1 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -722,6 +722,9 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
 	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
 
+	/* Numonyx -- n25q */
+	{ "n25q128",    INFO(0x20ba18,  0, 64 * 1024, 256, 0) },
+
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
 	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
 	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
-- 
1.7.0.4



From joakim.tjernlund at transmode.se  Thu Oct  4 14:39:42 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Thu, 4 Oct 2012 20:39:42 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
 <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
 <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>
Message-ID: <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>

Thomas.Betker at rohde-schwarz.com wrote on 2012/10/04 18:51:58:
>
> Hello Joakim:
>
> > Try Reply With Internet-style History (We use Notes here too)
>
> Got it. Thanks!
>
> > > jffs2_reserve_space() must not be called with f->sem held because it
> > > acquires c->alloc_sem.
> >
> > hmm, are you sure? Did it fail?
> > As far as I can see jffs2_garbage_collect_live() does this.
>
> jffs2_reserve_space() does mutex_lock(&c->alloc_sem) first thing, and
> README.Locking says "Never attempt to allocate space or lock alloc_sem
> with any f->sem held.". So I didn't even try; yes, I am a coward. (:-)
> Also, all the code I checked carefully releases f->sem before calling
> jffs2_reserve_space().

I see, thanks.

>
> jffs2_garbage_collect_live() doesn't call jffs2_reserve_space() directly.
> Is it called indirectly somehow?

hmm, misread the code a bit so forget this comment.

>
> > > So I have moved mutex_lock(&f->sem) and grab_cache_page_write_begin()
> > > after jffs2_reserve_space(). Attached is my 3.4.11 patch (which is
> based
> > > on your patch) for review; I hope it is not mangled by Lotus Notes ...
> >
> > don't have time to look ATM
>
> Okay. When the tests succeed, I will simply mail it to the list as a
> regular patch, for general review.

I think your patch will work, but I don't like having 2 call sites
to grab_cache_page_write_begin(mapping, index, flags) so I came
up with this instead(untested as well):

diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index db3889b..8eaeaa35 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -140,31 +140,33 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
-	int ret = 0;
+	int ret = -ENOMEM;
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_raw_inode ri;
+	uint32_t alloc_len;
+
+	if (pageofs > inode->i_size) {
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			return ret;
+	}

+	mutex_lock(&f->sem);
 	pg = grab_cache_page_write_begin(mapping, index, flags);
 	if (!pg)
-		return -ENOMEM;
+		goto out_unlock;
 	*pagep = pg;

 	jffs2_dbg(1, "%s()\n", __func__);

-	if (pageofs > inode->i_size) {
+	if (!ret) { /* reserve_space succeded */
 		/* Make new hole frag from old EOF to new page */
-		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
-		uint32_t alloc_len;

 		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs);

-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			goto out_page;
-
-		mutex_lock(&f->sem);
 		memset(&ri, 0, sizeof(ri));

 		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +193,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 		if (IS_ERR(fn)) {
 			ret = PTR_ERR(fn);
 			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +207,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 			jffs2_mark_node_obsolete(c, fn->raw);
 			jffs2_free_full_dnode(fn);
 			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		jffs2_complete_reservation(c);
 		inode->i_size = pageofs;
-		mutex_unlock(&f->sem);
 	}

 	/*
@@ -220,18 +219,19 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 	 * case of a short-copy.
 	 */
 	if (!PageUptodate(pg)) {
-		mutex_lock(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
-		mutex_unlock(&f->sem);
 		if (ret)
 			goto out_page;
 	}
+	mutex_unlock(&f->sem);
 	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
-	return ret;
+	return 0;

 out_page:
 	unlock_page(pg);
 	page_cache_release(pg);
+out_unlock:
+	mutex_unlock(&f->sem);
 	return ret;
 }




From joakim.tjernlund at transmode.se  Thu Oct  4 14:55:28 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Thu, 4 Oct 2012 20:55:28 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
 <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
 <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>
 <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>
Message-ID: <OFEB6FD0F2.3E7FF2DB-ONC1257A8D.00677FC4-C1257A8D.0067F4B9@transmode.se>

>
> Thomas.Betker at rohde-schwarz.com wrote on 2012/10/04 18:51:58:
> >
> > Hello Joakim:
> >
> > > Try Reply With Internet-style History (We use Notes here too)
> >
> > Got it. Thanks!
> >
> > > > jffs2_reserve_space() must not be called with f->sem held because it
> > > > acquires c->alloc_sem.
> > >
> > > hmm, are you sure? Did it fail?
> > > As far as I can see jffs2_garbage_collect_live() does this.
> >
> > jffs2_reserve_space() does mutex_lock(&c->alloc_sem) first thing, and
> > README.Locking says "Never attempt to allocate space or lock alloc_sem
> > with any f->sem held.". So I didn't even try; yes, I am a coward. (:-)
> > Also, all the code I checked carefully releases f->sem before calling
> > jffs2_reserve_space().
>
> I see, thanks.
>
> >
> > jffs2_garbage_collect_live() doesn't call jffs2_reserve_space() directly.
> > Is it called indirectly somehow?
>
> hmm, misread the code a bit so forget this comment.
>
> >
> > > > So I have moved mutex_lock(&f->sem) and grab_cache_page_write_begin()
> > > > after jffs2_reserve_space(). Attached is my 3.4.11 patch (which is
> > based
> > > > on your patch) for review; I hope it is not mangled by Lotus Notes ...
> > >
> > > don't have time to look ATM
> >
> > Okay. When the tests succeed, I will simply mail it to the list as a
> > regular patch, for general review.
>
> I think your patch will work, but I don't like having 2 call sites
> to grab_cache_page_write_begin(mapping, index, flags) so I came
> up with this instead(untested as well):

Forgot, could you add some debug code to test if pageofs <= inode->i_size:
	ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
      ....
      if(pageofs <= inode->i_size) {
         print debug stuff here
      }
	ri.dsize = cpu_to_je32(pageofs - inode->i_size);

 Jocke



From marex at denx.de  Thu Oct  4 16:24:29 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 4 Oct 2012 22:24:29 +0200
Subject: [PATCH v2 0/9] add EDO feature for gpmi-nand driver
In-Reply-To: <1347519480-31106-1-git-send-email-b32955@freescale.com>
References: <1347519480-31106-1-git-send-email-b32955@freescale.com>
Message-ID: <201210042224.30095.marex@denx.de>

Dear Huang Shijie,

> The ONFI nand supports the EDO (extended data out) feature in
> asynchronous mode when the host controller(such as gpmi-nand)
> uses a tRC of less then 30ns.
> 
> The gpmi can supports this EDO feature.
> This patch set adds the EDO support the gpmi-nand driver.
> 
> patch 1 ~ patch 2:
> 	 These two patches provide the infrastructure for the EDO feature.
>          They add necessary MTD helpers for the ONFI nand set/get features,
> 	 and the help to get the supportted timing mode.
> 	 These two patches are new version. The init version has been
> 	 reviewed by Vikram & Florian.
> 
> patch 3 ~ patch 7:
>          These patches are clean-ups for the gpmi-nand's timing code.
> 	 Also they make the some preparations for the EDO patch.
> 
> patch 8: add the EDO feature to the gpmi-nand.
> 
> 
> patch 9: a small optimization for the timing.
>          only set the timing registers one time.
> 
> I tested this patch set on the IMX6Q-arm2 board with several Micron's
> ONFI nand chips. Some chips only can supports to mode 4, some chips
> can supports to mode 5.
> 
> The performance is much improved. Take Micron MT29F32G08MAA for example
> (in mode 5, 100MHz):
[...]

Was this ever tested on something else than mx6q? I suspect these broke gpmi 
nand on mx28. Can you please verify?


From marex at denx.de  Thu Oct  4 16:56:06 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 4 Oct 2012 22:56:06 +0200
Subject: [PATCH v2 0/9] add EDO feature for gpmi-nand driver
In-Reply-To: <201210042224.30095.marex@denx.de>
References: <1347519480-31106-1-git-send-email-b32955@freescale.com>
 <201210042224.30095.marex@denx.de>
Message-ID: <201210042256.06286.marex@denx.de>

Dear Huang Shijie,

> > The ONFI nand supports the EDO (extended data out) feature in
> > asynchronous mode when the host controller(such as gpmi-nand)
> > uses a tRC of less then 30ns.
> > 
> > The gpmi can supports this EDO feature.
> > This patch set adds the EDO support the gpmi-nand driver.
> > 
> > patch 1 ~ patch 2:
> > 	 These two patches provide the infrastructure for the EDO feature.
> > 	 
> >          They add necessary MTD helpers for the ONFI nand set/get
> >          features,
> > 	 
> > 	 and the help to get the supportted timing mode.
> > 	 These two patches are new version. The init version has been
> > 	 reviewed by Vikram & Florian.
> > 
> > patch 3 ~ patch 7:
> >          These patches are clean-ups for the gpmi-nand's timing code.
> > 	 
> > 	 Also they make the some preparations for the EDO patch.
> > 
> > patch 8: add the EDO feature to the gpmi-nand.
> > 
> > 
> > patch 9: a small optimization for the timing.
> > 
> >          only set the timing registers one time.
> > 
> > I tested this patch set on the IMX6Q-arm2 board with several Micron's
> > ONFI nand chips. Some chips only can supports to mode 4, some chips
> > can supports to mode 5.
> > 
> > The performance is much improved. Take Micron MT29F32G08MAA for example
> 
> > (in mode 5, 100MHz):
> [...]
> 
> Was this ever tested on something else than mx6q? I suspect these broke
> gpmi nand on mx28. Can you please verify?

Hm, this series isnt the problematic one ... poking further ... I recall next 
20120921 worked fine.

Best regards,
Marek Vasut


From vincenzo.aliberti at gmail.com  Thu Oct  4 17:17:14 2012
From: vincenzo.aliberti at gmail.com (Vincenzo Aliberti)
Date: Thu,  4 Oct 2012 23:17:14 +0200
Subject: =?UTF-8?q?=5BPATCH=5D=20=5BMTD=5D=20MTD=20driver=20for=20LPDDR2-NVM=20PCM=20memories?=
Message-ID: <1349385434-3073-1-git-send-email-valibert@micron.com>

Dear All,
    continuing Micron support activity on PCM memories you can find here-below a 
patch containing MTD driver for LPDDR2-NVM memories as demoed during Q2 Linaro 
Connect in Hong Kong.

Let me thank TI Panda open source team for support on platform enablement 
activity and Arnd for his first feedback on driver implementation

Regards,
	Vincenzo


Signed-off-by: Vincenzo Aliberti <vincenzo.aliberti at gmail.com>
---
 drivers/mtd/Kconfig                 |    2 +
 drivers/mtd/Makefile                |    2 +-
 drivers/mtd/lpddr2_nvm/Kconfig      |    9 +
 drivers/mtd/lpddr2_nvm/Makefile     |    5 +
 drivers/mtd/lpddr2_nvm/lpddr2_nvm.c |  547 +++++++++++++++++++++++++++++++++++
 include/mtd/mtd-abi.h               |    1 +
 6 files changed, 565 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/lpddr2_nvm/Kconfig
 create mode 100644 drivers/mtd/lpddr2_nvm/Makefile
 create mode 100644 drivers/mtd/lpddr2_nvm/lpddr2_nvm.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 27143e0..be277b9 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -326,6 +326,8 @@ source "drivers/mtd/onenand/Kconfig"
 
 source "drivers/mtd/lpddr/Kconfig"
 
+source "drivers/mtd/lpddr2_nvm/Kconfig"
+
 source "drivers/mtd/ubi/Kconfig"
 
 endif # MTD
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index f901354..783310e 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -30,6 +30,6 @@ obj-$(CONFIG_MTD_SWAP)		+= mtdswap.o
 nftl-objs		:= nftlcore.o nftlmount.o
 inftl-objs		:= inftlcore.o inftlmount.o
 
-obj-y		+= chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
+obj-y		+= chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ lpddr2_nvm/
 
 obj-$(CONFIG_MTD_UBI)		+= ubi/
diff --git a/drivers/mtd/lpddr2_nvm/Kconfig b/drivers/mtd/lpddr2_nvm/Kconfig
new file mode 100644
index 0000000..a5cec65
--- /dev/null
+++ b/drivers/mtd/lpddr2_nvm/Kconfig
@@ -0,0 +1,9 @@
+menu "LPDDR2_NVM memory drivers"
+	depends on MTD!=n
+
+config MTD_LPDDR2_NVM
+	tristate "Support for LPDDR2-NVM PCM memories"
+	help
+	  This option enables support of LPDDR2-NVM (Low power double data rate 2)
+	  PCM memories.
+endmenu
diff --git a/drivers/mtd/lpddr2_nvm/Makefile b/drivers/mtd/lpddr2_nvm/Makefile
new file mode 100644
index 0000000..dc6fe27
--- /dev/null
+++ b/drivers/mtd/lpddr2_nvm/Makefile
@@ -0,0 +1,5 @@
+#
+# linux/drivers/mtd/lpddr2_nvm/Makefile
+#
+
+obj-$(CONFIG_MTD_LPDDR2_NVM)	+= lpddr2_nvm.o
diff --git a/drivers/mtd/lpddr2_nvm/lpddr2_nvm.c b/drivers/mtd/lpddr2_nvm/lpddr2_nvm.c
new file mode 100644
index 0000000..9c97a9e
--- /dev/null
+++ b/drivers/mtd/lpddr2_nvm/lpddr2_nvm.c
@@ -0,0 +1,547 @@
+/*
+ * LPDDR2-NVM MTD driver. This module provides read, write, erase, lock/unlock
+ * support for LPDDR2-NVM PCM memories
+ *
+ * Copyright ? 2012 Micron Technology, Inc.
+ *
+ * Vincenzo Aliberti <vincenzo.aliberti at gmail.com>
+ * Domenico Manna <domenico.manna at gmail.com>
+ * Many thanks to Andrea Vigilante for intial enabling
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+
+/* Parameters */
+#define ERASE_BLOCKSIZE			(0x00020000/2)	/* in Word */
+#define WRITE_BUFFSIZE			(0x00000400/2)	/* in Word */
+#define OW_BASE_ADDRESS			0x00000000	/* OW offset */
+
+/* PFOW symbols address offset */
+#define PFOW_QUERY_STRING_P		(0x0000/2)	/* in Word */
+#define PFOW_QUERY_STRING_F		(0x0002/2)	/* in Word */
+#define PFOW_QUERY_STRING_O		(0x0004/2)	/* in Word */
+#define PFOW_QUERY_STRING_W		(0x0006/2)	/* in Word */
+
+/* OW registers address */
+#define CMD_CODE_OFS			(0x0080/2)	/* in Word */
+#define CMD_DATA_OFS			(0x0084/2)	/* in Word */
+#define CMD_ADD_L_OFS			(0x0088/2)	/* in Word */
+#define CMD_ADD_H_OFS			(0x008A/2)	/* in Word */
+#define MPR_L_OFS			(0x0090/2)	/* in Word */
+#define MPR_H_OFS			(0x0092/2)	/* in Word */
+#define CMD_EXEC_OFS			(0x00C0/2)	/* in Word */
+#define STATUS_REG_OFS			(0x00CC/2)	/* in Word */
+#define PRG_BUFFER_OFS			(0x0010/2)	/* in Word */
+
+/* Datamask */
+#define MR_CFGMASK			0x8000
+#define SR_OK_DATAMASK			0x0080
+
+/* LPDDR2-NVM Commands */
+#define LPDDR2_NVM_LOCK			0x0061
+#define LPDDR2_NVM_UNLOCK		0x0062
+#define LPDDR2_NVM_SW_PROGRAM		0x0041
+#define LPDDR2_NVM_SW_OVERWRITE		0x0042
+#define LPDDR2_NVM_BUF_PROGRAM		0x00E9
+#define LPDDR2_NVM_BUF_OVERWRITE	0x00EA
+#define LPDDR2_NVM_ERASE		0x0020
+
+/*
+ * Internal Type Definitions
+ * pcm_int_data contains memory controller details:
+ * @reg_data : LPDDR2_MODE_REG_DATA register address after remapping
+ * @reg_cfg  : LPDDR2_MODE_REG_CFG register address after remapping
+ * &bus_width: memory bus-width (eg: x16 2 Bytes, x32 4 Bytes)
+ */
+struct pcm_int_data {
+	void __iomem *reg_data;
+	void __iomem *reg_cfg;
+	int bus_width;
+};
+
+static DEFINE_MUTEX(lpdd2_nvm_mutex);
+
+static inline map_word build_map_word(u_long myword)
+{
+	map_word val = { {0} };
+	val.x[0] = myword;
+	return val;
+}
+
+static inline u_int build_mr_cfgmaks(u_int bus_width)
+{
+	u_int val = MR_CFGMASK;
+
+	if (bus_width == 0x0004)		/* x32 device */
+		val = val<<16;
+
+	return val;
+}
+
+static inline u_int build_sr_ok_datamask(u_int bus_width)
+{
+	u_int val = SR_OK_DATAMASK;
+
+	if (bus_width == 0x0004)		/* x32 device */
+		val = (val<<16)+val;
+
+	return val;
+}
+
+/*
+ * Enable lpddr2-nvm Overlay Window
+ */
+static inline void ow_enable(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+
+	writel_relaxed(build_mr_cfgmaks(pcm_data->bus_width) | 0x18,
+		pcm_data->reg_cfg);
+	writel_relaxed(0x01, pcm_data->reg_data);
+}
+
+/*
+ * Disable lpddr2-nvm Overlay Window
+ */
+static inline void ow_disable(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+
+	writel_relaxed(build_mr_cfgmaks(pcm_data->bus_width) | 0x18,
+		pcm_data->reg_cfg);
+	writel_relaxed(0x02, pcm_data->reg_data);
+}
+
+/*
+ * Execute lpddr2-nvm operations
+ */
+static int lpddr2_nvm_do_op(struct map_info *map, u_long cmd_code,
+	u_long cmd_data, u_long cmd_add, u_long cmd_mpr, u_char *buf)
+{
+	map_word add_l = { {0} }, add_h = { {0} }, mpr_l = { {0} },
+		mpr_h = { {0} }, data_l = { {0} }, cmd = { {0} },
+		exec_cmd = { {0} }, sr;
+	map_word data_h = { {0} };	/* only for 2x x16 devices stacked */
+	u_long i, status_reg, prg_buff_ofs;
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	u_int sr_ok_datamask = build_sr_ok_datamask(pcm_data->bus_width);
+
+	/* Builds low and high words for OW Control Registers */
+	add_l.x[0]	= cmd_add&0x0000FFFF;
+	add_h.x[0]	= (cmd_add>>16)&0x0000FFFF;
+	mpr_l.x[0]	= cmd_mpr&0x0000FFFF;
+	mpr_h.x[0]	= (cmd_mpr>>16)&0x0000FFFF;
+	cmd.x[0]	= cmd_code&0x0000FFFF;
+	exec_cmd.x[0]	= 0x0001;
+	data_l.x[0]	= cmd_data&0x0000FFFF;
+	data_h.x[0]	= (cmd_data>>16)&0x0000FFFF; /* only for 2x x16 */
+
+	/* Set Overlay Window Control Registers */
+	map_write(map, cmd, map->pfow_base+CMD_CODE_OFS*pcm_data->bus_width);
+	map_write(map, data_l, map->pfow_base+CMD_DATA_OFS*pcm_data->bus_width);
+	map_write(map, add_l, map->pfow_base+CMD_ADD_L_OFS*pcm_data->bus_width);
+	map_write(map, add_h, map->pfow_base+CMD_ADD_H_OFS*pcm_data->bus_width);
+	map_write(map, mpr_l, map->pfow_base+MPR_L_OFS*pcm_data->bus_width);
+	map_write(map, mpr_h, map->pfow_base+MPR_H_OFS*pcm_data->bus_width);
+	if (pcm_data->bus_width == 0x0004) {	/* 2x16 devices stacked */
+		map_write(map, cmd, map->pfow_base +
+			CMD_CODE_OFS*pcm_data->bus_width + 2);
+		map_write(map, data_h, map->pfow_base +
+			CMD_DATA_OFS*pcm_data->bus_width + 2);
+		map_write(map, add_l, map->pfow_base +
+			CMD_ADD_L_OFS*pcm_data->bus_width + 2);
+		map_write(map, add_h, map->pfow_base +
+			CMD_ADD_H_OFS*pcm_data->bus_width + 2);
+		map_write(map, mpr_l, map->pfow_base +
+			MPR_L_OFS*pcm_data->bus_width + 2);
+		map_write(map, mpr_h, map->pfow_base +
+			MPR_H_OFS*pcm_data->bus_width + 2);
+	}
+
+	/* Fill Program Buffer */
+	if ((cmd_code == LPDDR2_NVM_BUF_PROGRAM) ||
+		(cmd_code == LPDDR2_NVM_BUF_OVERWRITE)) {
+		prg_buff_ofs = (map_read(map, map->pfow_base +
+			PRG_BUFFER_OFS*pcm_data->bus_width)).x[0];
+		for (i = 0; i < cmd_mpr; i++) {
+			map_write(map, build_map_word(buf[i]), map->pfow_base +
+			prg_buff_ofs + i);
+		}
+	}
+
+	/* Command Execute */
+	map_write(map, exec_cmd, map->pfow_base+CMD_EXEC_OFS*
+		pcm_data->bus_width);
+	if (pcm_data->bus_width == 0x0004)	/* 2x16 devices stacked */
+		map_write(map, exec_cmd, map->pfow_base +
+			CMD_EXEC_OFS*pcm_data->bus_width + 2);
+
+	/* Status Register Check */
+	do {
+		sr = map_read(map, map->pfow_base +
+			STATUS_REG_OFS*pcm_data->bus_width);
+		status_reg = sr.x[0];
+		if (pcm_data->bus_width == 0x0004) {/* 2x16 devices stacked */
+			sr = map_read(map, map->pfow_base +
+				STATUS_REG_OFS*pcm_data->bus_width + 2);
+			status_reg += sr.x[0]<<16;
+		}
+	} while ((status_reg&sr_ok_datamask) != sr_ok_datamask);
+
+	return (((status_reg&sr_ok_datamask) == sr_ok_datamask) ? 0 : -EIO);
+}
+
+/*
+ * Execute lpddr2-nvm operations @ block level
+ */
+static int lpddr2_nvm_do_block_op(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len, u_char block_op)
+{
+	struct map_info *map = mtd->priv;
+	u_long add, end_add;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	add = start_add;
+	end_add = add + len;
+
+	if ((add > mtd->size) || (end_add > mtd->size)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	do {
+		ret = lpddr2_nvm_do_op(map, block_op, 0x00, add, add, NULL);
+		if (ret)
+			goto out;
+		add += mtd->erasesize;
+	} while (add < end_add);
+
+out:
+	ow_disable(map);
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * verify presence of PFOW string
+ */
+static int lpddr2_nvm_pfow_present(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	map_word pfow_val[4];
+	unsigned int found = 1;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	/* Load string from array */
+	pfow_val[0] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_P *
+			pcm_data->bus_width);
+	pfow_val[1] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_F *
+			pcm_data->bus_width);
+	pfow_val[2] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_O *
+			pcm_data->bus_width);
+	pfow_val[3] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_W *
+			pcm_data->bus_width);
+
+	/* Verify the string loaded vs expected */
+	if (!map_word_equal(map, build_map_word('P'), pfow_val[0]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('F'), pfow_val[1]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('O'), pfow_val[2]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('W'), pfow_val[3]))
+		found = 0;
+
+	ow_disable(map);
+
+	mutex_unlock(&lpdd2_nvm_mutex);
+
+	return found;
+}
+
+/*
+ * lpddr2_nvm driver read method
+ */
+static int lpddr2_nvm_read(struct mtd_info *mtd, loff_t start_add,
+				size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	*retlen = len;
+
+	if ((start_add + len) > mtd->size) {
+		pr_alert("lpddr2_nvm: read out of memory range\n");
+		*retlen = 0;
+		ret = -EINVAL;
+		goto out;
+	}
+
+	map_copy_from(map, buf, start_add, *retlen);
+
+out:
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver write method
+ */
+static int lpddr2_nvm_write(struct mtd_info *mtd, loff_t start_add,
+				size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	u_long add, current_len, tot_len, target_len, my_data;
+	u_char *write_buf = (u_char *)buf;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	/* Set start value for the variables */
+	add = start_add;
+	target_len = len;
+	tot_len = 0;
+
+	if ((start_add + len) > mtd->size) {
+		pr_alert("lpddr2_nvm: write out of memory range\n");
+		*retlen = 0;
+		ret = -EINVAL;
+		goto out;
+	}
+
+	while (tot_len < target_len) {
+		if (!(IS_ALIGNED(add, mtd->writesize))) { /* do sw program */
+			my_data = write_buf[tot_len];
+			my_data += (write_buf[tot_len+1])<<8;
+			if (pcm_data->bus_width == 0x0004) {/* 2x16 devices */
+				my_data += (write_buf[tot_len+2])<<16;
+				my_data += (write_buf[tot_len+3])<<24;
+			}
+			ret = lpddr2_nvm_do_op(map, LPDDR2_NVM_SW_OVERWRITE,
+				my_data, add, 0x00, NULL);
+			if (ret)
+				goto out;
+
+			add += pcm_data->bus_width;
+			tot_len += pcm_data->bus_width;
+		} else {		/* do buffer program */
+			current_len = min(target_len - tot_len,
+				(u_long) mtd->writesize);
+			ret = lpddr2_nvm_do_op(map, LPDDR2_NVM_BUF_OVERWRITE,
+				0x00, add, current_len, write_buf + tot_len);
+			if (ret)
+				goto out;
+
+			add += current_len;
+			tot_len += current_len;
+		}
+	}
+
+out:
+	*retlen = tot_len;
+	ow_disable(map);
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver erase method
+ */
+static int lpddr2_nvm_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	int ret = lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
+		LPDDR2_NVM_ERASE);
+	if (!ret) {
+		instr->state = MTD_ERASE_DONE;
+		mtd_erase_callback(instr);
+	}
+
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver unlock method
+ */
+static int lpddr2_nvm_unlock(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len)
+{
+	return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_UNLOCK);
+}
+
+/*
+ * lpddr2_nvm driver lock method
+ */
+static int lpddr2_nvm_lock(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len)
+{
+	return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_LOCK);
+}
+
+/*
+ * lpddr2_nvm driver probe method
+ */
+static int lpddr2_nvm_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct map_info *lpddr2_nvm_map;
+	struct mtd_info *lpddr2_nvm_mtd;
+	struct resource *address_range = platform_get_resource(pdev,
+						IORESOURCE_MEM, 0);
+	struct resource *control_regs = platform_get_resource(pdev,
+						IORESOURCE_MEM, 1);
+	struct resource *buswidth = platform_get_resource(pdev,
+						IORESOURCE_BUS, 0);
+	struct pcm_int_data *pcm_data;
+
+	/* Allocate memory control_regs data structures */
+	pcm_data = kzalloc(sizeof(*pcm_data), GFP_KERNEL);
+	if (!control_regs) {
+		pr_alert(
+		"lpddr2_nvm_probe: Failed to allocate memory for int_data\n");
+		ret = 1;
+		goto out;
+	}
+	pcm_data->reg_data =	(void *) control_regs->start;
+	pcm_data->reg_cfg =	(void *) control_regs->end;
+	pcm_data->bus_width =	(int) buswidth->start;
+
+	/* Allocate memory for map_info & mtd_info data structures */
+	lpddr2_nvm_map = kzalloc(sizeof(*lpddr2_nvm_map), GFP_KERNEL);
+	if (!lpddr2_nvm_map) {
+		pr_alert(
+		"lpddr2_nvm_probe: Failed to allocate memory for map\n");
+		ret = 1;
+		goto out;
+	}
+
+	lpddr2_nvm_mtd = kzalloc(sizeof(*lpddr2_nvm_mtd), GFP_KERNEL);
+	if (!lpddr2_nvm_mtd) {
+		pr_alert(
+		"lpddr2_nvm_probe: Failed to allocate memory for mtd\n");
+		ret = 1;
+		goto out;
+	}
+
+	/* Reserve lpddr2_nvm address range */
+	if (request_mem_region(address_range->start, (address_range->end -
+		address_range->start + 1), "lpddr2_nvm") == NULL) {
+		pr_alert(
+		"lpddr2_nvm_probe: Unable to reserve memory address %#010x\n",
+		address_range->start);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* Populate map_info data structure */
+	*lpddr2_nvm_map = (struct map_info) {
+		.virt		= ioremap_nocache(address_range->start,
+				(address_range->end-address_range->start+1)),
+		.name		= pdev->dev.init_name,
+		.phys		= address_range->start,
+		.size		= address_range->end - address_range->start + 1,
+		.bankwidth	= pcm_data->bus_width/2,
+		.pfow_base	= OW_BASE_ADDRESS,
+		.fldrv_priv	= pcm_data,
+	};
+
+	simple_map_init(lpddr2_nvm_map);	/* fill with default methods */
+
+	/* Populate mtd_info data structure */
+	*lpddr2_nvm_mtd = (struct mtd_info) {
+		.name		= pdev->dev.init_name,
+		.type		= MTD_RAM,
+		.priv		= lpddr2_nvm_map,
+		.size		= address_range->end - address_range->start + 1,
+		.erasesize	= ERASE_BLOCKSIZE * pcm_data->bus_width,
+		.writesize	= 1,
+		.writebufsize	= WRITE_BUFFSIZE * pcm_data->bus_width,
+		.flags		= (MTD_CAP_PCM | MTD_POWERUP_LOCK),
+		._read		= lpddr2_nvm_read,
+		._read_oob	= NULL,
+		._write		= lpddr2_nvm_write,
+		._write_oob	= NULL,
+		._erase		= lpddr2_nvm_erase,
+		._unlock	= lpddr2_nvm_unlock,
+		._lock		= lpddr2_nvm_lock,
+		._sync		= NULL,
+		._suspend	= NULL,
+		._resume	= NULL,
+		._block_isbad	= NULL,
+		._block_markbad	= NULL,
+	};
+
+	/* Verify the presence of the device looking for PFOW string */
+	if (lpddr2_nvm_pfow_present(lpddr2_nvm_map)) {
+		pr_alert("lpddr2_nvm_probe: device recognized\n");
+		/* Register the mtd_partition structure */
+		if (mtd_add_partition(lpddr2_nvm_mtd, "my_pcm", 0x10000000,
+			0x00)){
+			pr_alert(
+			"lpddr2_nvm_probe: Failed to add mtd partition\n");
+			ret = 1;
+			goto out;
+		}
+		ret = 0;
+	} else {
+		pr_alert("%s: PFOW string not found at address %#010lx\n",
+			lpddr2_nvm_map->name, lpddr2_nvm_map->pfow_base);
+		ret = 1;
+	}
+
+out:
+	return ret;
+}
+
+/* Initialize platform_driver data structure for lpddr2_nvm */
+static struct platform_driver lpddr2_nvm_drv = {
+	.driver		= {
+		.name	= "lpddr2_nvm",
+	},
+	.probe		= lpddr2_nvm_probe,
+	.remove		= NULL,
+	.suspend	= NULL,
+	.resume		= NULL,
+};
+
+module_platform_driver(lpddr2_nvm_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vincenzo Aliberti <vincenzo.aliberti at gmail.com>");
+MODULE_DESCRIPTION("MTD driver for LPDDR2-NVM PCM memories");
+
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 36eace0..33f3036 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -109,6 +109,7 @@ struct mtd_write_req {
 #define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 #define MTD_CAP_NORFLASH	(MTD_WRITEABLE | MTD_BIT_WRITEABLE)
 #define MTD_CAP_NANDFLASH	(MTD_WRITEABLE)
+#define MTD_CAP_PCM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 
 /* Obsolete ECC byte placement modes (used with obsolete MEMGETOOBSEL) */
 #define MTD_NANDECC_OFF		0	// Switch off ECC (Not recommended)
-- 
1.7.9.5



From marex at denx.de  Thu Oct  4 20:51:18 2012
From: marex at denx.de (Marek Vasut)
Date: Fri, 5 Oct 2012 02:51:18 +0200
Subject: m25p80: missing MTD owner
In-Reply-To: <50694DCB.6010303@parrot.com>
References: <50694DCB.6010303@parrot.com>
Message-ID: <201210050251.18859.marex@denx.de>

Dear Gr?gor Boirie,

> Hi all,
> 
> It seems possible to unload m25p80 module while a JFFS2 partition is
> still mounted onto flash. This produces oops when MTD layer tries to
> access underlying device later on.
> 
> A quick look at m25p_probe shows that "owner" field of allocated mtd
> device structure is left uninitialized, preventing MTD layer from
> incrementing module usage count. This patch for v3.4.11 solves the issue
> for me :
> 
> @@ -873,6 +873,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
>         else
>                 flash->mtd.name = dev_name(&spi->dev);
> 
> +       flash->mtd.owner = THIS_MODULE;
>         flash->mtd.type = MTD_NORFLASH;
>         flash->mtd.writesize = 1;
>         flash->mtd.flags = MTD_CAP_NORFLASH;
> 
> 
> Regards.

Do you mind submitting a proper patch via git send-email please?

Best regards,
Marek Vasut


From marex at denx.de  Thu Oct  4 21:37:11 2012
From: marex at denx.de (Marek Vasut)
Date: Fri, 5 Oct 2012 03:37:11 +0200
Subject: [PATCH 9/9] mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID
In-Reply-To: <1348544455-17656-10-git-send-email-computersforpeace@gmail.com>
References: <1348544455-17656-1-git-send-email-computersforpeace@gmail.com>
 <1348544455-17656-10-git-send-email-computersforpeace@gmail.com>
Message-ID: <201210050337.12011.marex@denx.de>

Dear Brian Norris,

> Datasheets for the following Samsung NAND parts (both MLC and SLC) describe
> extensions to the Samsung 6-byte extended ID decoding table:
[...]

This breaks my board with K9F2G08 part:

[    0.860000] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 
256MiB 3,3V 8-bit), page size: 2048, OOB size: 64


> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 7e93d0d..bcb58ce 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2939,19 +2939,18 @@ static void nand_decode_ext_id(struct mtd_info
> *mtd, struct nand_chip *chip, /*
>  	 * Field definitions are in the following datasheets:
>  	 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
> -	 * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
> +	 * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
>  	 * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>  	 *
>  	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
>  	 * to do.
>  	 */
> -	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
> -			(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
> +	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
[...]

I believe the above hunk is wrong, reverting it fixes the problem.

Best regards,
Marek Vasut


From marex at denx.de  Thu Oct  4 21:45:49 2012
From: marex at denx.de (Marek Vasut)
Date: Fri, 5 Oct 2012 03:45:49 +0200
Subject: GPMI NAND crashes with UBIFS
Message-ID: <201210050345.49507.marex@denx.de>

Hello guys,

I tried integck from mtd-utils 1.5.0 on GPMI NAND driver since I suspect it 
still has issues with UBI. See the outcome for yourself, log attached. Any 
suggestions would be very appreciated.

:~/mtd-utils-1.5.0/tests/fs-tests/integrity# ./integck /media
integck: pid 492, testing "ubifs" at "/media/cf"[  203.450000] UBIFS warning 
(pid 492): power_cut_emulated: failing after 19403ms

[  203.450000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 4:0 (the buffer was corrupted)
[  203.470000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 8:2048 (the buffer was corrupted)
[  203.480000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 1:4096 (the buffer was corrupted)
[  203.490000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 2:4096 (the buffer was corrupted)
[  203.510000] UBIFS: un-mount UBI device 0, volume 0
[  203.520000] UBIFS: background thread "ubifs_bgt0_0" stops
[  203.520000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 1:6144 (the buffer was corrupted)
[  203.530000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 2:6144 (the buffer was corrupted)
[  203.560000] UBIFS: background thread "ubifs_bgt0_0" started, PID 494
[  203.650000] UBIFS warning (pid 492): power_cut_emulated: failing in master 
LEB 1
[  203.660000] UBIFS warning (pid 492): power_cut_emulated: ========== Power cut 
emulated ==========
[  203.670000] [<8001315c>] (unwind_backtrace+0x0/0xf0) from [<801c96c4>] 
(power_cut_emulated+0x300/0x65c)
[  203.680000] [<801c96c4>] (power_cut_emulated+0x300/0x65c) from [<801ce924>] 
(dbg_leb_write+0x40/0x1b0)
[  203.690000] [<801ce924>] (dbg_leb_write+0x40/0x1b0) from [<801a9314>] 
(ubifs_leb_write+0x58/0x130)
[  203.700000] [<801a9314>] (ubifs_leb_write+0x58/0x130) from [<801aac44>] 
(ubifs_write_node+0xc4/0x1b4)
[  203.710000] [<801aac44>] (ubifs_write_node+0xc4/0x1b4) from [<801b0a9c>] 
(ubifs_write_master+0x104/0x18c)
[  203.720000] [<801b0a9c>] (ubifs_write_master+0x104/0x18c) from [<801a6d9c>] 
(ubifs_mount+0x10e0/0x16f4)
[  203.730000] [<801a6d9c>] (ubifs_mount+0x10e0/0x16f4) from [<800a0e8c>] 
(mount_fs+0x14/0xd0)
[  203.740000] [<800a0e8c>] (mount_fs+0x14/0xd0) from [<800b9528>] 
(vfs_kern_mount+0x4c/0xc0)
[  203.750000] [<800b9528>] (vfs_kern_mount+0x4c/0xc0) from [<800b95f0>] 
(do_kern_mount+0x34/0xd0)
[  203.750000] [<800b95f0>] (do_kern_mount+0x34/0xd0) from [<800ba6f4>] 
(do_mount+0x118/0x710)
[  203.760000] [<800ba6f4>] (do_mount+0x118/0x710) from [<800bad70>] 
(sys_mount+0x84/0xc4)
[  203.770000] [<800bad70>] (sys_mount+0x84/0xc4) from [<8000eba0>] 
(ret_fast_syscall+0x0/0x2c)
[  203.780000] UBIFS warning (pid 492): corrupt_data: filled bytes 262-2047 with 
random data
[  203.790000] UBIFS warning (pid 492): dbg_leb_write: actually write 2048 bytes 
to LEB 1:8192 (the buffer was corrupted)
[  203.800000] UBIFS error (pid 492): ubifs_leb_write: writing 2048 bytes to LEB 
1:8192 failed, error -30
[  203.810000] UBIFS warning (pid 492): ubifs_ro_mode: switched to read-only 
mode, error -30
[  203.820000] [<8001315c>] (unwind_backtrace+0x0/0xf0) from [<801a93d4>] 
(ubifs_leb_write+0x118/0x130)
[  203.830000] [<801a93d4>] (ubifs_leb_write+0x118/0x130) from [<801aac44>] 
(ubifs_write_node+0xc4/0x1b4)
[  203.840000] [<801aac44>] (ubifs_write_node+0xc4/0x1b4) from [<801b0a9c>] 
(ubifs_write_master+0x104/0x18c)
[  203.850000] [<801b0a9c>] (ubifs_write_master+0x104/0x18c) from [<801a6d9c>] 
(ubifs_mount+0x10e0/0x16f4)
[  203.870000] [<801a6d9c>] (ubifs_mount+0x10e0/0x16f4) from [<800a0e8c>] 
(mount_fs+0x14/0xd0)
[  203.870000] [<800a0e8c>] (mount_fs+0x14/0xd0) from [<800b9528>] 
(vfs_kern_mount+0x4c/0xc0)
[  203.880000] [<800b9528>] (vfs_kern_mount+0x4c/0xc0) from [<800b95f0>] 
(do_kern_mount+0x34/0xd0)
[  203.890000] [<800b95f0>] (do_kern_mount+0x34/0xd0) from [<800ba6f4>] 
(do_mount+0x118/0x710)
[  203.900000] [<800ba6f4>] (do_mount+0x118/0x710) from [<800bad70>] 
(sys_mount+0x84/0xc4)
[  203.910000] [<800bad70>] (sys_mount+0x84/0xc4) from [<8000eba0>] 
(ret_fast_syscall+0x0/0x2c)
[  203.920000] [<8001315c>] (unwind_backtrace+0x0/0xf0) from [<801a93d8>] 
(ubifs_leb_write+0x11c/0x130)
[  203.930000] [<801a93d8>] (ubifs_leb_write+0x11c/0x130) from [<801aac44>] 
(ubifs_write_node+0xc4/0x1b4)
[  203.940000] [<801aac44>] (ubifs_write_node+0xc4/0x1b4) from [<801b0a9c>] 
(ubifs_write_master+0x104/0x18c)
[  203.950000] [<801b0a9c>] (ubifs_write_master+0x104/0x18c) from [<801a6d9c>] 
(ubifs_mount+0x10e0/0x16f4)
[  203.960000] [<801a6d9c>] (ubifs_mount+0x10e0/0x16f4) from [<800a0e8c>] 
(mount_fs+0x14/0xd0)
[  203.970000] [<800a0e8c>] (mount_fs+0x14/0xd0) from [<800b9528>] 
(vfs_kern_mount+0x4c/0xc0)
[  203.980000] [<800b9528>] (vfs_kern_mount+0x4c/0xc0) from [<800b95f0>] 
(do_kern_mount+0x34/0xd0)
[  203.990000] [<800b95f0>] (do_kern_mount+0x34/0xd0) from [<800ba6f4>] 
(do_mount+0x118/0x710)
[  204.000000] [<800ba6f4>] (do_mount+0x118/0x710) from [<800bad70>] 
(sys_mount+0x84/0xc4)
[  204.010000] [<800bad70>] (sys_mount+0x84/0xc4) from [<8000eba0>] 
(ret_fast_syscall+0x0/0x2c)
[  204.020000]  magic          0x6101831
[  204.020000]  crc            0x970eb552
[  204.020000]  node_type      7 (master node)
[  204.030000]  group_type     0 (no node group)
[  204.030000]  sqnum          20
[  204.040000]  len            512
[  204.040000]  highest_inum   66
[  204.040000]  commit number  1
[  204.050000]  flags          0x3
[  204.050000]  log_lnum       4
[  204.050000]  root_lnum      13
[  204.050000]  root_offs      0
[  204.060000]  root_len       168
[  204.060000]  gc_lnum        12
[  204.060000]  ihead_lnum     13
[  204.070000]  ihead_offs     2048
[  204.070000]  index_size     168
[  204.070000]  lpt_lnum       8
[  204.080000]  lpt_offs       2124
[  204.080000]  nhead_lnum     8
[  204.080000]  nhead_offs     4096
[  204.090000]  ltab_lnum      8
[  204.090000]  ltab_offs      2048
[  204.090000]  lsave_lnum     0
[  204.100000]  lsave_offs     0
[  204.100000]  lscan_lnum     11
[  204.100000]  leb_cnt        1984
[  204.100000]  empty_lebs     1971
[  204.110000]  idx_lebs       1
[  204.110000]  total_free     250519552
[  204.110000]  total_dirty    3160
[  204.120000]  total_used     768
[  204.120000]  total_dead     0
[  204.120000]  total_dark     12115968
[  204.140000] UBIFS: background thread "ubifs_bgt0_0" stops
integck: unmounted /media/cf, but cannot mount it back R/W (line 3200, error 30 
(Read-only file system))
integck: error!: condition '!__err' failed in recover_tested_fs() at 
integck.c:3200
integck: error 30 (Read-only file system)

Best regards,
Marek Vasut


From dan.carpenter at oracle.com  Fri Oct  5 02:57:04 2012
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 5 Oct 2012 09:57:04 +0300
Subject: [bug reportish] UBI_MAX_ERASECOUNTER not used consistently
Message-ID: <20121005065704.GA26466@elgon.mountain>

Hi Artem,

I normally audit for underflows and I had a question about this code.

mtd/ubi/attach.c
   665  static int early_erase_peb(struct ubi_device *ubi,
   666                             const struct ubi_attach_info *ai, int pnum, int ec)
   667  {
   668          int err;
   669          struct ubi_ec_hdr *ec_hdr;
   670  
   671          if ((long long)ec >= UBI_MAX_ERASECOUNTER) {

Casting to long long doesn't serve any purpose.  We normally say that
"> UBI_MAX_ERASECOUNTER" is invalid but "== UBI_MAX_ERASECOUNTER" is Ok.
The "ec" variable is signed and negative values are missed on this
check.

   672                  /*
   673                   * Erase counter overflow. Upgrade UBI and use 64-bit
   674                   * erase counters internally.
   675                   */
   676                  ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec);
   677                  return -EINVAL;
   678          }
   679  
   680          ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);

regards,
dan carpenter


From jlu at pengutronix.de  Fri Oct  5 03:50:05 2012
From: jlu at pengutronix.de (Jan =?ISO-8859-1?Q?L=FCbbe?=)
Date: Fri, 05 Oct 2012 09:50:05 +0200
Subject: [PATCH] mtd: m25p80: Add support for Numonyx N25Q128
In-Reply-To: <1349372416-16925-1-git-send-email-monstr@monstr.eu>
References: <1349372416-16925-1-git-send-email-monstr@monstr.eu>
Message-ID: <1349423405.3427.3.camel@coredoba.hi.pengutronix.de>

On Thu, 2012-10-04 at 19:40 +0200, Michal Simek wrote:
> From: Wendy Liang <wendy.liang at petalogix.com>
> 
> Add the id and sector mappings for SPI flash chips.

An equivalent patch is already in David Woodhouse's l2-mtd tree:
http://git.infradead.org/users/dedekind/l2-mtd.git/commitdiff/3105875f6b8902628caee2fd7821af43707c6bde

Regards,
Jan
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



From dedekind1 at gmail.com  Fri Oct  5 04:48:26 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 05 Oct 2012 11:48:26 +0300
Subject: Problem with verify-ing patch (error: arch/m68k/Kconfig.cpu:
 patch does not apply)
In-Reply-To: <1348574785.20474.15.camel@sauron.fi.intel.com>
References: <CACna6rwju0g+sq+vBAfCqFJm=EBLg79G2XoGEKs5n1Y=PcmKBg@mail.gmail.com>
 <1348499094.4880.65.camel@sauron.fi.intel.com>
 <CACna6ryu06qsgX99kdkeDaB+XJv4XwC0-O+5ysNFa1iOMEgNow@mail.gmail.com>
 <1348574785.20474.15.camel@sauron.fi.intel.com>
Message-ID: <1349426906.20373.77.camel@sauron.fi.intel.com>

On Tue, 2012-09-25 at 15:06 +0300, Artem Bityutskiy wrote:
> I'll do the fixes as soon as I have some time, please, keep bugging me
> and thanks for your feed-back!

I've just pushed a change which should improve user-friendliness. Now I
check for dependencies in many places and try to inform the user if a
program is missing, plus give some suggestions where to take it from.
E.g., for cross-tools I print the URL where one can download pre-built
cross-tools.

Thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121005/bd978401/attachment.sig>

From avinashphilip at ti.com  Fri Oct  5 04:51:50 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Fri, 5 Oct 2012 08:51:50 +0000
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com> 
Message-ID: <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>

On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
> On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
> > On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
> > > ELM module can be used for error correction of BCH 4 & 8 bit. Also
> > > support read & write page in one shot by adding custom read_page &
> > > write_page methods. This helps in optimizing code.
> > > 
> > > New structure member "is_elm_used" is added to know the status of
> > > whether the ELM module is used for error correction or not.
> > > 
> > > Note:
> > > ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
> > > with RBL ECC layout, even though the requirement was only 13 byte. This
> > > results a common ecc layout across RBL, U-boot & Linux.
> > > 
> > 
> > See a few comments below,
> > 
> > (...)
> > > +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
> > > +                               u_char *read_ecc, u_char *calc_ecc)
> > > +{
> > > +       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> > > +                       mtd);
> > > +       int eccsteps = info->nand.ecc.steps;
> > > +       int i , j, stat = 0;
> > > +       int eccsize, eccflag, size;
> > > +       struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
> > > +       u_char *ecc_vec = calc_ecc;
> > > +       enum bch_ecc type;
> > > +       bool is_error_reported = false;
> > > +
> > > +       /* initialize elm error vector to zero */
> > > +       memset(err_vec, 0, sizeof(err_vec));
> > > +       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
> > > +               size = BCH8_SIZE;
> > > +               eccsize = BCH8_ECC_OOB_BYTES;
> > > +               type = BCH8_ECC;
> > > +       } else {
> > > +               size = BCH4_SIZE;
> > > +               eccsize = BCH4_SIZE;
> > > +               type = BCH4_ECC;
> > > +       }
> > > +
> > > +       for (i = 0; i < eccsteps ; i++) {
> > > +               eccflag = 0;    /* initialize eccflag */
> > > +
> > > +               for (j = 0; (j < eccsize); j++) {
> > > +                       if (read_ecc[j] != 0xFF) {
> > > +                               eccflag = 1;    /* data area is flashed */
> > 
> > Just a reminder: this way of checking if a page has been programmed is not robust to bitflips,
> > so you may get into trouble with UBIFS on a fairly recent device.

Sorry I missed this point.

Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) is 0xFF. If all data
in spare area is 0xFF, conclude that the page is erased & no need of error correction. In case
of bit flip present in spare area, page will be reported as uncorrectable.
But I am not understand understand " trouble with UBIFS on a fairly recent device".
Can you little elaborativ

Thanks
Avinash 



From Thomas.Betker at rohde-schwarz.com  Fri Oct  5 05:17:22 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Fri, 5 Oct 2012 11:17:22 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
 <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
 <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>
 <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>
Message-ID: <OF860E68DA.97A53995-ONC1257A8E.003297E0-C1257A8E.003308E2@rohde-schwarz.com>

Hello Joakim:

> I think your patch will work, but I don't like having 2 call sites
> to grab_cache_page_write_begin(mapping, index, flags) so I came
> up with this instead(untested as well):

The tests I ran this night were successful. I have adapted my patch 
according to your suggestions and started re-testing; I won't be able to 
finish today, though, so I will post the final patch on Monday (assuming 
that it works).

Have a nice weekend,
Thomas


From joakim.tjernlund at transmode.se  Fri Oct  5 05:21:52 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Fri, 5 Oct 2012 11:21:52 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OF860E68DA.97A53995-ONC1257A8E.003297E0-C1257A8E.003308E2@rohde-schwarz.com>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
 <OF52EBAA51.F623F8FB-ONC1257A8B.005B88EA-C1257A8B.005BD53C@transmode.se>
 <OFF2FAA55C.4813D4C0-ONC1257A8B.0060F9EA-C1257A8B.00634CA4@transmode.se>
 <OF930A0EE5.DA214D86-ONC1257A8B.00673BC9-C1257A8B.0067E92C@transmode.se>
 <OFD47DAD5E.85DB9677-ONC1257A8D.003FBACE-C1257A8D.004EC32A@rohde-schwarz.com>
 <OF422CEB2B.7CB3BECB-ONC1257A8D.0058F723-C1257A8D.00595592@transmode.se>
 <OF7B7B7723.82703A82-ONC1257A8D.005A1DFC-C1257A8D.005CA7D7@rohde-schwarz.com>
 <OFB615AF11.05DABF7D-ONC1257A8D.00661C69-C1257A8D.0066832C@transmode.se>
 <OF860E68DA.97A53995-ONC1257A8E.003297E0-C1257A8E.003308E2@rohde-schwarz.com>
Message-ID: <OF4EE2658D.D4054C9C-ONC1257A8E.0033523C-C1257A8E.003370D7@transmode.se>

Thomas.Betker at rohde-schwarz.com wrote on 2012/10/05 11:17:22:
>
> Hello Joakim:
>
> > I think your patch will work, but I don't like having 2 call sites
> > to grab_cache_page_write_begin(mapping, index, flags) so I came
> > up with this instead(untested as well):
>
> The tests I ran this night were successful. I have adapted my patch
> according to your suggestions and started re-testing; I won't be able to
> finish today, though, so I will post the final patch on Monday (assuming
> that it works).

I was just about to sent the final version. There was an bug in the
error patch. Hang in and a proper patch will come shortly.

 Jocke



From Joakim.Tjernlund at transmode.se  Fri Oct  5 05:24:24 2012
From: Joakim.Tjernlund at transmode.se (Joakim Tjernlund)
Date: Fri, 5 Oct 2012 11:24:24 +0200
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
Message-ID: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>

Thomas.Betker at rohde-schwarz.com reports:

The target system is an SoC with a dual ARMv7 (Cortex-A9), and we are
running the long-term 3.4.11 kernel (whose fs/jffs2/ seems to be pretty
close to the latest mainline kernel). The deadlock occurred when using scp
to copy files from a host system to the target system.

The GC thread hangs in lock_page(page), the write thread hangs in the
first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:

jffs2_garbage_collect_live
    mutex_lock(&f->sem)                         (A)
    jffs2_garbage_collect_dnode [inlined]
        jffs2_gc_fetch_page
            read_cache_page_async
                do_read_cache_page
                    lock_page(page) [inlined]
                        __lock_page             (B) ***

jffs2_write_begin
    grab_cache_page_write_begin
        find_lock_page
            lock_page(page)                     (B)
    mutex_lock(&f->sem)                         (A) ***

I have manually analyzed the stacks and confirmed that both threads sit on
the theme 'struct page'.

Fix this by restructuring jffs2_write_begin to take the f->sem lock
before the page lock. However one must make sure not to hold f->sem
when calling jffs2_reserve_space according to README.Locking

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
---

 This needs to be review by someone that understands the
 looking rules better. David?

 fs/jffs2/file.c |   41 +++++++++++++++++++++--------------------
 1 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index db3889b..23adcdc 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -140,31 +140,35 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
-	int ret = 0;
+	int ret = -ENOMEM;
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_raw_inode ri;
+	uint32_t alloc_len;
 
+	if (pageofs > inode->i_size) {
+		/* reserve space must be be before locking f->sem */
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			return ret;
+	}
+
+	mutex_lock(&f->sem);
 	pg = grab_cache_page_write_begin(mapping, index, flags);
 	if (!pg)
-		return -ENOMEM;
+		goto out_unlock;
+
 	*pagep = pg;
 
 	jffs2_dbg(1, "%s()\n", __func__);
 
-	if (pageofs > inode->i_size) {
+	if (!ret) { /* reserve_space succeded */
 		/* Make new hole frag from old EOF to new page */
-		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
-		uint32_t alloc_len;
 
 		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs);
 
-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			goto out_page;
-
-		mutex_lock(&f->sem);
 		memset(&ri, 0, sizeof(ri));
 
 		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -190,8 +194,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 
 		if (IS_ERR(fn)) {
 			ret = PTR_ERR(fn);
-			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -205,13 +207,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 				  ret);
 			jffs2_mark_node_obsolete(c, fn->raw);
 			jffs2_free_full_dnode(fn);
-			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		jffs2_complete_reservation(c);
 		inode->i_size = pageofs;
-		mutex_unlock(&f->sem);
 	}
 
 	/*
@@ -220,18 +219,20 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 	 * case of a short-copy.
 	 */
 	if (!PageUptodate(pg)) {
-		mutex_lock(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
-		mutex_unlock(&f->sem);
 		if (ret)
 			goto out_page;
 	}
+	mutex_unlock(&f->sem);
 	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
-	return ret;
+	return 0;
 
 out_page:
 	unlock_page(pg);
 	page_cache_release(pg);
+out_unlock:
+	jffs2_complete_reservation(c);
+	mutex_unlock(&f->sem);
 	return ret;
 }
 
-- 
1.7.8.6



From stigge at antcom.de  Fri Oct  5 05:30:28 2012
From: stigge at antcom.de (Roland Stigge)
Date: Fri, 05 Oct 2012 11:30:28 +0200
Subject: Pull request for mainline
Message-ID: <506EA8B4.6050309@antcom.de>

Hi,

just small reminder, just in case: Now would be a good opportunity for a
pull request for mtd to mainline, if not already done. ;-)

Thanks,

Roland


From dedekind1 at gmail.com  Fri Oct  5 05:32:39 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 05 Oct 2012 12:32:39 +0300
Subject: [PATCH] mtd: onenand: Make flexonenand_set_boundary static
In-Reply-To: <1348294351-27182-1-git-send-email-sachin.kamat@linaro.org>
References: <1348294351-27182-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1349429559.20373.78.camel@sauron.fi.intel.com>

On Sat, 2012-09-22 at 11:42 +0530, Sachin Kamat wrote:
> Fixes the following sparse warning:
> drivers/mtd/onenand/onenand_base.c:3697:5: warning:
> symbol 'flexonenand_set_boundary' was not declared. Should it be static?
> 
> Cc: Kyungmin Park <kyungmin.park at samsung.com>
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121005/8fa4eba4/attachment.sig>

From monstr at monstr.eu  Fri Oct  5 05:58:04 2012
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 05 Oct 2012 11:58:04 +0200
Subject: [PATCH] mtd: m25p80: Add support for Numonyx N25Q128
In-Reply-To: <1349423405.3427.3.camel@coredoba.hi.pengutronix.de>
References: <1349372416-16925-1-git-send-email-monstr@monstr.eu>
 <1349423405.3427.3.camel@coredoba.hi.pengutronix.de>
Message-ID: <506EAF2C.7070604@monstr.eu>

On 10/05/2012 09:50 AM, Jan L?bbe wrote:
> On Thu, 2012-10-04 at 19:40 +0200, Michal Simek wrote:
>> From: Wendy Liang <wendy.liang at petalogix.com>
>>
>> Add the id and sector mappings for SPI flash chips.
>
> An equivalent patch is already in David Woodhouse's l2-mtd tree:
> http://git.infradead.org/users/dedekind/l2-mtd.git/commitdiff/3105875f6b8902628caee2fd7821af43707c6bde

Great thanks.
Michal


-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian


From dedekind1 at gmail.com  Fri Oct  5 06:17:04 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 05 Oct 2012 13:17:04 +0300
Subject: [PATCH 1/8] mtd_tests: Refactor duplicate code
In-Reply-To: <506AF9F0.7010903@gmail.com>
References: <506AF985.30104@gmail.com> <506AF9F0.7010903@gmail.com>
Message-ID: <1349432224.20373.80.camel@sauron.fi.intel.com>

On Tue, 2012-10-02 at 19:58 +0530, Vikram Narayanan wrote:
> Move the duplicate code from all the tests to a common header.
> 
> Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>

Could you please re-structure your patches so that you first do the
'pr_' changes, and then this one. Because 'pr_' are trivial and I can
apply them right away.

This one - I think if you look at UBI and JFFS2 - you may find them also
use the same pattern, and you can actually make this function go to
mtdcore.c and be exported instead.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121005/cff54ad1/attachment.sig>

From dedekind1 at gmail.com  Fri Oct  5 08:06:43 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 05 Oct 2012 15:06:43 +0300
Subject: UBIFS back-ports update
Message-ID: <1349438803.20373.91.camel@sauron.fi.intel.com>

Hi UBI/UBIFS users,

FYI, I've stopped maintaining pre 3.0 UBI/UBIFS back-port trees. I won't
remove them, but won't maintain either. If someone wants to do that,
feel free to send patches/pull requests.

The supported back-port trees now are 3.0-3.6.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121005/ba681b29/attachment-0001.sig>

From linus.walleij at linaro.org  Fri Oct  5 08:49:44 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 5 Oct 2012 14:49:44 +0200
Subject: [PATCH 1/1] mtd: st fsmc_nand: pass the ale and cmd resource via
 resource
In-Reply-To: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
References: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <CACRpkdb10dfKR-sAvbUar+ZsC16uLofhBXuMxfL7QtXLhNg1+Q@mail.gmail.com>

On Thu, Oct 4, 2012 at 3:14 PM, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj at jcrosoft.com> wrote:

> Do not use the platform_data to pass resource and be smart in the drivers.
> Just pass it via resource
>
> Switch to devm_request_and_ioremap at the sametime
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Vipin Kumar <vipin.kumar at st.com>
> Cc: linux-mtd at lists.infradead.org

This is much better. Actually I was confused by these offsets recently...
Acked-by: Linus Walleij <linus.walleij at linaro.org>

My patch to convert the Nomadik to the FSMC driver will collide with this,
but I can sure fix it up as we run into it, no big deal.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Fri Oct  5 08:52:06 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 5 Oct 2012 14:52:06 +0200
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
References: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <CACRpkdYMz05DwtLtHkggvo8VFOtvPLpovwq6fLceeiFK0Wci0Q@mail.gmail.com>

On Thu, Oct 4, 2012 at 9:28 AM, Linus Walleij <linus.walleij at linaro.org> wrote:

> The Nomadik NAND driver is really just a subset of the existing
> FSMC driver, so let's switch over to using that driver instead,
> since it handles more variants of this chip. The callbacks for
> setting up the chip is doing stuff now handled by the FSMC
> driver.
>
> Cc: Alessandro Rubini <rubini at unipv.it>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> I'm requesting Mike Turquette's ACK on this patch so I can merge
> it through ARM SoC.

Still requesting Mike's ACK, but not for merging through ARM SoC
but through MTD.

If you apply Jean-Christophe's patch first (please do that) I will
send a v2 of this patch set to be applied onto MTD as well
(should be OK).

Yours,
Linus Walleij


From rubini at unipv.it  Fri Oct  5 08:58:21 2012
From: rubini at unipv.it (Alessandro Rubini)
Date: Fri, 5 Oct 2012 14:58:21 +0200
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <CACRpkdYMz05DwtLtHkggvo8VFOtvPLpovwq6fLceeiFK0Wci0Q@mail.gmail.com>
References: <CACRpkdYMz05DwtLtHkggvo8VFOtvPLpovwq6fLceeiFK0Wci0Q@mail.gmail.com>
 <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20121005125821.GA7937@mail.gnudd.com>

>> The Nomadik NAND driver is really just a subset of the existing
>> FSMC driver,
>>
>> Cc: Alessandro Rubini <rubini at unipv.it>

> Still requesting Mike's ACK, but not for merging through ARM SoC
> but through MTD.

Oh, and please get mine too. Sorry for not noticing the message, busy
times...

I'm pretty sure there was no fsmc driver back then. But clearly
something coming from the vendor and used on several boards is better
then something made by an external consultant for a specific
evaluation board. So ok to ditch my nand driver.

Acked-by: Alessandro Rubini <rubini at unipv.it>



From plagnioj at jcrosoft.com  Fri Oct  5 10:20:04 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 5 Oct 2012 16:20:04 +0200
Subject: [PATCH 1/1] mtd: st fsmc_nand: pass the ale and cmd resource
 via resource
In-Reply-To: <CACRpkdb10dfKR-sAvbUar+ZsC16uLofhBXuMxfL7QtXLhNg1+Q@mail.gmail.com>
References: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
 <CACRpkdb10dfKR-sAvbUar+ZsC16uLofhBXuMxfL7QtXLhNg1+Q@mail.gmail.com>
Message-ID: <20121005142004.GB12462@game.jcrosoft.org>

On 14:49 Fri 05 Oct     , Linus Walleij wrote:
> 
> On Thu, Oct 4, 2012 at 3:14 PM, Jean-Christophe PLAGNIOL-VILLARD
> <plagnioj at jcrosoft.com> wrote:
> 
> > Do not use the platform_data to pass resource and be smart in the drivers.
> > Just pass it via resource
> >
> > Switch to devm_request_and_ioremap at the sametime
> >
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> > Cc: Linus Walleij <linus.walleij at linaro.org>
> > Cc: Vipin Kumar <vipin.kumar at st.com>
> > Cc: linux-mtd at lists.infradead.org
> 
> This is much better. Actually I was confused by these offsets recently...
> Acked-by: Linus Walleij <linus.walleij at linaro.org>
> 
> My patch to convert the Nomadik to the FSMC driver will collide with this,
> but I can sure fix it up as we run into it, no big deal.
ha you did it too

I'll give it a try

Best Regards,
J.


From ivan.djelic at parrot.com  Fri Oct  5 10:23:38 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Fri, 5 Oct 2012 16:23:38 +0200
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
Message-ID: <20121005142338.GA7199@parrot.com>

On Fri, Oct 05, 2012 at 09:51:50AM +0100, Philip, Avinash wrote:
> On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
> > On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
> > > On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
> > > > ELM module can be used for error correction of BCH 4 & 8 bit. Also
> > > > support read & write page in one shot by adding custom read_page &
> > > > write_page methods. This helps in optimizing code.
> > > > 
> > > > New structure member "is_elm_used" is added to know the status of
> > > > whether the ELM module is used for error correction or not.
> > > > 
> > > > Note:
> > > > ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
> > > > with RBL ECC layout, even though the requirement was only 13 byte. This
> > > > results a common ecc layout across RBL, U-boot & Linux.
> > > > 
> > > 
> > > See a few comments below,
> > > 
> > > (...)
> > > > +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
> > > > +                               u_char *read_ecc, u_char *calc_ecc)
> > > > +{
> > > > +       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> > > > +                       mtd);
> > > > +       int eccsteps = info->nand.ecc.steps;
> > > > +       int i , j, stat = 0;
> > > > +       int eccsize, eccflag, size;
> > > > +       struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
> > > > +       u_char *ecc_vec = calc_ecc;
> > > > +       enum bch_ecc type;
> > > > +       bool is_error_reported = false;
> > > > +
> > > > +       /* initialize elm error vector to zero */
> > > > +       memset(err_vec, 0, sizeof(err_vec));
> > > > +       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
> > > > +               size = BCH8_SIZE;
> > > > +               eccsize = BCH8_ECC_OOB_BYTES;
> > > > +               type = BCH8_ECC;
> > > > +       } else {
> > > > +               size = BCH4_SIZE;
> > > > +               eccsize = BCH4_SIZE;
> > > > +               type = BCH4_ECC;
> > > > +       }
> > > > +
> > > > +       for (i = 0; i < eccsteps ; i++) {
> > > > +               eccflag = 0;    /* initialize eccflag */
> > > > +
> > > > +               for (j = 0; (j < eccsize); j++) {
> > > > +                       if (read_ecc[j] != 0xFF) {
> > > > +                               eccflag = 1;    /* data area is flashed */
> > > 
> > > Just a reminder: this way of checking if a page has been programmed is not robust to bitflips,
> > > so you may get into trouble with UBIFS on a fairly recent device.
> 
> Sorry I missed this point.
> 
> Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) is 0xFF. If all data
> in spare area is 0xFF, conclude that the page is erased & no need of error correction. In case
> of bit flip present in spare area, page will be reported as uncorrectable.
> But I am not understand understand " trouble with UBIFS on a fairly recent device".
> Can you little elaborativ

There are at least 2 potential problems when reading an erased page with bitflips:

1. bitflip in data area and no bitflip in spare area (all 0xff)
Your code will not perform any ECC correction.
UBIFS does not like finding bitflips in empty pages, see for instance
http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.

2. bitflip in ECC bytes in spare area
Your code will report an uncorrectable error upon reading; if this happens while reading a partially programmed UBI block,
I guess you will lose data.

BR,
--
Ivan


From gcembed at gmail.com  Fri Oct  5 11:34:02 2012
From: gcembed at gmail.com (=?UTF-8?B?R2HDq3RhbiBDYXJsaWVy?=)
Date: Fri, 05 Oct 2012 17:34:02 +0200
Subject: mxc-nand + jffs2 : dir ino #9041 appears to be a hard link
Message-ID: <506EFDEA.7050305@gmail.com>

Hello,
I am working with iMX27 (3DS) with NAND support (and bbiswap patch : 
mxc_nand : allow swapping the Bad block Indicator for NFC v1).

Here is errors that I have sometimes after updating a lot of of files.
Everything is working good until I power off the board (before that I 
start that reboot script that sync and umount all filesystems and 
remount / as ro (sync is also run before remount) before reboot.
While this update, there is several "ln -sf" because busybox must be 
updated.

Sometimes it works and sometimes filesystem gets corrupted and gives me 
following kind of errors :
jffs2: error: (1) jffs2_build_inode_pass1: child dir "share" (ino #9044) 
of dir ino #9041 appears to be a hard link


jffs2: warning: (1022) jffs2_get_inode_nodes: Eep. No valid nodes for 
ino #9044.
jffs2: warning: (1022) jffs2_do_read_inode_internal: no data nodes found 
for ino #9044

This never occurs with kernel 2.6.22 from Freescale but with kernel 
3.4.4, it occurs.
I am going to compile kernel 3.4.12 but I don't see anything in commits 
about this problem.

Does anyone have an idea where the problem is ?
Thanks for your help.
Best regards,
Ga?tan Carlier.


From afzal at ti.com  Fri Oct  5 11:52:50 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:22:50 +0530
Subject: [PATCH 00/15] OMAP-GPMC related cleanup for common zImage
Message-ID: <cover.1349450454.git.afzal@ti.com>

Hi,

This series cleans up omap-gpmc related code so that omap can
be a part of common zImage.

This series moves gpmc.h from plat-omap/include/plat to mach-omap2
so that header file is local.

Patches 1-4 qualifies as -rc material (assuming pull request
containing basic gpmc driver is accepted by Linus).

Patch 1 is an already posted one, has been pulled into this series.

Patches 5-6 removes necessity of cpu.h from onenand driver based
on Tony's suggestion.

Patches 7 & 8 cleans up the already moved platform data header files
to contain only platform data. Also gpmc-nand information is moved
to nand platform data header.

Patches 9-14 makes nand driver independent of gpmc header file

And the final patch localizes gpmc header.

This has been tested on omap3evm.

This series is available
        @ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-czimage-v1
and is based on
        linux-next (next-20121005)
and is dependent on
	http://marc.info/?l=linux-omap&m=134945131602622&w=2

Regards
Afzal


Afzal Mohammed (15):
  ARM: OMAP2+: gpmc: annotate exit sections properly
  mtd: onenand: omap: cleanup gpmc dependency
  mtd: nand: omap: free region as per resource size
  mtd: nand: omap: read nand using register address
  ARM: OMAP2+: onenand: connected soc info in pdata
  mtd: onenand: omap: use pdata info instead of cpu_is
  ARM: OMAP2+: onenand: header cleanup
  ARM: OMAP2+: nand: header cleanup
  mtd: nand: omap: bring in gpmc nand macros
  ARM: OMAP2+: nand: bch capability check
  ARM: OMAP2+: gpmc: nand register helper bch update
  mtd: nand: omap: handle gpmc bch[48]
  ARM: OMAP2+: gpmc: remove exported nand functions
  mtd: nand: omap: gpmc header removal
  ARM: OMAP2+: gpmc: localize gpmc header

 arch/arm/mach-omap2/board-2430sdp.c                |   2 +-
 arch/arm/mach-omap2/board-3430sdp.c                |   2 +-
 arch/arm/mach-omap2/board-apollon.c                |   2 +-
 arch/arm/mach-omap2/board-cm-t35.c                 |   5 +-
 arch/arm/mach-omap2/board-cm-t3517.c               |   5 +-
 arch/arm/mach-omap2/board-devkit8000.c             |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   7 +-
 arch/arm/mach-omap2/board-flash.h                  |   2 +-
 arch/arm/mach-omap2/board-h4.c                     |   2 +-
 arch/arm/mach-omap2/board-igep0020.c               |   3 +-
 arch/arm/mach-omap2/board-ldp.c                    |   2 +-
 arch/arm/mach-omap2/board-n8x0.c                   |   1 +
 arch/arm/mach-omap2/board-omap3beagle.c            |   2 +-
 arch/arm/mach-omap2/board-omap3logic.c             |   2 +-
 arch/arm/mach-omap2/board-omap3pandora.c           |   3 +-
 arch/arm/mach-omap2/board-omap3stalker.c           |   2 +-
 arch/arm/mach-omap2/board-omap3touchbook.c         |   2 +-
 arch/arm/mach-omap2/board-overo.c                  |   2 +-
 arch/arm/mach-omap2/board-rm680.c                  |   3 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c       |   3 +-
 arch/arm/mach-omap2/board-rx51.c                   |   2 +-
 arch/arm/mach-omap2/board-zoom-debugboard.c        |   2 +-
 arch/arm/mach-omap2/common-board-devices.c         |   1 -
 arch/arm/mach-omap2/gpmc-nand.c                    |  81 ++--
 arch/arm/mach-omap2/gpmc-nand.h                    |  27 ++
 arch/arm/mach-omap2/gpmc-onenand.c                 |   9 +-
 arch/arm/mach-omap2/gpmc-onenand.h                 |  24 ++
 arch/arm/mach-omap2/gpmc-smc91x.c                  |   2 +-
 arch/arm/mach-omap2/gpmc-smsc911x.c                |   2 +-
 arch/arm/mach-omap2/gpmc.c                         | 459 +--------------------
 .../{plat-omap/include/plat => mach-omap2}/gpmc.h  |  59 +--
 arch/arm/mach-omap2/pm34xx.c                       |   2 +-
 arch/arm/mach-omap2/usb-tusb6010.c                 |   2 +-
 drivers/mtd/nand/omap2.c                           | 121 +++++-
 drivers/mtd/onenand/omap2.c                        |   9 +-
 include/linux/platform_data/mtd-nand-omap2.h       |  46 ++-
 include/linux/platform_data/mtd-onenand-omap2.h    |  20 +-
 37 files changed, 317 insertions(+), 605 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-nand.h
 create mode 100644 arch/arm/mach-omap2/gpmc-onenand.h
 rename arch/arm/{plat-omap/include/plat => mach-omap2}/gpmc.h (70%)

-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:53:20 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:23:20 +0530
Subject: [PATCH 01/15] ARM: OMAP2+: gpmc: annotate exit sections properly
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <a517afd9ed3be069b475caae791156b9c4663849.1349450454.git.afzal@ti.com>

compiler complained,
`gpmc_remove' referenced in section `.data' of arch/arm/mach-omap2/built-in.o: defined in discarded section `.exit.text' of arch/arm/mach-omap2/built-in.o

Annotate gpmc_remove function and dependents with __devexit.

Reported-by: Tony Lindgren <tony at atomide.com>
Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 2cbdcb9..163458d 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -886,7 +886,7 @@ static int gpmc_setup_irq(void)
 	return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
 }
 
-static __exit int gpmc_free_irq(void)
+static __devexit int gpmc_free_irq(void)
 {
 	int i;
 
@@ -992,7 +992,7 @@ static __devinit int gpmc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static __exit int gpmc_remove(struct platform_device *pdev)
+static __devexit int gpmc_remove(struct platform_device *pdev)
 {
 	gpmc_free_irq();
 	gpmc_mem_exit();
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:53:29 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:23:29 +0530
Subject: [PATCH 02/15] mtd: onenand: omap: cleanup gpmc dependency
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <77643c064b9d0d639f75f793130bb40768b015e1.1349450454.git.afzal@ti.com>

requesting, freeing gpmc cs is now handled fully
by gpmc, remove left out gpmc dependency as well
as unnecessary include of gpmc.h

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/onenand/omap2.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 1961be9..d7ef2c9 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -38,7 +38,6 @@
 #include <linux/regulator/consumer.h>
 
 #include <asm/mach/flash.h>
-#include <plat/gpmc.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 #include <asm/gpio.h>
 
@@ -803,7 +802,6 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
 	}
 	iounmap(c->onenand.base);
 	release_mem_region(c->phys_base, c->mem_size);
-	gpmc_cs_free(c->gpmc_cs);
 	kfree(c);
 
 	return 0;
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:53:35 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:23:35 +0530
Subject: [PATCH 03/15] mtd: nand: omap: free region as per resource size
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <011a0d90343de9204cfd977381b36cace032482b.1349450454.git.afzal@ti.com>

memory as is now obtained via resource, upon freeing use
resource size. This also helps get rid of one macro.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..4c33135 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1513,7 +1513,7 @@ static int omap_nand_remove(struct platform_device *pdev)
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
-	release_mem_region(info->phys_base, NAND_IO_SIZE);
+	release_mem_region(info->phys_base, info->mem_size);
 	kfree(info);
 	return 0;
 }
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:53:48 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:23:48 +0530
Subject: [PATCH 04/15] mtd: nand: omap: read nand using register address
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <571607de9b49c4d44a03e793a9b36654e5ff4570.1349450454.git.afzal@ti.com>

Now that gpmc-nand registers are available in driver, use it
to read nand data.

"65b97cf  mtd: nand: omap2: handle nand on gpmc" modified all
other instances. After initial versions of that patch, a new
change added reading nand data using gpmc exposed function.
In the final version this change was not taken care.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4c33135..abfc602 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -996,7 +996,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 		cond_resched();
 	}
 
-	status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA);
+	status = readb(info->reg.gpmc_nand_data);
 	return status;
 }
 
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:53:54 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:23:54 +0530
Subject: [PATCH 05/15] ARM: OMAP2+: onenand: connected soc info in pdata
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <6065bed749924f28a3d268145d1b7c980a3c97eb.1349450454.git.afzal@ti.com>

onenand driver needs to know whether soc is falling under
34xx family to properly handle onenand. But driver is not
supposed to do cpu_is_* check, hence educate platform data
with this information. Driver can make use of it to avoid
cpu_is_* check.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c              | 5 +++++
 include/linux/platform_data/mtd-onenand-omap2.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 544d501..f0b677a 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -409,6 +409,11 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
 		gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
 	}
 
+	if (cpu_is_omap34xx())
+		gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
+	else
+		gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
+
 	err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
 				(unsigned long *)&gpmc_onenand_resource.start);
 	if (err < 0) {
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
index 21bb0ff..ef9c60d 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -14,6 +14,7 @@
 
 #define ONENAND_SYNC_READ	(1 << 0)
 #define ONENAND_SYNC_READWRITE	(1 << 1)
+#define	ONENAND_IN_OMAP34XX	(1 << 2)
 
 struct omap_onenand_platform_data {
 	int			cs;
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:00 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:00 +0530
Subject: [PATCH 06/15] mtd: onenand: omap: use pdata info instead of cpu_is
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <860ba92c34cbb490beccd5442087087c1751a6a2.1349450454.git.afzal@ti.com>

platform data now contains a field to indicate whether
soc belongs to omap34xx family, use it instead of
cpu_is_* check.

This helps in removing dependency of platform specific
header file - cpu.h

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/onenand/omap2.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d7ef2c9..959f465 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -42,7 +42,6 @@
 #include <asm/gpio.h>
 
 #include <plat/dma.h>
-#include <plat/cpu.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -62,6 +61,7 @@ struct omap2_onenand {
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
 	struct regulator *regulator;
+	u8 flags;
 };
 
 static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
@@ -154,7 +154,7 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
 			syscfg |= ONENAND_SYS_CFG1_IOBE;
 			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
-			if (cpu_is_omap34xx())
+			if (c->flags & ONENAND_IN_OMAP34XX)
 				/* Add a delay to let GPIO settle */
 				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
 		}
@@ -638,6 +638,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
+	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
 	c->dma_channel = pdata->dma_channel;
@@ -728,7 +729,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
 	this = &c->onenand;
 	if (c->dma_channel >= 0) {
 		this->wait = omap2_onenand_wait;
-		if (cpu_is_omap34xx()) {
+		if (c->flags & ONENAND_IN_OMAP34XX) {
 			this->read_bufferram = omap3_onenand_read_bufferram;
 			this->write_bufferram = omap3_onenand_write_bufferram;
 		} else {
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:06 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:06 +0530
Subject: [PATCH 07/15] ARM: OMAP2+: onenand: header cleanup
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <4a5b5b27c74ef2a18dfcea7102104924812946b3.1349450454.git.afzal@ti.com>

For common arm zImage existing onenand header file
in platform specific location was moved to generic
platform data location, but it contained more than
platform data, remove it. New local header has been
created for exposing functions.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-flash.c               |  1 +
 arch/arm/mach-omap2/board-igep0020.c            |  1 +
 arch/arm/mach-omap2/board-n8x0.c                |  1 +
 arch/arm/mach-omap2/board-rm680.c               |  1 +
 arch/arm/mach-omap2/board-rx51-peripherals.c    |  1 +
 arch/arm/mach-omap2/gpmc-onenand.c              |  1 +
 arch/arm/mach-omap2/gpmc-onenand.h              | 24 ++++++++++++++++++++++++
 include/linux/platform_data/mtd-onenand-omap2.h | 19 +++----------------
 8 files changed, 33 insertions(+), 16 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-onenand.h

diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index f8b30cb..de68fdf 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -25,6 +25,7 @@
 
 #include "common.h"
 #include "board-flash.h"
+#include "gpmc-onenand.h"
 
 #define REG_FPGA_REV			0x10
 #define REG_FPGA_DIP_SWITCH_INPUT2	0x60
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index f6b3ed0..83c6efa 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -43,6 +43,7 @@
 #include "common-board-devices.h"
 #include "board-flash.h"
 #include "control.h"
+#include "gpmc-onenand.h"
 
 #define IGEP2_SMSC911X_CS       5
 #define IGEP2_SMSC911X_GPIO     176
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index d95f727..92b1916 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -32,6 +32,7 @@
 #include <plat/mmc.h>
 
 #include "mux.h"
+#include "gpmc-onenand.h"
 
 #define TUSB6010_ASYNC_CS	1
 #define TUSB6010_SYNC_CS	4
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 45997bf..154cf33 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -33,6 +33,7 @@
 #include "hsmmc.h"
 #include "sdram-nokia.h"
 #include "common-board-devices.h"
+#include "gpmc-onenand.h"
 
 static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ed85fb8..aa6a2a4 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -54,6 +54,7 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-onenand.h"
 
 #define SYSTEM_REV_B_USES_VAUX3	0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index f0b677a..29671cc 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -23,6 +23,7 @@
 #include <plat/gpmc.h>
 
 #include "soc.h"
+#include "gpmc-onenand.h"
 
 #define	ONENAND_IO_SIZE	SZ_128K
 
diff --git a/arch/arm/mach-omap2/gpmc-onenand.h b/arch/arm/mach-omap2/gpmc-onenand.h
new file mode 100644
index 0000000..216f23a
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.h
@@ -0,0 +1,24 @@
+/*
+ *  arch/arm/mach-omap2/gpmc-onenand.h
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef	__OMAP2_GPMC_ONENAND_H
+#define	__OMAP2_GPMC_ONENAND_H
+
+#include <linux/platform_data/mtd-onenand-omap2.h>
+
+#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
+extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+#else
+#define board_onenand_data	NULL
+static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+{
+}
+#endif
+
+#endif
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
index ef9c60d..685af7e 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -9,6 +9,9 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef	__MTD_ONENAND_OMAP2_H
+#define	__MTD_ONENAND_OMAP2_H
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
@@ -27,20 +30,4 @@ struct omap_onenand_platform_data {
 	u8			regulator_can_sleep;
 	u8			skip_initial_unlocking;
 };
-
-#define ONENAND_MAX_PARTITIONS 8
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
-
-extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
-
-#else
-
-#define board_onenand_data	NULL
-
-static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
-{
-}
-
 #endif
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:12 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:12 +0530
Subject: [PATCH 08/15] ARM: OMAP2+: nand: header cleanup
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <ea8ee1d422a11756c9ffdc62fe329bb69cf83408.1349450454.git.afzal@ti.com>

For common arm zImage existing onenand header file
in platform specific location was moved to generic
platform data location, but it contained more than
platform data, remove it. New local header has been
created for exposing functions.

Also move gpmc-nand platform data to platform header
meant for nand from gpmc header file

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-cm-t35.c           |  3 +-
 arch/arm/mach-omap2/board-cm-t3517.c         |  3 +-
 arch/arm/mach-omap2/board-flash.c            |  4 +--
 arch/arm/mach-omap2/board-omap3pandora.c     |  3 +-
 arch/arm/mach-omap2/common-board-devices.c   |  1 -
 arch/arm/mach-omap2/gpmc-nand.c              | 54 +++++++++++++++-------------
 arch/arm/mach-omap2/gpmc-nand.h              | 27 ++++++++++++++
 arch/arm/mach-omap2/gpmc.c                   |  2 ++
 arch/arm/plat-omap/include/plat/gpmc.h       | 28 ++-------------
 include/linux/platform_data/mtd-nand-omap2.h | 41 ++++++++++++++-------
 10 files changed, 98 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-nand.h

diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 376d26e..fef68de 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -53,6 +53,7 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-nand.h"
 
 #define CM_T35_GPIO_PENDOWN		57
 #define SB_T35_USB_HUB_RESET_GPIO	167
@@ -181,7 +182,7 @@ static struct omap_nand_platform_data cm_t35_nand_data = {
 
 static void __init cm_t35_init_nand(void)
 {
-	if (gpmc_nand_init(&cm_t35_nand_data) < 0)
+	if (gpmc_nand_init(&cm_t35_nand_data, NULL) < 0)
 		pr_err("CM-T35: Unable to register NAND device\n");
 }
 #else
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 59c0a45..3a19e80 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -49,6 +49,7 @@
 #include "control.h"
 #include "common-board-devices.h"
 #include "am35xx-emac.h"
+#include "gpmc-nand.h"
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 static struct gpio_led cm_t3517_leds[] = {
@@ -240,7 +241,7 @@ static struct omap_nand_platform_data cm_t3517_nand_data = {
 
 static void __init cm_t3517_init_nand(void)
 {
-	if (gpmc_nand_init(&cm_t3517_nand_data) < 0)
+	if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0)
 		pr_err("CM-T3517: NAND initialization failed\n");
 }
 #else
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index de68fdf..776e57a 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -26,6 +26,7 @@
 #include "common.h"
 #include "board-flash.h"
 #include "gpmc-onenand.h"
+#include "gpmc-nand.h"
 
 #define REG_FPGA_REV			0x10
 #define REG_FPGA_DIP_SWITCH_INPUT2	0x60
@@ -139,10 +140,9 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.parts		= nand_parts;
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
-	board_nand_data.gpmc_t		= gpmc_t;
 
 	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-	gpmc_nand_init(&board_nand_data);
+	gpmc_nand_init(&board_nand_data, gpmc_t);
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 00a1f4a..f286b4b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -50,6 +50,7 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-nand.h"
 
 #define PANDORA_WIFI_IRQ_GPIO		21
 #define PANDORA_WIFI_NRESET_GPIO	23
@@ -602,7 +603,7 @@ static void __init omap3pandora_init(void)
 	omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
 	usbhs_init(&usbhs_bdata);
 	usb_musb_init(NULL);
-	gpmc_nand_init(&pandora_nand_data);
+	gpmc_nand_init(&pandora_nand_data, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 90e0597..ad85609 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -25,7 +25,6 @@
 #include <linux/spi/ads7846.h>
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/mtd-nand-omap2.h>
 
 #include "common.h"
 #include "common-board-devices.h"
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 4eceaca..c1b9b1d 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -20,6 +20,10 @@
 #include <plat/gpmc.h>
 
 #include "soc.h"
+#include "gpmc-nand.h"
+
+/* minimum size for IO mapping */
+#define	NAND_IO_SIZE	4
 
 static struct resource gpmc_nand_resource[] = {
 	{
@@ -40,37 +44,36 @@ static struct platform_device gpmc_nand_device = {
 	.resource	= gpmc_nand_resource,
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data)
+static int omap2_nand_gpmc_retime(
+				struct omap_nand_platform_data *gpmc_nand_data,
+				struct gpmc_timings *gpmc_t)
 {
 	struct gpmc_timings t;
 	int err;
 
-	if (!gpmc_nand_data->gpmc_t)
-		return 0;
-
 	memset(&t, 0, sizeof(t));
-	t.sync_clk = gpmc_nand_data->gpmc_t->sync_clk;
-	t.cs_on = gpmc_nand_data->gpmc_t->cs_on;
-	t.adv_on = gpmc_nand_data->gpmc_t->adv_on;
+	t.sync_clk = gpmc_t->sync_clk;
+	t.cs_on = gpmc_t->cs_on;
+	t.adv_on = gpmc_t->adv_on;
 
 	/* Read */
-	t.adv_rd_off = gpmc_nand_data->gpmc_t->adv_rd_off;
+	t.adv_rd_off = gpmc_t->adv_rd_off;
 	t.oe_on  = t.adv_on;
-	t.access = gpmc_nand_data->gpmc_t->access;
-	t.oe_off = gpmc_nand_data->gpmc_t->oe_off;
-	t.cs_rd_off = gpmc_nand_data->gpmc_t->cs_rd_off;
-	t.rd_cycle = gpmc_nand_data->gpmc_t->rd_cycle;
+	t.access = gpmc_t->access;
+	t.oe_off = gpmc_t->oe_off;
+	t.cs_rd_off = gpmc_t->cs_rd_off;
+	t.rd_cycle = gpmc_t->rd_cycle;
 
 	/* Write */
-	t.adv_wr_off = gpmc_nand_data->gpmc_t->adv_wr_off;
+	t.adv_wr_off = gpmc_t->adv_wr_off;
 	t.we_on  = t.oe_on;
 	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = gpmc_nand_data->gpmc_t->wr_data_mux_bus;
-		t.wr_access = gpmc_nand_data->gpmc_t->wr_access;
+		t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
+		t.wr_access = gpmc_t->wr_access;
 	}
-	t.we_off = gpmc_nand_data->gpmc_t->we_off;
-	t.cs_wr_off = gpmc_nand_data->gpmc_t->cs_wr_off;
-	t.wr_cycle = gpmc_nand_data->gpmc_t->wr_cycle;
+	t.we_off = gpmc_t->we_off;
+	t.cs_wr_off = gpmc_t->cs_wr_off;
+	t.wr_cycle = gpmc_t->wr_cycle;
 
 	/* Configure GPMC */
 	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
@@ -87,7 +90,8 @@ static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data
 	return 0;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+			  struct gpmc_timings *gpmc_t)
 {
 	int err	= 0;
 	struct device *dev = &gpmc_nand_device.dev;
@@ -108,11 +112,13 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 				gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
 	gpmc_nand_resource[2].start =
 				gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
-	 /* Set timings in GPMC */
-	err = omap2_nand_gpmc_retime(gpmc_nand_data);
-	if (err < 0) {
-		dev_err(dev, "Unable to set gpmc timings: %d\n", err);
-		return err;
+
+	if (gpmc_t) {
+		err = omap2_nand_gpmc_retime(gpmc_nand_data, gpmc_t);
+		if (err < 0) {
+			dev_err(dev, "Unable to set gpmc timings: %d\n", err);
+			return err;
+		}
 	}
 
 	/* Enable RD PIN Monitoring Reg */
diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h
new file mode 100644
index 0000000..11a377f
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-nand.h
@@ -0,0 +1,27 @@
+/*
+ *  arch/arm/mach-omap2/gpmc-nand.h
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef	__OMAP2_GPMC_NAND_H
+#define	__OMAP2_GPMC_NAND_H
+
+#include <plat/gpmc.h>
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
+extern int gpmc_nand_init(struct omap_nand_platform_data *d,
+			  struct gpmc_timings *gpmc_t);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d,
+				 struct gpmc_timings *gpmc_t)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 163458d..3a73196 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -26,6 +26,8 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
+#include <linux/platform_data/mtd-nand-omap2.h>
+
 #include <asm/mach-types.h>
 #include <plat/gpmc.h>
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 1cafbfd..17fc1e7 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -11,6 +11,8 @@
 #ifndef __OMAP2_GPMC_H
 #define __OMAP2_GPMC_H
 
+#include <linux/platform_data/mtd-nand-omap2.h>
+
 /* Maximum Number of Chip Selects */
 #define GPMC_CS_NUM		8
 
@@ -86,16 +88,6 @@
 #define PREFETCH_FIFOTHRESHOLD_MAX	0x40
 #define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
 
-enum omap_ecc {
-		/* 1-bit ecc: stored at end of spare area */
-	OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */
-	OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */
-		/* 1-bit ecc: stored at beginning of spare area as romcode */
-	OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */
-	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
-	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
-};
-
 /* bool type time settings */
 struct gpmc_bool_timings {
 	bool cycle2cyclediffcsen;
@@ -152,22 +144,6 @@ struct gpmc_timings {
 	struct gpmc_bool_timings bool_timings;
 };
 
-struct gpmc_nand_regs {
-	void __iomem	*gpmc_status;
-	void __iomem	*gpmc_nand_command;
-	void __iomem	*gpmc_nand_address;
-	void __iomem	*gpmc_nand_data;
-	void __iomem	*gpmc_prefetch_config1;
-	void __iomem	*gpmc_prefetch_config2;
-	void __iomem	*gpmc_prefetch_control;
-	void __iomem	*gpmc_prefetch_status;
-	void __iomem	*gpmc_ecc_config;
-	void __iomem	*gpmc_ecc_control;
-	void __iomem	*gpmc_ecc_size_config;
-	void __iomem	*gpmc_ecc1_result;
-	void __iomem	*gpmc_bch_result0;
-};
-
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 1a68c1e..e1965fe 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -8,7 +8,9 @@
  * published by the Free Software Foundation.
  */
 
-#include <plat/gpmc.h>
+#ifndef	_MTD_NAND_OMAP2_H
+#define	_MTD_NAND_OMAP2_H
+
 #include <linux/mtd/partitions.h>
 
 enum nand_io {
@@ -18,10 +20,35 @@ enum nand_io {
 	NAND_OMAP_PREFETCH_IRQ		/* prefetch enabled irq mode */
 };
 
+enum omap_ecc {
+		/* 1-bit ecc: stored at end of spare area */
+	OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */
+	OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */
+		/* 1-bit ecc: stored at beginning of spare area as romcode */
+	OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */
+	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
+	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
+};
+
+struct gpmc_nand_regs {
+	void __iomem	*gpmc_status;
+	void __iomem	*gpmc_nand_command;
+	void __iomem	*gpmc_nand_address;
+	void __iomem	*gpmc_nand_data;
+	void __iomem	*gpmc_prefetch_config1;
+	void __iomem	*gpmc_prefetch_config2;
+	void __iomem	*gpmc_prefetch_control;
+	void __iomem	*gpmc_prefetch_status;
+	void __iomem	*gpmc_ecc_config;
+	void __iomem	*gpmc_ecc_control;
+	void __iomem	*gpmc_ecc_size_config;
+	void __iomem	*gpmc_ecc1_result;
+	void __iomem	*gpmc_bch_result0;
+};
+
 struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
-	struct gpmc_timings	*gpmc_t;
 	int			nr_parts;
 	bool			dev_ready;
 	enum nand_io		xfer_type;
@@ -30,14 +57,4 @@ struct omap_nand_platform_data {
 	struct gpmc_nand_regs	reg;
 };
 
-/* minimum size for IO mapping */
-#define	NAND_IO_SIZE	4
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-extern int gpmc_nand_init(struct omap_nand_platform_data *d);
-#else
-static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
-{
-	return 0;
-}
 #endif
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:19 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:19 +0530
Subject: [PATCH 09/15] mtd: nand: omap: bring in gpmc nand macros
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <6cc3ba828d620da5019ac9a0cb8a640f0065773c.1349450454.git.afzal@ti.com>

Bring onto driver the macros defined in gpmc.h that are
not necessary outside driver, helps in removing inclusion
of gpmc.h too. Also remove GPMC prefix on those macros to
make clear it's independence with gpmc header.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index abfc602..f0a1b1d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -110,6 +110,11 @@
 #define	ECC1RESULTSIZE			0x1
 #define	ECCCLEAR			0x100
 #define	ECC1				0x1
+#define	PREFETCH_FIFOTHRESHOLD_MAX	0x40
+#define	PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
+#define	PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
+#define	PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
+#define	STATUS_BUFF_EMPTY		0x00000001
 
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
@@ -269,7 +274,7 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
 		/* wait until buffer is available for write */
 		do {
 			status = readl(info->reg.gpmc_status) &
-					GPMC_STATUS_BUFF_EMPTY;
+					STATUS_BUFF_EMPTY;
 		} while (!status);
 	}
 }
@@ -307,7 +312,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 		/* wait until buffer is available for write */
 		do {
 			status = readl(info->reg.gpmc_status) &
-					GPMC_STATUS_BUFF_EMPTY;
+					STATUS_BUFF_EMPTY;
 		} while (!status);
 	}
 }
@@ -348,7 +353,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
 	} else {
 		do {
 			r_count = readl(info->reg.gpmc_prefetch_status);
-			r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count);
+			r_count = PREFETCH_STATUS_FIFO_CNT(r_count);
 			r_count = r_count >> 2;
 			ioread32_rep(info->nand.IO_ADDR_R, p, r_count);
 			p += r_count;
@@ -395,7 +400,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
 	} else {
 		while (len) {
 			w_count = readl(info->reg.gpmc_prefetch_status);
-			w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count);
+			w_count = PREFETCH_STATUS_FIFO_CNT(w_count);
 			w_count = w_count >> 1;
 			for (i = 0; (i < w_count) && len; i++, len -= 2)
 				iowrite16(*p++, info->nand.IO_ADDR_W);
@@ -407,7 +412,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
 		do {
 			cpu_relax();
 			val = readl(info->reg.gpmc_prefetch_status);
-			val = GPMC_PREFETCH_STATUS_COUNT(val);
+			val = PREFETCH_STATUS_COUNT(val);
 		} while (val && (tim++ < limit));
 
 		/* disable and stop the PFPW engine */
@@ -493,7 +498,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
 	do {
 		cpu_relax();
 		val = readl(info->reg.gpmc_prefetch_status);
-		val = GPMC_PREFETCH_STATUS_COUNT(val);
+		val = PREFETCH_STATUS_COUNT(val);
 	} while (val && (tim++ < limit));
 
 	/* disable and stop the PFPW engine */
@@ -556,7 +561,7 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 	u32 bytes;
 
 	bytes = readl(info->reg.gpmc_prefetch_status);
-	bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
+	bytes = PREFETCH_STATUS_FIFO_CNT(bytes);
 	bytes = bytes  & 0xFFFC; /* io in multiple of 4 bytes */
 	if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
 		if (this_irq == info->gpmc_irq_count)
@@ -682,7 +687,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
 	limit = (loops_per_jiffy *  msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
 	do {
 		val = readl(info->reg.gpmc_prefetch_status);
-		val = GPMC_PREFETCH_STATUS_COUNT(val);
+		val = PREFETCH_STATUS_COUNT(val);
 		cpu_relax();
 	} while (val && (tim++ < limit));
 
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:26 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:26 +0530
Subject: [PATCH 10/15] ARM: OMAP2+: nand: bch capability check
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <1a465d868bcd2d182a5b6571e31714fc5951be38.1349450454.git.afzal@ti.com>

Capability of bch schemes could be discovered using soc
revision checks. If soc revision indicates that selected
ecc scheme is not supported bail out.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index c1b9b1d..7983d54 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -90,6 +90,27 @@ static int omap2_nand_gpmc_retime(
 	return 0;
 }
 
+static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
+{
+	/* support only OMAP3 class */
+	if (!cpu_is_omap34xx()) {
+		pr_err("BCH ecc is not supported on this CPU\n");
+		return 0;
+	}
+
+	/*
+	 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
+	 * Other chips may be added if confirmed to work.
+	 */
+	if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) &&
+	    (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
+		pr_err("BCH 4-bit mode is not supported on this CPU\n");
+		return 0;
+	}
+
+	return 1;
+}
+
 int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 			  struct gpmc_timings *gpmc_t)
 {
@@ -128,6 +149,9 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 
 	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
 
+	if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt))
+		return -EINVAL;
+
 	err = platform_device_register(&gpmc_nand_device);
 	if (err < 0) {
 		dev_err(dev, "Unable to register NAND device\n");
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:32 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:32 +0530
Subject: [PATCH 11/15] ARM: OMAP2+: gpmc: nand register helper bch update
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <4ba6dff22def5d5e00d4b7270164ce5e0d71a3c1.1349450454.git.afzal@ti.com>

Update helper function that provides gpmc-nand register
details for nand driver with bch register information.
Using this nand driver can be made self sufficient to
handle remaining gpmc-nand operations by itself instead
of relying on gpmc exported nand functions.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c                   | 18 +++++++++++++++++-
 include/linux/platform_data/mtd-nand-omap2.h |  7 ++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 3a73196..eb577c5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -61,6 +61,9 @@
 #define GPMC_ECC_SIZE_CONFIG	0x1fc
 #define GPMC_ECC1_RESULT        0x200
 #define GPMC_ECC_BCH_RESULT_0   0x240   /* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_1	0x244	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_2	0x248	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_3	0x24c	/* not available on OMAP2 */
 
 /* GPMC ECC control settings */
 #define GPMC_ECC_CTRL_ECCCLEAR		0x100
@@ -84,6 +87,7 @@
 
 #define GPMC_CS0_OFFSET		0x60
 #define GPMC_CS_SIZE		0x30
+#define	GPMC_BCH_SIZE		0x10
 
 #define GPMC_MEM_START		0x00000000
 #define GPMC_MEM_END		0x3FFFFFFF
@@ -779,6 +783,8 @@ EXPORT_SYMBOL(gpmc_prefetch_reset);
 
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
+	int i;
+
 	reg->gpmc_status = gpmc_base + GPMC_STATUS;
 	reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
 				GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
@@ -794,7 +800,17 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
 	reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
 	reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
-	reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0;
+
+	for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
+		reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
+					   GPMC_BCH_SIZE * i;
+	}
 }
 
 int gpmc_get_client_irq(unsigned irq_config)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index e1965fe..24d32ca 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -13,6 +13,8 @@
 
 #include <linux/mtd/partitions.h>
 
+#define	GPMC_BCH_NUM_REMAINDER	8
+
 enum nand_io {
 	NAND_OMAP_PREFETCH_POLLED = 0,	/* prefetch polled mode, default */
 	NAND_OMAP_POLLED,		/* polled mode, without prefetch */
@@ -43,7 +45,10 @@ struct gpmc_nand_regs {
 	void __iomem	*gpmc_ecc_control;
 	void __iomem	*gpmc_ecc_size_config;
 	void __iomem	*gpmc_ecc1_result;
-	void __iomem	*gpmc_bch_result0;
+	void __iomem	*gpmc_bch_result0[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result1[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result2[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result3[GPMC_BCH_NUM_REMAINDER];
 };
 
 struct omap_nand_platform_data {
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:38 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:38 +0530
Subject: [PATCH 12/15] mtd: nand: omap: handle gpmc bch[48]
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <dc678b08468e16200bef05e8927526916fb4459e.1349450454.git.afzal@ti.com>

gpmc-nand bch registers are now available in driver,
make use of it to handle bch[48] instead of relying
on gpmc exported functions.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 95 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 86 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f0a1b1d..e3fc8d7 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -106,6 +106,7 @@
 #define	CS_MASK				0x7
 #define	ENABLE_PREFETCH			(0x1 << 7)
 #define	DMA_MPU_MODE_SHIFT		2
+#define	ECCSIZE0_SHIFT			12
 #define	ECCSIZE1_SHIFT			22
 #define	ECC1RESULTSIZE			0x1
 #define	ECCCLEAR			0x100
@@ -1034,19 +1035,45 @@ static int omap_dev_ready(struct mtd_info *mtd)
 static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 {
 	int nerrors;
-	unsigned int dev_width;
+	unsigned int dev_width, nsectors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 	struct nand_chip *chip = mtd->priv;
+	u32 val;
 
 	nerrors = (info->nand.ecc.bytes == 13) ? 8 : 4;
 	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+	nsectors = 1;
 	/*
 	 * Program GPMC to perform correction on one 512-byte sector at a time.
 	 * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
 	 * gives a slight (5%) performance gain (but requires additional code).
 	 */
-	(void)gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width, 1, nerrors);
+
+	writel(ECC1, info->reg.gpmc_ecc_control);
+
+	/*
+	 * When using BCH, sector size is hardcoded to 512 bytes.
+	 * Here we are using wrapping mode 6 both for reading and writing, with:
+	 *  size0 = 0  (no additional protected byte in spare area)
+	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
+	 */
+	val = (32 << ECCSIZE1_SHIFT) | (0 << ECCSIZE0_SHIFT);
+	writel(val, info->reg.gpmc_ecc_size_config);
+
+	/* BCH configuration */
+	val = ((1                        << 16) | /* enable BCH */
+	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
+	       (0x06                     <<  8) | /* wrap mode = 6 */
+	       (dev_width                <<  7) | /* bus width */
+	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
+	       (info->gpmc_cs            <<  1) | /* ECC CS */
+	       (0x1));                            /* enable ECC */
+
+	writel(val, info->reg.gpmc_ecc_config);
+
+	/* clear ecc and enable bits */
+	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
 
 /**
@@ -1060,7 +1087,31 @@ static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat,
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	return gpmc_calculate_ecc_bch4(info->gpmc_cs, dat, ecc_code);
+	unsigned long nsectors, val1, val2;
+
+	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
+
+	for (i = 0; i < nsectors; i++) {
+
+		/* Read hw-computed remainder */
+		val1 = readl(info->reg.gpmc_bch_result0[i]);
+		val2 = readl(info->reg.gpmc_bch_result1[i]);
+
+		/*
+		 * Add constant polynomial to remainder, in order to get an ecc
+		 * sequence of 0xFFs for a buffer filled with 0xFFs; and
+		 * left-justify the resulting polynomial.
+		 */
+		*ecc++ = 0x28 ^ ((val2 >> 12) & 0xFF);
+		*ecc++ = 0x13 ^ ((val2 >>  4) & 0xFF);
+		*ecc++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
+		*ecc++ = 0x39 ^ ((val1 >> 20) & 0xFF);
+		*ecc++ = 0x96 ^ ((val1 >> 12) & 0xFF);
+		*ecc++ = 0xac ^ ((val1 >> 4) & 0xFF);
+		*ecc++ = 0x7f ^ ((val1 & 0xF) << 4);
+	}
+
+	return 0;
 }
 
 /**
@@ -1074,7 +1125,38 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	return gpmc_calculate_ecc_bch8(info->gpmc_cs, dat, ecc_code);
+	unsigned long nsectors, reg, val1, val2, val3, val4;
+
+	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
+
+	for (i = 0; i < nsectors; i++) {
+
+		/* Read hw-computed remainder */
+		val1 = readl(info->reg.gpmc_bch_result0[i]);
+		val2 = readl(info->reg.gpmc_bch_result1[i]);
+		val3 = readl(info->reg.gpmc_bch_result2[i]);
+		val4 = readl(info->reg.gpmc_bch_result3[i]);
+
+		/*
+		 * Add constant polynomial to remainder, in order to get an ecc
+		 * sequence of 0xFFs for a buffer filled with 0xFFs.
+		 */
+		*ecc++ = 0xef ^ (val4 & 0xFF);
+		*ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
+		*ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
+		*ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
+		*ecc++ = 0xed ^ (val3 & 0xFF);
+		*ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
+		*ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
+		*ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
+		*ecc++ = 0x97 ^ (val2 & 0xFF);
+		*ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
+		*ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
+		*ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
+		*ecc++ = 0xb5 ^ (val1 & 0xFF);
+	}
+
+	return 0;
 }
 
 /**
@@ -1147,11 +1229,6 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 		goto fail;
 	}
 
-	/* initialize GPMC BCH engine */
-	ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
-	if (ret)
-		goto fail;
-
 	/* software bch library is only used to detect and locate errors */
 	info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
 	if (!info->bch)
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:44 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:44 +0530
Subject: [PATCH 13/15] ARM: OMAP2+: gpmc: remove exported nand functions
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <9d82fa7c51461a6bd6438516f0d087cd56b546ce.1349450454.git.afzal@ti.com>

nand driver handles gpmc-nand block fully, hence no more
users for these exported nand functions, remove it.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c             | 432 ---------------------------------
 arch/arm/plat-omap/include/plat/gpmc.h |  31 ---
 2 files changed, 463 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index eb577c5..1121248 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -150,7 +150,6 @@ static struct resource	gpmc_mem_root;
 static struct resource	gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
-static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
 static struct device *gpmc_dev;
 static int gpmc_irq;
 static resource_size_t phys_base, mem_size;
@@ -171,22 +170,6 @@ static u32 gpmc_read_reg(int idx)
 	return __raw_readl(gpmc_base + idx);
 }
 
-static void gpmc_cs_write_byte(int cs, int idx, u8 val)
-{
-	void __iomem *reg_addr;
-
-	reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
-	__raw_writeb(val, reg_addr);
-}
-
-static u8 gpmc_cs_read_byte(int cs, int idx)
-{
-	void __iomem *reg_addr;
-
-	reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
-	return __raw_readb(reg_addr);
-}
-
 void gpmc_cs_write_reg(int cs, int idx, u32 val)
 {
 	void __iomem *reg_addr;
@@ -563,44 +546,6 @@ void gpmc_cs_free(int cs)
 EXPORT_SYMBOL(gpmc_cs_free);
 
 /**
- * gpmc_read_status - read access request to get the different gpmc status
- * @cmd: command type
- * @return status
- */
-int gpmc_read_status(int cmd)
-{
-	int	status = -EINVAL;
-	u32	regval = 0;
-
-	switch (cmd) {
-	case GPMC_GET_IRQ_STATUS:
-		status = gpmc_read_reg(GPMC_IRQSTATUS);
-		break;
-
-	case GPMC_PREFETCH_FIFO_CNT:
-		regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
-		status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval);
-		break;
-
-	case GPMC_PREFETCH_COUNT:
-		regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
-		status = GPMC_PREFETCH_STATUS_COUNT(regval);
-		break;
-
-	case GPMC_STATUS_BUFFER:
-		regval = gpmc_read_reg(GPMC_STATUS);
-		/* 1 : buffer is available to write */
-		status = regval & GPMC_STATUS_BUFF_EMPTY;
-		break;
-
-	default:
-		printk(KERN_ERR "gpmc_read_status: Not supported\n");
-	}
-	return status;
-}
-EXPORT_SYMBOL(gpmc_read_status);
-
-/**
  * gpmc_cs_configure - write request to configure gpmc
  * @cs: chip select number
  * @cmd: command type
@@ -668,119 +613,6 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
 }
 EXPORT_SYMBOL(gpmc_cs_configure);
 
-/**
- * gpmc_nand_read - nand specific read access request
- * @cs: chip select number
- * @cmd: command type
- */
-int gpmc_nand_read(int cs, int cmd)
-{
-	int rval = -EINVAL;
-
-	switch (cmd) {
-	case GPMC_NAND_DATA:
-		rval = gpmc_cs_read_byte(cs, GPMC_CS_NAND_DATA);
-		break;
-
-	default:
-		printk(KERN_ERR "gpmc_read_nand_ctrl: Not supported\n");
-	}
-	return rval;
-}
-EXPORT_SYMBOL(gpmc_nand_read);
-
-/**
- * gpmc_nand_write - nand specific write request
- * @cs: chip select number
- * @cmd: command type
- * @wval: value to write
- */
-int gpmc_nand_write(int cs, int cmd, int wval)
-{
-	int err = 0;
-
-	switch (cmd) {
-	case GPMC_NAND_COMMAND:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_COMMAND, wval);
-		break;
-
-	case GPMC_NAND_ADDRESS:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_ADDRESS, wval);
-		break;
-
-	case GPMC_NAND_DATA:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_DATA, wval);
-
-	default:
-		printk(KERN_ERR "gpmc_write_nand_ctrl: Not supported\n");
-		err = -EINVAL;
-	}
-	return err;
-}
-EXPORT_SYMBOL(gpmc_nand_write);
-
-
-
-/**
- * gpmc_prefetch_enable - configures and starts prefetch transfer
- * @cs: cs (chip select) number
- * @fifo_th: fifo threshold to be used for read/ write
- * @dma_mode: dma mode enable (1) or disable (0)
- * @u32_count: number of bytes to be transferred
- * @is_write: prefetch read(0) or write post(1) mode
- */
-int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
-				unsigned int u32_count, int is_write)
-{
-
-	if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
-		pr_err("gpmc: fifo threshold is not supported\n");
-		return -1;
-	} else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
-		/* Set the amount of bytes to be prefetched */
-		gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
-
-		/* Set dma/mpu mode, the prefetch read / post write and
-		 * enable the engine. Set which cs is has requested for.
-		 */
-		gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
-					PREFETCH_FIFOTHRESHOLD(fifo_th) |
-					ENABLE_PREFETCH |
-					(dma_mode << DMA_MPU_MODE) |
-					(0x1 & is_write)));
-
-		/*  Start the prefetch engine */
-		gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1);
-	} else {
-		return -EBUSY;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(gpmc_prefetch_enable);
-
-/**
- * gpmc_prefetch_reset - disables and stops the prefetch engine
- */
-int gpmc_prefetch_reset(int cs)
-{
-	u32 config1;
-
-	/* check if the same module/cs is trying to reset */
-	config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
-	if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs)
-		return -EINVAL;
-
-	/* Stop the PFPW engine */
-	gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0);
-
-	/* Reset/disable the PFPW engine */
-	gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0);
-
-	return 0;
-}
-EXPORT_SYMBOL(gpmc_prefetch_reset);
-
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
 	int i;
@@ -1145,267 +977,3 @@ void omap3_gpmc_restore_context(void)
 	}
 }
 #endif /* CONFIG_ARCH_OMAP3 */
-
-/**
- * gpmc_enable_hwecc - enable hardware ecc functionality
- * @cs: chip select number
- * @mode: read/write mode
- * @dev_width: device bus width(1 for x16, 0 for x8)
- * @ecc_size: bytes for which ECC will be generated
- */
-int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
-{
-	unsigned int val;
-
-	/* check if ecc module is in used */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	gpmc_ecc_used = cs;
-
-	/* clear ecc and enable bits */
-	gpmc_write_reg(GPMC_ECC_CONTROL,
-			GPMC_ECC_CTRL_ECCCLEAR |
-			GPMC_ECC_CTRL_ECCREG1);
-
-	/* program ecc and result sizes */
-	val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F));
-	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val);
-
-	switch (mode) {
-	case GPMC_ECC_READ:
-	case GPMC_ECC_WRITE:
-		gpmc_write_reg(GPMC_ECC_CONTROL,
-				GPMC_ECC_CTRL_ECCCLEAR |
-				GPMC_ECC_CTRL_ECCREG1);
-		break;
-	case GPMC_ECC_READSYN:
-		gpmc_write_reg(GPMC_ECC_CONTROL,
-				GPMC_ECC_CTRL_ECCCLEAR |
-				GPMC_ECC_CTRL_ECCDISABLE);
-		break;
-	default:
-		printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode);
-		break;
-	}
-
-	/* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
-	val = (dev_width << 7) | (cs << 1) | (0x1);
-	gpmc_write_reg(GPMC_ECC_CONFIG, val);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_enable_hwecc);
-
-/**
- * gpmc_calculate_ecc - generate non-inverted ecc bytes
- * @cs: chip select number
- * @dat: data pointer over which ecc is computed
- * @ecc_code: ecc code buffer
- *
- * Using non-inverted ECC is considered ugly since writing a blank
- * page (padding) will clear the ECC bytes. This is not a problem as long
- * no one is trying to write data on the seemingly unused page. Reading
- * an erased page will produce an ECC mismatch between generated and read
- * ECC bytes that has to be dealt with separately.
- */
-int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code)
-{
-	unsigned int val = 0x0;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	/* read ecc result */
-	val = gpmc_read_reg(GPMC_ECC1_RESULT);
-	*ecc_code++ = val;          /* P128e, ..., P1e */
-	*ecc_code++ = val >> 16;    /* P128o, ..., P1o */
-	/* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
-	*ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc);
-
-#ifdef CONFIG_ARCH_OMAP3
-
-/**
- * gpmc_init_hwecc_bch - initialize hardware BCH ecc functionality
- * @cs: chip select number
- * @nsectors: how many 512-byte sectors to process
- * @nerrors: how many errors to correct per sector (4 or 8)
- *
- * This function must be executed before any call to gpmc_enable_hwecc_bch.
- */
-int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors)
-{
-	/* check if ecc module is in use */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	/* support only OMAP3 class */
-	if (!cpu_is_omap34xx()) {
-		printk(KERN_ERR "BCH ecc is not supported on this CPU\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
-	 * Other chips may be added if confirmed to work.
-	 */
-	if ((nerrors == 4) &&
-	    (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
-		printk(KERN_ERR "BCH 4-bit mode is not supported on this CPU\n");
-		return -EINVAL;
-	}
-
-	/* sanity check */
-	if (nsectors > 8) {
-		printk(KERN_ERR "BCH cannot process %d sectors (max is 8)\n",
-		       nsectors);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_init_hwecc_bch);
-
-/**
- * gpmc_enable_hwecc_bch - enable hardware BCH ecc functionality
- * @cs: chip select number
- * @mode: read/write mode
- * @dev_width: device bus width(1 for x16, 0 for x8)
- * @nsectors: how many 512-byte sectors to process
- * @nerrors: how many errors to correct per sector (4 or 8)
- */
-int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
-			  int nerrors)
-{
-	unsigned int val;
-
-	/* check if ecc module is in use */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	gpmc_ecc_used = cs;
-
-	/* clear ecc and enable bits */
-	gpmc_write_reg(GPMC_ECC_CONTROL, 0x1);
-
-	/*
-	 * When using BCH, sector size is hardcoded to 512 bytes.
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
-	 */
-	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (32 << 22) | (0 << 12));
-
-	/* BCH configuration */
-	val = ((1                        << 16) | /* enable BCH */
-	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
-	       (0x06                     <<  8) | /* wrap mode = 6 */
-	       (dev_width                <<  7) | /* bus width */
-	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
-	       (cs                       <<  1) | /* ECC CS */
-	       (0x1));                            /* enable ECC */
-
-	gpmc_write_reg(GPMC_ECC_CONFIG, val);
-	gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_enable_hwecc_bch);
-
-/**
- * gpmc_calculate_ecc_bch4 - Generate 7 ecc bytes per sector of 512 data bytes
- * @cs:  chip select number
- * @dat: The pointer to data on which ecc is computed
- * @ecc: The ecc output buffer
- */
-int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc)
-{
-	int i;
-	unsigned long nsectors, reg, val1, val2;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
-
-		/* Read hw-computed remainder */
-		val1 = gpmc_read_reg(reg + 0);
-		val2 = gpmc_read_reg(reg + 4);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs; and
-		 * left-justify the resulting polynomial.
-		 */
-		*ecc++ = 0x28 ^ ((val2 >> 12) & 0xFF);
-		*ecc++ = 0x13 ^ ((val2 >>  4) & 0xFF);
-		*ecc++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
-		*ecc++ = 0x39 ^ ((val1 >> 20) & 0xFF);
-		*ecc++ = 0x96 ^ ((val1 >> 12) & 0xFF);
-		*ecc++ = 0xac ^ ((val1 >> 4) & 0xFF);
-		*ecc++ = 0x7f ^ ((val1 & 0xF) << 4);
-	}
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch4);
-
-/**
- * gpmc_calculate_ecc_bch8 - Generate 13 ecc bytes per block of 512 data bytes
- * @cs:  chip select number
- * @dat: The pointer to data on which ecc is computed
- * @ecc: The ecc output buffer
- */
-int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc)
-{
-	int i;
-	unsigned long nsectors, reg, val1, val2, val3, val4;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
-
-		/* Read hw-computed remainder */
-		val1 = gpmc_read_reg(reg + 0);
-		val2 = gpmc_read_reg(reg + 4);
-		val3 = gpmc_read_reg(reg + 8);
-		val4 = gpmc_read_reg(reg + 12);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs.
-		 */
-		*ecc++ = 0xef ^ (val4 & 0xFF);
-		*ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
-		*ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
-		*ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
-		*ecc++ = 0xed ^ (val3 & 0xFF);
-		*ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
-		*ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
-		*ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
-		*ecc++ = 0x97 ^ (val2 & 0xFF);
-		*ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
-		*ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
-		*ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
-		*ecc++ = 0xb5 ^ (val1 & 0xFF);
-	}
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch8);
-
-#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 17fc1e7..e08a51a 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -34,15 +34,6 @@
 #define GPMC_SET_IRQ_STATUS	0x00000004
 #define GPMC_CONFIG_WP		0x00000005
 
-#define GPMC_GET_IRQ_STATUS	0x00000006
-#define GPMC_PREFETCH_FIFO_CNT	0x00000007 /* bytes available in FIFO for r/w */
-#define GPMC_PREFETCH_COUNT	0x00000008 /* remaining bytes to be read/write*/
-#define GPMC_STATUS_BUFFER	0x00000009 /* 1: buffer is available to write */
-
-#define GPMC_NAND_COMMAND	0x0000000a
-#define GPMC_NAND_ADDRESS	0x0000000b
-#define GPMC_NAND_DATA		0x0000000c
-
 #define GPMC_ENABLE_IRQ		0x0000000d
 
 /* ECC commands */
@@ -78,15 +69,10 @@
 #define GPMC_DEVICETYPE_NOR		0
 #define GPMC_DEVICETYPE_NAND		2
 #define GPMC_CONFIG_WRITEPROTECT	0x00000010
-#define GPMC_STATUS_BUFF_EMPTY		0x00000001
 #define WR_RD_PIN_MONITORING		0x00600000
-#define GPMC_PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
-#define GPMC_PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
-#define PREFETCH_FIFOTHRESHOLD_MAX	0x40
-#define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
 
 /* bool type time settings */
 struct gpmc_bool_timings {
@@ -161,25 +147,8 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern int gpmc_cs_set_reserved(int cs, int reserved);
 extern int gpmc_cs_reserved(int cs);
-extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
-					unsigned int u32_count, int is_write);
-extern int gpmc_prefetch_reset(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern int gpmc_read_status(int cmd);
 extern int gpmc_cs_configure(int cs, int cmd, int wval);
-extern int gpmc_nand_read(int cs, int cmd);
-extern int gpmc_nand_write(int cs, int cmd, int wval);
-
-int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size);
-int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code);
-
-#ifdef CONFIG_ARCH_OMAP3
-int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors);
-int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
-			  int nerrors);
-int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc);
-int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc);
-#endif /* CONFIG_ARCH_OMAP3 */
 
 #endif
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:50 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:50 +0530
Subject: [PATCH 14/15] mtd: nand: omap: gpmc header removal
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <483b3586b25cfe4069e9a1953733a94814b3db7b.1349450454.git.afzal@ti.com>

nand driver no longer needs gpmc header, remove it.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index e3fc8d7..d6664d7 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -28,7 +28,6 @@
 #endif
 
 #include <plat/dma.h>
-#include <plat/gpmc.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #define	DRIVER_NAME	"omap2-nand"
-- 
1.7.12



From afzal at ti.com  Fri Oct  5 11:54:56 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Fri, 5 Oct 2012 21:24:56 +0530
Subject: [PATCH 15/15] ARM: OMAP2+: gpmc: localize gpmc header
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <5b6e54e44dc29cb3a169909fa89f486b25cee637.1349450454.git.afzal@ti.com>

Requirement of gpmc header outside of mach-omap2 has been
cutoff, move gpmc header file in plat-omap folder to local
mach-omap2 folder

Objective - common zImage participation of omap

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-2430sdp.c                    | 2 +-
 arch/arm/mach-omap2/board-3430sdp.c                    | 2 +-
 arch/arm/mach-omap2/board-apollon.c                    | 2 +-
 arch/arm/mach-omap2/board-cm-t35.c                     | 2 +-
 arch/arm/mach-omap2/board-cm-t3517.c                   | 2 +-
 arch/arm/mach-omap2/board-devkit8000.c                 | 2 +-
 arch/arm/mach-omap2/board-flash.c                      | 2 +-
 arch/arm/mach-omap2/board-flash.h                      | 2 +-
 arch/arm/mach-omap2/board-h4.c                         | 2 +-
 arch/arm/mach-omap2/board-igep0020.c                   | 2 +-
 arch/arm/mach-omap2/board-ldp.c                        | 2 +-
 arch/arm/mach-omap2/board-omap3beagle.c                | 2 +-
 arch/arm/mach-omap2/board-omap3logic.c                 | 2 +-
 arch/arm/mach-omap2/board-omap3stalker.c               | 2 +-
 arch/arm/mach-omap2/board-omap3touchbook.c             | 2 +-
 arch/arm/mach-omap2/board-overo.c                      | 2 +-
 arch/arm/mach-omap2/board-rm680.c                      | 2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c           | 2 +-
 arch/arm/mach-omap2/board-rx51.c                       | 2 +-
 arch/arm/mach-omap2/board-zoom-debugboard.c            | 2 +-
 arch/arm/mach-omap2/gpmc-nand.c                        | 3 +--
 arch/arm/mach-omap2/gpmc-nand.h                        | 2 +-
 arch/arm/mach-omap2/gpmc-onenand.c                     | 3 +--
 arch/arm/mach-omap2/gpmc-smc91x.c                      | 2 +-
 arch/arm/mach-omap2/gpmc-smsc911x.c                    | 2 +-
 arch/arm/mach-omap2/gpmc.c                             | 3 +--
 arch/arm/{plat-omap/include/plat => mach-omap2}/gpmc.h | 0
 arch/arm/mach-omap2/pm34xx.c                           | 2 +-
 arch/arm/mach-omap2/usb-tusb6010.c                     | 2 +-
 29 files changed, 28 insertions(+), 31 deletions(-)
 rename arch/arm/{plat-omap/include/plat => mach-omap2}/gpmc.h (100%)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 95b384d..49e49d0 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -34,7 +34,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 #include "gpmc-smc91x.h"
 
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 96cd369..5ad0901 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -33,7 +33,7 @@
 #include <plat/usb.h>
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <video/omapdss.h>
 #include <video/omap-panel-tfp410.h>
 
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index cea3aba..8cdd186 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -35,7 +35,7 @@
 
 #include <plat/led.h>
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index fef68de..73e2ba9 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -40,7 +40,7 @@
 
 #include "common.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 3a19e80..b5495e4 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -41,7 +41,7 @@
 #include "common.h"
 #include <plat/usb.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include "am35xx.h"
 
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 9933966..3eedb8f 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -39,7 +39,7 @@
 #include <asm/mach/flash.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 776e57a..c56986f 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -18,7 +18,7 @@
 #include <linux/io.h>
 
 #include <plat/cpu.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 #include <plat/tc.h>
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index a3aa5fc..2fb5d41 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -12,7 +12,7 @@
  */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #define PDC_NOR		1
 #define PDC_NAND	2
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 8d04bf8..65ebf58 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -33,7 +33,6 @@
 
 #include <plat/menelaus.h>
 #include <plat/dma.h>
-#include <plat/gpmc.h>
 #include "debug-devices.h"
 
 #include <video/omapdss.h>
@@ -42,6 +41,7 @@
 #include "common.h"
 #include "mux.h"
 #include "control.h"
+#include "gpmc.h"
 
 #define H4_FLASH_CS	0
 #define H4_SMC91X_CS	1
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 83c6efa..9a9a9b5 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -30,7 +30,7 @@
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 83383f3..e1628cd 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -35,7 +35,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <mach/board-zoom.h>
 #include <plat/usb.h>
 #include "gpmc-smsc911x.h"
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index f240e21..65eaaee 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -41,7 +41,7 @@
 #include "common.h"
 #include <video/omapdss.h>
 #include <video/omap-panel-tfp410.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <plat/omap_device.h>
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 7bd8253..5cfade2 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -35,7 +35,7 @@
 #include <asm/mach/map.h>
 
 #include "gpmc-smsc911x.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/sdrc.h>
 #include <plat/usb.h>
 
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c7f3d02..11fcc73 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -40,7 +40,7 @@
 #include <asm/mach/flash.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 3f013c8..cd282ae 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -44,7 +44,7 @@
 #include <asm/system_info.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index e2cf0f7..3a9d1fa 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -49,7 +49,7 @@
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
 #include <video/omap-panel-tfp410.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 154cf33..3c3a473 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -25,7 +25,7 @@
 #include <plat/i2c.h>
 #include <plat/mmc.h>
 #include <plat/usb.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "common.h"
 #include <plat/serial.h>
 
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index aa6a2a4..5ba8942 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -32,7 +32,7 @@
 
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/omap-pm.h>
 #include "gpmc-smc91x.h"
 
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 7bbb05d..88ba5be 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -25,7 +25,7 @@
 
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index afb2278..be9f71d 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -17,7 +17,7 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smsc911x.h"
 
 #include <mach/board-zoom.h>
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 7983d54..db969a5 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -17,8 +17,7 @@
 
 #include <asm/mach/flash.h>
 
-#include <plat/gpmc.h>
-
+#include "gpmc.h"
 #include "soc.h"
 #include "gpmc-nand.h"
 
diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h
index 11a377f..d59e128 100644
--- a/arch/arm/mach-omap2/gpmc-nand.h
+++ b/arch/arm/mach-omap2/gpmc-nand.h
@@ -10,7 +10,7 @@
 #ifndef	__OMAP2_GPMC_NAND_H
 #define	__OMAP2_GPMC_NAND_H
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 29671cc..54e2255 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -20,8 +20,7 @@
 
 #include <asm/mach/flash.h>
 
-#include <plat/gpmc.h>
-
+#include "gpmc.h"
 #include "soc.h"
 #include "gpmc-onenand.h"
 
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 5654753..6eed907 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <linux/smc91x.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smc91x.h"
 
 #include "soc.h"
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 249a0b4..ef99011 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -20,7 +20,7 @@
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smsc911x.h"
 
 static struct resource gpmc_smsc911x_resources[] = {
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1121248..285070e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -29,15 +29,14 @@
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #include <asm/mach-types.h>
-#include <plat/gpmc.h>
 
 #include <plat/cpu.h>
-#include <plat/gpmc.h>
 #include <plat/sdrc.h>
 #include <plat/omap_device.h>
 
 #include "soc.h"
 #include "common.h"
+#include "gpmc.h"
 
 #define	DEVICE_NAME		"omap-gpmc"
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/mach-omap2/gpmc.h
similarity index 100%
rename from arch/arm/plat-omap/include/plat/gpmc.h
rename to arch/arm/mach-omap2/gpmc.h
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ba670db..ed98f4f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -40,7 +40,7 @@
 #include "powerdomain.h"
 #include <plat/sdrc.h>
 #include <plat/prcm.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/dma.h>
 
 #include "common.h"
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 7a85ebe..8ee73fc 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -18,7 +18,7 @@
 
 #include <linux/usb/musb.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include "mux.h"
 
-- 
1.7.12



From bas at bmail.ru  Fri Oct  5 11:57:52 2012
From: bas at bmail.ru (kyak)
Date: Fri, 5 Oct 2012 19:57:52 +0400 (MSK)
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.LNX.2.02.1210032322590.1375@bas>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
Message-ID: <alpine.LNX.2.02.1210051949390.1375@bas>

I think the fact that i created that example directories in /tmp is 
misleading. 
This is not a tmpfs problem.

I observe the same problem with any other directory (namely, with my 
/home, which is not reabable).

When one of the directories in "-d" hierarchy is not readable, mkfs.ubifs 
will fail all the time, thinking that the output file is located in UBIFS 
root directory.

On Wed, 3 Oct 2012, kyak wrote:

> Hi,
>
> Consider the following sequence of commands:
>
> cd ~
> mkdir -p /tmp/wtf/wtf1
> chmod u-r /tmp/wtf
> mkfs.ubifs -m 4096 -e 516096 -c 4095 -d /tmp/wtf/wtf1 -o mytest.img
> Error: output file cannot be in the UBIFS root directory
>
> mytest.img is not inside /tmp/wtf/wtf1, but mkfs.ubifs fails because /tmp/wtf 
> is not readable.
> It seems that implementation of in_path(..) in mkfs.ubifs.c is not quite 
> correct to handle this type of situations.
>
> If you are wondering, my /home is not readable, and this prevents me from 
> building any ubifs image inside of /home/user.
>
> Thanks in advance.
>


From jgunthorpe at obsidianresearch.com  Fri Oct  5 14:32:02 2012
From: jgunthorpe at obsidianresearch.com (Jason Gunthorpe)
Date: Fri, 5 Oct 2012 12:32:02 -0600
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
Message-ID: <20121005183202.GA11385@obsidianresearch.com>

Using jiffies for timeout could have significant rounding, ie if we
start at jiffie 1.9 and timeout at 2 then we may only get .1 jiffies
of timeout, which is not nearly enough. With a Hz of 250 I've seen
random bogus timeouts from this code.

Add a +1 to the HZ calculations to ensure a guaranteed minimum
timeout period.

This also increases the write_buffer timeout to 1.5us since I have
flashes in use that have a datasheet max of over 1 us.

Signed-off-by: Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
---
 drivers/mtd/chips/cfi_cmdset_0002.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 22d0493..46a1dde 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1150,10 +1150,10 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 	 * use the maximum timeout value given by the chip at probe time
 	 * instead.  Unfortunately, struct flchip does have a field for
 	 * maximum timeout, only for typical which can be far too short
-	 * depending of the conditions.	 The ' + 1' is to avoid having a
-	 * timeout of 0 jiffies if HZ is smaller than 1000.
+	 * depending of the conditions.	 The ' + 2' is to ensure we get
+	 * *at least* 1000us of timeout.
 	 */
-	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+	unsigned long uWriteTimeout = (HZ / 1000) + 2;
 	int ret = 0;
 	map_word oldd;
 	int retry_cnt = 0;
@@ -1382,8 +1382,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
-	/* see comments in do_write_oneword() regarding uWriteTimeo. */
-	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
+	/* see comments in do_write_oneword() regarding uWriteTimeo.
+	   Note: write_buffer commands take longer so we use a higher
+	   time. The AMD 29LV256M for instance has a datasheet max
+	   of 1.2ms for page and 600us for byte */
+	unsigned long uWriteTimeout = (HZ / 1500) + 2;
 	int ret = -EIO;
 	unsigned long cmd_adr;
 	int z, words;
-- 
1.7.5.4



From zajec5 at gmail.com  Sat Oct  6 06:57:35 2012
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Sat, 6 Oct 2012 12:57:35 +0200
Subject: Problem with verify-ing patch (error: arch/m68k/Kconfig.cpu:
 patch does not apply)
In-Reply-To: <1349426906.20373.77.camel@sauron.fi.intel.com>
References: <CACna6rwju0g+sq+vBAfCqFJm=EBLg79G2XoGEKs5n1Y=PcmKBg@mail.gmail.com>
 <1348499094.4880.65.camel@sauron.fi.intel.com>
 <CACna6ryu06qsgX99kdkeDaB+XJv4XwC0-O+5ysNFa1iOMEgNow@mail.gmail.com>
 <1348574785.20474.15.camel@sauron.fi.intel.com>
 <1349426906.20373.77.camel@sauron.fi.intel.com>
Message-ID: <CACna6rxZpxFL6xfjbdsW95_rfqL_yhRbUxLnGXeDLXQypLN0mQ@mail.gmail.com>

2012/10/5 Artem Bityutskiy <dedekind1 at gmail.com>:
> On Tue, 2012-09-25 at 15:06 +0300, Artem Bityutskiy wrote:
>> I'll do the fixes as soon as I have some time, please, keep bugging me
>> and thanks for your feed-back!
>
> I've just pushed a change which should improve user-friendliness. Now I
> check for dependencies in many places and try to inform the user if a
> program is missing, plus give some suggestions where to take it from.
> E.g., for cross-tools I print the URL where one can download pre-built
> cross-tools.

Great, thanks for you work! :)

-- 
Rafa?


From computersforpeace at gmail.com  Sat Oct  6 16:24:25 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Sat, 6 Oct 2012 13:24:25 -0700
Subject: [PATCH 9/9] mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID
In-Reply-To: <201210050337.12011.marex@denx.de>
References: <1348544455-17656-1-git-send-email-computersforpeace@gmail.com>
 <1348544455-17656-10-git-send-email-computersforpeace@gmail.com>
 <201210050337.12011.marex@denx.de>
Message-ID: <CAN8TOE-3s7o8KX1MJKSHdTog2-rsHtrvK=LXSpeO2XDfM8M6LA@mail.gmail.com>

Hi Marek,

On Thu, Oct 4, 2012 at 6:37 PM, Marek Vasut <marex at denx.de> wrote:
> This breaks my board with K9F2G08 part:
>
> [    0.860000] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND
> 256MiB 3,3V 8-bit), page size: 2048, OOB size: 64

Thanks for the report. I really appreciate the testing! Exactly which
part is this, and what is the full 8-byte ID? For instance, I can
reproduce this on K9F2G08U0B, with ID EC DA 10 95 44 00 EC DA.

>>
>> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
>> index 7e93d0d..bcb58ce 100644
>> --- a/drivers/mtd/nand/nand_base.c
>> +++ b/drivers/mtd/nand/nand_base.c
>> @@ -2939,19 +2939,18 @@ static void nand_decode_ext_id(struct mtd_info
>> *mtd, struct nand_chip *chip, /*
>>        * Field definitions are in the following datasheets:
>>        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
>> -      * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
>> +      * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
>>        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>>        *
>>        * Check for ID length, cell type, and Hynix/Samsung ID to decide what
>>        * to do.
>>        */
>> -     if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
>> -                     (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
>> +     if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
> [...]
>
> I believe the above hunk is wrong, reverting it fixes the problem.

Yeah, that is one fix. But my real issue is in the ID length, not SLC
vs. MLC. Its datasheet *says* it has a 5-byte ID, but it actually
wraps around at the 6-byte mark (i.e., EC DA 10 95 44 00 EC DA ...) so
its ID length appears as 6. Now, the above hunk is intentional, since
I found Samsung SLC NAND with 6-byte ID which follow this same
pattern. And I don't have any recorded Samsung 6-byte ID SLC who
*don't* follow this pattern. See the following doc, plus I have more
NAND data that should be updated here sometime:

http://www.linux-mtd.infradead.org/nand-data/nanddata.html

Anyway, according to my data, the problem is actually in this hunk in patch 6:

mtd: nand: add generic READ ID length calculation functions

-       if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
-                       id_data[0] == NAND_MFR_SAMSUNG &&
-                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                       id_data[5] != 0x00) {
+       if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {

Notice that I dropped the 'id_data[5] != 0x00' check. So I think if I
squash the following diff (probably mangled) into the series, this
solves your problems and mine. Can you test?

If it works, I'll probably resend this diff with a full, proper
explanation (and Tested-by credit), or else I can send a v2 of patches
6 and 9. (It's up to Artem, which form he'd rather maintain in his
tree.)

Thanks,
Brian

---
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec6841d..fa1ae76 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2989,7 +2989,8 @@ static void nand_decode_ext_id(struct mtd_info
*mtd, struct nand_chip *chip,
 	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
 	 * to do.
 	 */
-	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+			id_data[5] != 0x00) {
 		/* Calc pagesize */
 		mtd->writesize = 2048 << (extid & 0x03);
 		extid >>= 2;


From computersforpeace at gmail.com  Sat Oct  6 16:28:24 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Sat, 6 Oct 2012 13:28:24 -0700
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <1349347930-32422-1-git-send-email-richard@nod.at>
References: <1349347930-32422-1-git-send-email-richard@nod.at>
Message-ID: <CAN8TOE_BC6JGbrMcTYf5oMWnaAAx=LSh3V08vMnaGQVhkT-Yrw@mail.gmail.com>

On Thu, Oct 4, 2012 at 3:52 AM, Richard Weinberger <richard at nod.at> wrote:
> Add documentation on fastmap to mtd-www.
>
> Signed-off-by: Richard Weinberger <richard at nod.at>

Umm, this email looks like a resend of the exact same patch. Can you
send a proper v2? :)

Brian


From marex at denx.de  Sat Oct  6 23:29:51 2012
From: marex at denx.de (Marek Vasut)
Date: Sun, 7 Oct 2012 05:29:51 +0200
Subject: [PATCH 9/9] mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID
In-Reply-To: <CAN8TOE-3s7o8KX1MJKSHdTog2-rsHtrvK=LXSpeO2XDfM8M6LA@mail.gmail.com>
References: <1348544455-17656-1-git-send-email-computersforpeace@gmail.com>
 <201210050337.12011.marex@denx.de>
 <CAN8TOE-3s7o8KX1MJKSHdTog2-rsHtrvK=LXSpeO2XDfM8M6LA@mail.gmail.com>
Message-ID: <201210070529.51557.marex@denx.de>

Dear Brian Norris,

> Hi Marek,
> 
> On Thu, Oct 4, 2012 at 6:37 PM, Marek Vasut <marex at denx.de> wrote:
> > This breaks my board with K9F2G08 part:
> > 
> > [    0.860000] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung
> > NAND 256MiB 3,3V 8-bit), page size: 2048, OOB size: 64
> 
> Thanks for the report. I really appreciate the testing! Exactly which
> part is this, and what is the full 8-byte ID? For instance, I can
> reproduce this on K9F2G08U0B, with ID EC DA 10 95 44 00 EC DA.

Yep, that's it ...

ec da 10 95 44 00 ec da

> >> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> >> index 7e93d0d..bcb58ce 100644
> >> --- a/drivers/mtd/nand/nand_base.c
> >> +++ b/drivers/mtd/nand/nand_base.c
> >> @@ -2939,19 +2939,18 @@ static void nand_decode_ext_id(struct mtd_info
> >> *mtd, struct nand_chip *chip, /*
> >> 
> >>        * Field definitions are in the following datasheets:
> >>        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
> >> 
> >> -      * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
> >> +      * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
> >> 
> >>        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
> >>        *
> >>        * Check for ID length, cell type, and Hynix/Samsung ID to decide
> >>        what * to do.
> >>        */
> >> 
> >> -     if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
> >> -                     (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
> >> +     if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
> > 
> > [...]
> > 
> > I believe the above hunk is wrong, reverting it fixes the problem.
> 
> Yeah, that is one fix. But my real issue is in the ID length, not SLC
> vs. MLC. Its datasheet *says* it has a 5-byte ID, but it actually
> wraps around at the 6-byte mark (i.e., EC DA 10 95 44 00 EC DA ...) so
> its ID length appears as 6. Now, the above hunk is intentional, since
> I found Samsung SLC NAND with 6-byte ID which follow this same
> pattern. And I don't have any recorded Samsung 6-byte ID SLC who
> *don't* follow this pattern. See the following doc, plus I have more
> NAND data that should be updated here sometime:
> 
> http://www.linux-mtd.infradead.org/nand-data/nanddata.html

Nice!

> Anyway, according to my data, the problem is actually in this hunk in patch
> 6:
> 
> mtd: nand: add generic READ ID length calculation functions
> 
> -       if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
> -                       id_data[0] == NAND_MFR_SAMSUNG &&
> -                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
> -                       id_data[5] != 0x00) {
> +       if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
> +                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
> 
> Notice that I dropped the 'id_data[5] != 0x00' check. So I think if I
> squash the following diff (probably mangled) into the series, this
> solves your problems and mine. Can you test?

Yes, that's a good solution.

Tested-by: Marek Vasut <marex at denx.de>

> If it works, I'll probably resend this diff with a full, proper
> explanation (and Tested-by credit), or else I can send a v2 of patches
> 6 and 9. (It's up to Artem, which form he'd rather maintain in his
> tree.)
> 
> Thanks,
> Brian
> 
> ---
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index ec6841d..fa1ae76 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2989,7 +2989,8 @@ static void nand_decode_ext_id(struct mtd_info
> *mtd, struct nand_chip *chip,
>  	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
>  	 * to do.
>  	 */
> -	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
> +	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
> +			id_data[5] != 0x00) {
>  		/* Calc pagesize */
>  		mtd->writesize = 2048 << (extid & 0x03);
>  		extid >>= 2;


From plagnioj at jcrosoft.com  Sun Oct  7 15:49:59 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sun, 7 Oct 2012 21:49:59 +0200
Subject: [PATCH 2/2] mtd: delete nomadik_nand driver
In-Reply-To: <1349335729-13438-1-git-send-email-linus.walleij@linaro.org>
References: <1349335729-13438-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20121007194959.GF12801@game.jcrosoft.org>

On 09:28 Thu 04 Oct     , Linus Walleij wrote:
> The nomadik_nand driver is really just a subset of the FSMC
> NAND driver, and there are no users anymore so let's delete
> it.
> 
> Cc: Alessandro Rubini <rubini at unipv.it>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> I'm seeking the MTD maintainer(s) ACK for this patch so I can
> merge it through the ARM SoC tree just after switching the
> platform to using the FSMC driver.
I've test the fsmc driver on nomadik too

Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Best Regards,
J.


From b32955 at freescale.com  Sun Oct  7 22:45:48 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 8 Oct 2012 10:45:48 +0800
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <1348425062-17427-1-git-send-email-festevam@gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
Message-ID: <50723E5C.3020403@freescale.com>

? 2012?09?24? 02:31, Fabio Estevam ??:
> From: Fabio Estevam <fabio.estevam at freescale.com>
>
> On a mx28 board the following error happens since commit 638064e56c 
> (mtd: gpmi: change the code for clocks):
>
> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
>
> Acquire the clock using "NULL" as it was done previously, so that the driver
> can register on mx23/mx28 as well.
>
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index c46be6c..1f23cb4 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
>  	int i;
>  
>  	/* The main clock is stored in the first. */
> -	r->clock[0] = clk_get(this->dev, "gpmi_io");
> +	r->clock[0] = clk_get(this->dev, NULL);
Please do not change this line.

The gpmi_io is for mx6q.
If you replace it with `NULL`. The mx6q can not find the proper clock.

thanks
Huang Shijie
>  	if (IS_ERR(r->clock[0]))
>  		goto err_clock;
>  




From b32955 at freescale.com  Sun Oct  7 22:51:58 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 8 Oct 2012 10:51:58 +0800
Subject: i.MX6S/GPMI-NAND issue on 3.5.4
In-Reply-To: <505CB1ED.8010909@gmail.com>
References: <505CB1ED.8010909@gmail.com>
Message-ID: <50723FCE.4000708@freescale.com>

? 2012?09?22? 02:29, Vikram Narayanan ??:
> Hello,
>
> I'm facing some issue with GPMI-NAND driver on i.MX6 solo.
Does the MX6Q solo support the NAND?
I have the solo board in my hand. But it can not support the NAND.

You make the board yourself?
If so, please check the pinmux for solo.

thanks
Huang Shijie



> I've a TOSHIBA 4KiB page NAND connected to the GPMI.
> (4KiB + 128 bytes OOB)
>
> I tested it using the following,
>
> 1) U-boot v2012.04
> 2) Freescale's U-boot for i.MX6
> 3) Freescale's Kernel 3.0.15
> Result: 0x98 0xAC 0x90 0x26 (Correct)
>
> 4) Linux v3.5.4 stable
> Result: 0x98 0xA8 0x90 0x20 (Incorrect)
>
> When I issue a READID command, 1, 2 & 3 gives me correct results,
> whereas the 3.5.4 version gives me some different result.
>
> Any help would be very much appreciated.
>
> Regards,
> Vikram
>




From marex at denx.de  Sun Oct  7 23:15:19 2012
From: marex at denx.de (Marek Vasut)
Date: Mon, 8 Oct 2012 05:15:19 +0200
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <50723E5C.3020403@freescale.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <50723E5C.3020403@freescale.com>
Message-ID: <201210080515.19706.marex@denx.de>

Dear Huang Shijie,

> ? 2012?09?24? 02:31, Fabio Estevam ??:
> > From: Fabio Estevam <fabio.estevam at freescale.com>
> > 
> > On a mx28 board the following error happens since commit 638064e56c
> > (mtd: gpmi: change the code for clocks):
> > 
> > gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
> > 
> > Acquire the clock using "NULL" as it was done previously, so that the
> > driver can register on mx23/mx28 as well.
> > 
> > Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
> > ---
> > 
> >  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index c46be6c..1f23cb4 100644
> > --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> > @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct
> > gpmi_nand_data *this)
> > 
> >  	int i;
> >  	
> >  	/* The main clock is stored in the first. */
> > 
> > -	r->clock[0] = clk_get(this->dev, "gpmi_io");
> > +	r->clock[0] = clk_get(this->dev, NULL);
> 
> Please do not change this line.
> 
> The gpmi_io is for mx6q.
> If you replace it with `NULL`. The mx6q can not find the proper clock.

Suggestion is really welcome though, please :) This is a problem, GPMI NAND is 
broken on anything != mx6q. Huang, can you please also test the changes you do 
to GPMI NAND on mx28/mx23 so we can avoid this breakage in the future?

Best regards,
Marek Vasut


From festevam at gmail.com  Sun Oct  7 23:22:08 2012
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 8 Oct 2012 00:22:08 -0300
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <50723E5C.3020403@freescale.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <50723E5C.3020403@freescale.com>
Message-ID: <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>

On Sun, Oct 7, 2012 at 11:45 PM, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2012?09?24? 02:31, Fabio Estevam ??:
>> From: Fabio Estevam <fabio.estevam at freescale.com>
>>
>> On a mx28 board the following error happens since commit 638064e56c
>> (mtd: gpmi: change the code for clocks):
>>
>> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
>>
>> Acquire the clock using "NULL" as it was done previously, so that the driver
>> can register on mx23/mx28 as well.
>>
>> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
>> ---
>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> index c46be6c..1f23cb4 100644
>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
>>       int i;
>>
>>       /* The main clock is stored in the first. */
>> -     r->clock[0] = clk_get(this->dev, "gpmi_io");
>> +     r->clock[0] = clk_get(this->dev, NULL);
> Please do not change this line.
>
> The gpmi_io is for mx6q.
> If you replace it with `NULL`. The mx6q can not find the proper clock.

What about this?

index 42978f1b..7b1aded 100644
--- a/drivers/clk/mxs/clk-imx28.c
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -139,7 +139,7 @@ enum imx28_clk {
        ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
        emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
        clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
-       ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
+       ssp1, ssp2, ssp3, gpmi_io, spdif, emi, saif0, saif1, lcdif, etm,
        fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
        clk_max
 };
@@ -208,7 +208,7 @@ int __init mx28_clocks_init(void)
        clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
        clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
        clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
-       clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
+       clks[gpmi_io] = mxs_clk_gate("gpmi_io", "gpmi_div", GPMI, 31);
        clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
        clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
        clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);

Can you please test it on mx28?

Regards,

Fabio Estevam


From b32955 at freescale.com  Sun Oct  7 23:32:58 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 8 Oct 2012 11:32:58 +0800
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>	<50723E5C.3020403@freescale.com>
 <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
Message-ID: <5072496A.3040205@freescale.com>

? 2012?10?08? 11:22, Fabio Estevam ??:
> On Sun, Oct 7, 2012 at 11:45 PM, Huang Shijie <b32955 at freescale.com> wrote:
>> ? 2012?09?24? 02:31, Fabio Estevam ??:
>>> From: Fabio Estevam <fabio.estevam at freescale.com>
>>>
>>> On a mx28 board the following error happens since commit 638064e56c
>>> (mtd: gpmi: change the code for clocks):
>>>
>>> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
>>>
>>> Acquire the clock using "NULL" as it was done previously, so that the driver
>>> can register on mx23/mx28 as well.
>>>
>>> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
>>> ---
>>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> index c46be6c..1f23cb4 100644
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
>>>       int i;
>>>
>>>       /* The main clock is stored in the first. */
>>> -     r->clock[0] = clk_get(this->dev, "gpmi_io");
>>> +     r->clock[0] = clk_get(this->dev, NULL);
>> Please do not change this line.
>>
>> The gpmi_io is for mx6q.
>> If you replace it with `NULL`. The mx6q can not find the proper clock.
> What about this?
>
> index 42978f1b..7b1aded 100644
> --- a/drivers/clk/mxs/clk-imx28.c
> +++ b/drivers/clk/mxs/clk-imx28.c
> @@ -139,7 +139,7 @@ enum imx28_clk {
>         ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
>         emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
>         clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
> -       ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
> +       ssp1, ssp2, ssp3, gpmi_io, spdif, emi, saif0, saif1, lcdif, etm,
>         fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
>         clk_max
>  };
> @@ -208,7 +208,7 @@ int __init mx28_clocks_init(void)
>         clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
>         clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
>         clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
> -       clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
> +       clks[gpmi_io] = mxs_clk_gate("gpmi_io", "gpmi_div", GPMI, 31);
:)

This patch is really not needed.

The clk_get() can get the right clock in the mx23/mx28. I tested them.

Please read the code of clk_get().


BR
Huang Shijie


>         clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
>         clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
>         clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
>
> Can you please test it on mx28?
>
> Regards,
>
> Fabio Estevam
>




From b32955 at freescale.com  Sun Oct  7 23:34:09 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 8 Oct 2012 11:34:09 +0800
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <201210080515.19706.marex@denx.de>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <50723E5C.3020403@freescale.com> <201210080515.19706.marex@denx.de>
Message-ID: <507249B1.7040308@freescale.com>

? 2012?10?08? 11:15, Marek Vasut ??:
> Dear Huang Shijie,
>
>> ? 2012?09?24? 02:31, Fabio Estevam ??:
>>> From: Fabio Estevam <fabio.estevam at freescale.com>
>>>
>>> On a mx28 board the following error happens since commit 638064e56c
>>> (mtd: gpmi: change the code for clocks):
>>>
>>> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
>>>
>>> Acquire the clock using "NULL" as it was done previously, so that the
>>> driver can register on mx23/mx28 as well.
>>>
>>> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
>>> ---
>>>
>>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index c46be6c..1f23cb4 100644
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct
>>> gpmi_nand_data *this)
>>>
>>>  	int i;
>>>  	
>>>  	/* The main clock is stored in the first. */
>>>
>>> -	r->clock[0] = clk_get(this->dev, "gpmi_io");
>>> +	r->clock[0] = clk_get(this->dev, NULL);
>> Please do not change this line.
>>
>> The gpmi_io is for mx6q.
>> If you replace it with `NULL`. The mx6q can not find the proper clock.
> Suggestion is really welcome though, please :) This is a problem, GPMI NAND is 
> broken on anything != mx6q. Huang, can you please also test the changes you do 
> to GPMI NAND on mx28/mx23 so we can avoid this breakage in the future?
yes. I tested in the mx23/mx28. It's ok, do not worry.

BR
Huang Shijie
> Best regards,
> Marek Vasut
>




From festevam at gmail.com  Sun Oct  7 23:31:50 2012
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 8 Oct 2012 00:31:50 -0300
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <5072496A.3040205@freescale.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <50723E5C.3020403@freescale.com>
 <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
 <5072496A.3040205@freescale.com>
Message-ID: <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>

On Mon, Oct 8, 2012 at 12:32 AM, Huang Shijie <b32955 at freescale.com> wrote:
>
> This patch is really not needed.
>
> The clk_get() can get the right clock in the mx23/mx28. I tested them.

Please test it on linux-next.

gpmi nand can not event be probed.

Regards,

Fabio Estevam


From marex at denx.de  Sun Oct  7 23:37:04 2012
From: marex at denx.de (Marek Vasut)
Date: Mon, 8 Oct 2012 05:37:04 +0200
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <507249B1.7040308@freescale.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <201210080515.19706.marex@denx.de> <507249B1.7040308@freescale.com>
Message-ID: <201210080537.04912.marex@denx.de>

Dear Huang Shijie,

> ? 2012?10?08? 11:15, Marek Vasut ??:
> > Dear Huang Shijie,
> > 
> >> ? 2012?09?24? 02:31, Fabio Estevam ??:
> >>> From: Fabio Estevam <fabio.estevam at freescale.com>
> >>> 
> >>> On a mx28 board the following error happens since commit 638064e56c
> >>> (mtd: gpmi: change the code for clocks):
> >>> 
> >>> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
> >>> 
> >>> Acquire the clock using "NULL" as it was done previously, so that the
> >>> driver can register on mx23/mx28 as well.
> >>> 
> >>> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
> >>> ---
> >>> 
> >>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>> 
> >>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> >>> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index c46be6c..1f23cb4 100644
> >>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> >>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> >>> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct
> >>> gpmi_nand_data *this)
> >>> 
> >>>  	int i;
> >>>  	
> >>>  	/* The main clock is stored in the first. */
> >>> 
> >>> -	r->clock[0] = clk_get(this->dev, "gpmi_io");
> >>> +	r->clock[0] = clk_get(this->dev, NULL);
> >> 
> >> Please do not change this line.
> >> 
> >> The gpmi_io is for mx6q.
> >> If you replace it with `NULL`. The mx6q can not find the proper clock.
> > 
> > Suggestion is really welcome though, please :) This is a problem, GPMI
> > NAND is broken on anything != mx6q. Huang, can you please also test the
> > changes you do to GPMI NAND on mx28/mx23 so we can avoid this breakage
> > in the future?
> 
> yes. I tested in the mx23/mx28. It's ok, do not worry.

I won't be posting here that it's broken in the first place if it was ok ;-)

Give it one more go with latest -next ...

Best regards,
Marek Vasut


From festevam at gmail.com  Sun Oct  7 23:46:20 2012
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 8 Oct 2012 00:46:20 -0300
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <50723E5C.3020403@freescale.com>
 <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
 <5072496A.3040205@freescale.com>
 <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>
Message-ID: <CAOMZO5CYgDi3Rj7gKJAr-nMrUSec4YAxLCkPPf-amA6nXP7_EA@mail.gmail.com>

On Mon, Oct 8, 2012 at 12:31 AM, Fabio Estevam <festevam at gmail.com> wrote:
> On Mon, Oct 8, 2012 at 12:32 AM, Huang Shijie <b32955 at freescale.com> wrote:
>>
>> This patch is really not needed.
>>
>> The clk_get() can get the right clock in the mx23/mx28. I tested them.
>
> Please test it on linux-next.
>
> gpmi nand can not event be probed.

What about this?

--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -495,7 +495,11 @@ static int __devinit gpmi_get_clks(struct
gpmi_nand_data *this)
        int i;

        /* The main clock is stored in the first. */
-       r->clock[0] = clk_get(this->dev, "gpmi_io");
+       if (GPMI_IS_MX6Q(this))
+               r->clock[0] = clk_get(this->dev, "gpmi_io");
+       else
+               r->clock[0] = clk_get(this->dev, NULL);
+
        if (IS_ERR(r->clock[0]))
                goto err_clock;


From marex at denx.de  Sun Oct  7 23:52:20 2012
From: marex at denx.de (Marek Vasut)
Date: Mon, 8 Oct 2012 05:52:20 +0200
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <CAOMZO5CYgDi3Rj7gKJAr-nMrUSec4YAxLCkPPf-amA6nXP7_EA@mail.gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>
 <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>
 <CAOMZO5CYgDi3Rj7gKJAr-nMrUSec4YAxLCkPPf-amA6nXP7_EA@mail.gmail.com>
Message-ID: <201210080552.20661.marex@denx.de>

Dear Fabio Estevam,

> On Mon, Oct 8, 2012 at 12:31 AM, Fabio Estevam <festevam at gmail.com> wrote:
> > On Mon, Oct 8, 2012 at 12:32 AM, Huang Shijie <b32955 at freescale.com> wrote:
> >> This patch is really not needed.
> >> 
> >> The clk_get() can get the right clock in the mx23/mx28. I tested them.
> > 
> > Please test it on linux-next.
> > 
> > gpmi nand can not event be probed.
> 
> What about this?

I don't like this one ... such condition shouldn't be in the driver.

> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -495,7 +495,11 @@ static int __devinit gpmi_get_clks(struct
> gpmi_nand_data *this)
>         int i;
> 
>         /* The main clock is stored in the first. */
> -       r->clock[0] = clk_get(this->dev, "gpmi_io");
> +       if (GPMI_IS_MX6Q(this))
> +               r->clock[0] = clk_get(this->dev, "gpmi_io");
> +       else
> +               r->clock[0] = clk_get(this->dev, NULL);
> +
>         if (IS_ERR(r->clock[0]))
>                 goto err_clock;

Best regards,
Marek Vasut


From josh.wu at atmel.com  Sun Oct  7 23:54:04 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Mon, 08 Oct 2012 11:54:04 +0800
Subject: MTD in mainline status
Message-ID: <50724E5C.1010809@atmel.com>

Hi,

Just a little reminder: it would be good time to send out the pull 
request to mainline for MTD in current merge window :-)

Best Regards,
Josh Wu


From festevam at gmail.com  Mon Oct  8 00:02:06 2012
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 8 Oct 2012 01:02:06 -0300
Subject: i.MX6S/GPMI-NAND issue on 3.5.4
In-Reply-To: <505CB1ED.8010909@gmail.com>
References: <505CB1ED.8010909@gmail.com>
Message-ID: <CAOMZO5Cwgd8WMKyQ64gsKFAbCnCHy4f6ytoOGTzU34h7xPJaVA@mail.gmail.com>

Hi Vikram,

On Fri, Sep 21, 2012 at 3:29 PM, Vikram Narayanan <vikram186 at gmail.com> wrote:
> Hello,
>
> I'm facing some issue with GPMI-NAND driver on i.MX6 solo.
> I've a TOSHIBA 4KiB page NAND connected to the GPMI.
> (4KiB + 128 bytes OOB)

Can you please post your mx6sl dts patches? This would help us to
identify the problem.

Regards,

Fabio Estevam


From vipin.kumar at st.com  Mon Oct  8 00:08:35 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Mon, 8 Oct 2012 09:38:35 +0530
Subject: [PATCH 1/1] mtd: st fsmc_nand: pass the ale and cmd resource
 via resource
In-Reply-To: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
References: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <507251C3.7020506@st.com>

On 10/4/2012 6:44 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Do not use the platform_data to pass resource and be smart in the drivers.
> Just pass it via resource
>
> Switch to devm_request_and_ioremap at the sametime
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD<plagnioj at jcrosoft.com>
> Cc: Linus Walleij<linus.walleij at linaro.org>
> Cc: Vipin Kumar<vipin.kumar at st.com>
> Cc: linux-mtd at lists.infradead.org
> ---
>   .../devicetree/bindings/mtd/fsmc-nand.txt          |   12 +++---
>   arch/arm/boot/dts/spear13xx.dtsi                   |   10 ++---
>   arch/arm/boot/dts/spear300.dtsi                    |    8 ++--
>   arch/arm/boot/dts/spear310.dtsi                    |    8 ++--
>   arch/arm/boot/dts/spear320.dtsi                    |    8 ++--
>   arch/arm/boot/dts/spear600.dtsi                    |    8 ++--
>   arch/arm/mach-u300/core.c                          |   14 ++++++-
>   drivers/mtd/nand/fsmc_nand.c                       |   44 +++++---------------
>   include/linux/mtd/fsmc.h                           |    3 --
>   9 files changed, 49 insertions(+), 66 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index e2c663b..e3ea32e 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -3,9 +3,7 @@
>   Required properties:
>   - compatible : "st,spear600-fsmc-nand"
>   - reg : Address range of the mtd chip
> -- reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
> -- st,ale-off : Chip specific offset to ALE
> -- st,cle-off : Chip specific offset to CLE
> +- reg-names: Should contain the reg names "fsmc_regs", "nand_data", "nand_addr" and "nand_cmd"
>
>   Optional properties:
>   - bank-width : Width (in bytes) of the device.  If not present, the width
> @@ -19,10 +17,10 @@ Example:
>   		#address-cells =<1>;
>   		#size-cells =<1>;
>   		reg =<0xd1800000 0x1000	/* FSMC Register */
> -		       0xd2000000 0x4000>;	/* NAND Base */
> -		reg-names = "fsmc_regs", "nand_data";
> -		st,ale-off =<0x20000>;
> -		st,cle-off =<0x10000>;
> +		       0xd2000000 0x0010	/* NAND Base DATA */
> +		       0xd2020000 0x0010	/* NAND Base ADDR */
> +		       0xd2010000 0x0010>;	/* NAND Base CMD */
> +		reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>
>   		bank-width =<1>;
>   		nand-skip-bbtscan;
> diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
> index f7b84ac..14a6d15 100644
> --- a/arch/arm/boot/dts/spear13xx.dtsi
> +++ b/arch/arm/boot/dts/spear13xx.dtsi
> @@ -104,15 +104,15 @@
>   			compatible = "st,spear600-fsmc-nand";
>   			#address-cells =<1>;
>   			#size-cells =<1>;
> -			reg =<0xb0000000 0x1000	/* FSMC Register */
> -			       0xb0800000 0x0010>;	/* NAND Base */
> -			reg-names = "fsmc_regs", "nand_data";
> +			reg =<0xb0000000 0x1000	/* FSMC Register*/
> +			       0xb0800000 0x0010	/* NAND Base DATA */
> +			       0xb0820000 0x0010	/* NAND Base ADDR */
> +			       0xb0810000 0x0010>;	/* NAND Base CMD */
> +			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>   			interrupts =<0 20 0x4
>   				      0 21 0x4
>   				      0 22 0x4
>   				      0 23 0x4>;
> -			st,ale-off =<0x20000>;
> -			st,cle-off =<0x10000>;
>   			status = "disabled";
>   		};
>
> diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
> index ed3627c..bc43638 100644
> --- a/arch/arm/boot/dts/spear300.dtsi
> +++ b/arch/arm/boot/dts/spear300.dtsi
> @@ -38,10 +38,10 @@
>   			#address-cells =<1>;
>   			#size-cells =<1>;
>   			reg =<0x94000000 0x1000	/* FSMC Register */
> -			       0x80000000 0x0010>;	/* NAND Base */
> -			reg-names = "fsmc_regs", "nand_data";
> -			st,ale-off =<0x20000>;
> -			st,cle-off =<0x10000>;
> +			       0x80000000 0x0010	/* NAND Base DATA */
> +			       0x80020000 0x0010	/* NAND Base ADDR */
> +			       0x80010000 0x0010>;	/* NAND Base CMD */
> +			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>   			status = "disabled";
>   		};
>
> diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
> index 62fc4fb..7840e52 100644
> --- a/arch/arm/boot/dts/spear310.dtsi
> +++ b/arch/arm/boot/dts/spear310.dtsi
> @@ -32,10 +32,10 @@
>   			#address-cells =<1>;
>   			#size-cells =<1>;
>   			reg =<0x44000000 0x1000	/* FSMC Register */
> -			       0x40000000 0x0010>;	/* NAND Base */
> -			reg-names = "fsmc_regs", "nand_data";
> -			st,ale-off =<0x10000>;
> -			st,cle-off =<0x20000>;
> +			       0x40000000 0x0010	/* NAND Base DATA */
> +			       0x40020000 0x0010	/* NAND Base ADDR */
> +			       0x40010000 0x0010>;	/* NAND Base CMD */
> +			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>   			status = "disabled";
>   		};
>
> diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
> index 1f49d69..5ad8206 100644
> --- a/arch/arm/boot/dts/spear320.dtsi
> +++ b/arch/arm/boot/dts/spear320.dtsi
> @@ -38,10 +38,10 @@
>   			#address-cells =<1>;
>   			#size-cells =<1>;
>   			reg =<0x4c000000 0x1000	/* FSMC Register */
> -			       0x50000000 0x0010>;	/* NAND Base */
> -			reg-names = "fsmc_regs", "nand_data";
> -			st,ale-off =<0x20000>;
> -			st,cle-off =<0x10000>;
> +			       0x50000000 0x0010	/* NAND Base DATA */
> +			       0x50020000 0x0010	/* NAND Base ADDR */
> +			       0x50010000 0x0010>;	/* NAND Base CMD */
> +			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>   			status = "disabled";
>   		};
>
> diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
> index a3c36e4..4ecc66f 100644
> --- a/arch/arm/boot/dts/spear600.dtsi
> +++ b/arch/arm/boot/dts/spear600.dtsi
> @@ -67,10 +67,10 @@
>   			#address-cells =<1>;
>   			#size-cells =<1>;
>   			reg =<0xd1800000 0x1000	/* FSMC Register */
> -			       0xd2000000 0x4000>;	/* NAND Base */
> -			reg-names = "fsmc_regs", "nand_data";
> -			st,ale-off =<0x20000>;
> -			st,cle-off =<0x10000>;
> +			       0xd2000000 0x0010	/* NAND Base DATA */
> +			       0xd2020000 0x0010	/* NAND Base ADDR */
> +			       0xd2010000 0x0010>;	/* NAND Base CMD */
> +			reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
>   			status = "disabled";
>   		};
>
> diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
> index ef6f602..527bcc2 100644
> --- a/arch/arm/mach-u300/core.c
> +++ b/arch/arm/mach-u300/core.c
> @@ -252,6 +252,18 @@ static struct resource rtc_resources[] = {
>    */
>   static struct resource fsmc_resources[] = {
>   	{
> +		.name  = "nand_addr",
> +		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
> +		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	{
> +		.name  = "nand_cmd",
> +		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
> +		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
> +		.flags = IORESOURCE_MEM,
> +	},
> +	{
>   		.name  = "nand_data",
>   		.start = U300_NAND_CS0_PHYS_BASE,
>   		.end   = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
> @@ -1496,8 +1508,6 @@ static struct fsmc_nand_platform_data nand_platform_data = {
>   	.nr_partitions = ARRAY_SIZE(u300_partitions),
>   	.options = NAND_SKIP_BBTSCAN,
>   	.width = FSMC_NAND_BW8,
> -	.ale_off = PLAT_NAND_ALE,
> -	.cle_off = PLAT_NAND_CLE,
>   };
>
>   static struct platform_device nand_device = {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index 38d2624..cb86450 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -876,8 +876,6 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>   			return -EINVAL;
>   		}
>   	}
> -	of_property_read_u32(np, "st,ale-off",&pdata->ale_off);
> -	of_property_read_u32(np, "st,cle-off",&pdata->cle_off);
>   	if (of_get_property(np, "nand-skip-bbtscan", NULL))
>   		pdata->options = NAND_SKIP_BBTSCAN;
>
> @@ -935,41 +933,28 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>   	if (!res)
>   		return -EINVAL;
>
> -	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
> -				pdev->name)) {
> -		dev_err(&pdev->dev, "Failed to get memory data resourse\n");
> -		return -ENOENT;
> -	}
> -
> -	host->data_pa = (dma_addr_t)res->start;
> -	host->data_va = devm_ioremap(&pdev->dev, res->start,
> -			resource_size(res));
> +	host->data_va = devm_request_and_ioremap(&pdev->dev, res);
>   	if (!host->data_va) {
>   		dev_err(&pdev->dev, "data ioremap failed\n");
>   		return -ENOMEM;
>   	}
> +	host->data_pa = (dma_addr_t)res->start;
>
> -	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off,
> -			resource_size(res), pdev->name)) {
> -		dev_err(&pdev->dev, "Failed to get memory ale resourse\n");
> -		return -ENOENT;
> -	}
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
> +	if (!res)
> +		return -EINVAL;
>
> -	host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off,
> -			resource_size(res));
> +	host->addr_va = devm_request_and_ioremap(&pdev->dev, res);
>   	if (!host->addr_va) {
>   		dev_err(&pdev->dev, "ale ioremap failed\n");
>   		return -ENOMEM;
>   	}
>
> -	if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off,
> -			resource_size(res), pdev->name)) {
> -		dev_err(&pdev->dev, "Failed to get memory cle resourse\n");
> -		return -ENOENT;
> -	}
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
> +	if (!res)
> +		return -EINVAL;
>
> -	host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off,
> -			resource_size(res));
> +	host->cmd_va = devm_request_and_ioremap(&pdev->dev, res);
>   	if (!host->cmd_va) {
>   		dev_err(&pdev->dev, "ale ioremap failed\n");
>   		return -ENOMEM;
> @@ -979,14 +964,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>   	if (!res)
>   		return -EINVAL;
>
> -	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
> -			pdev->name)) {
> -		dev_err(&pdev->dev, "Failed to get memory regs resourse\n");
> -		return -ENOENT;
> -	}
> -
> -	host->regs_va = devm_ioremap(&pdev->dev, res->start,
> -			resource_size(res));
> +	host->regs_va = devm_request_and_ioremap(&pdev->dev, res);
>   	if (!host->regs_va) {
>   		dev_err(&pdev->dev, "regs ioremap failed\n");
>   		return -ENOMEM;
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index b200292..d6ed61e 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -155,9 +155,6 @@ struct fsmc_nand_platform_data {
>   	unsigned int		width;
>   	unsigned int		bank;
>
> -	/* CLE, ALE offsets */
> -	unsigned int		cle_off;
> -	unsigned int		ale_off;
>   	enum access_mode	mode;
>
>   	void			(*select_bank)(uint32_t bank, uint32_t busw);

btw, I also have a few pending patches on this driver which I would be 
sending soon

Reviewed By: Vipin Kumar <vipin.kumar at st.com>


From b32955 at freescale.com  Mon Oct  8 00:53:20 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 8 Oct 2012 12:53:20 +0800
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>	<50723E5C.3020403@freescale.com>	<CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>	<5072496A.3040205@freescale.com>
 <CAOMZO5B4c+qaKrz2skB_vGCRBW-9mUhhOaCUtiEqtv36V8i5eQ@mail.gmail.com>
Message-ID: <50725C40.6060102@freescale.com>

? 2012?10?08? 11:31, Fabio Estevam ??:
> On Mon, Oct 8, 2012 at 12:32 AM, Huang Shijie<b32955 at freescale.com>  wrote:
>> This patch is really not needed.
>>
>> The clk_get() can get the right clock in the mx23/mx28. I tested them.
> Please test it on linux-next.
>
> gpmi nand can not event be probed.
ok.

I will test the linux-next as soon as possible.


BR
Huang Shijie
> Regards,
>
> Fabio Estevam
>




From afzal at ti.com  Mon Oct  8 01:35:56 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:05:56 +0530
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
Message-ID: <cover.1349672877.git.afzal@ti.com>

Hi,

This version(v2) of gpmc related cleanup for common zImage compared to
initial version, resolves build error upon selecting BCH CONFIG option.
Also a trivial patch on gpmc header removal from nand driver has been
squashed with patch that removes nand driver dependency on gpmc header
file.

This series cleans up omap-gpmc related code so that omap can
be a part of common zImage.

This series moves gpmc.h from plat-omap/include/plat to mach-omap2
so that header file is local.

Patches 1-4 qualifies as -rc material.

Patch 1 is an already posted one, has been pulled into this series.

Patches 5-6 removes necessity of cpu.h from onenand driver based
on Tony's suggestion.

Patches 7 & 8 cleans up the already moved platform data header files
to contain only platform data. Also gpmc-nand information is moved
to nand platform data header.

Patches 9-13 makes nand driver independent of gpmc header file

And the final patch localizes gpmc header.

This has been tested on omap3evm.

This series is available
        @ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-czimage-v2
and is based on
        linux-next (next-20121005)
and is dependent on
	http://marc.info/?l=linux-omap&m=134945131602622&w=2

Regards
Afzal


Afzal Mohammed (14):
  ARM: OMAP2+: gpmc: annotate exit sections properly
  mtd: onenand: omap: cleanup gpmc dependency
  mtd: nand: omap: free region as per resource size
  mtd: nand: omap: read nand using register address
  ARM: OMAP2+: onenand: connected soc info in pdata
  mtd: onenand: omap: use pdata info instead of cpu_is
  ARM: OMAP2+: onenand: header cleanup
  ARM: OMAP2+: nand: header cleanup
  mtd: nand: omap: bring in gpmc nand macros
  ARM: OMAP2+: nand: bch capability check
  ARM: OMAP2+: gpmc: nand register helper bch update
  mtd: nand: omap: handle gpmc bch[48]
  ARM: OMAP2+: gpmc: remove exported nand functions
  ARM: OMAP2+: gpmc: localize gpmc header

 arch/arm/mach-omap2/board-2430sdp.c             |   2 +-
 arch/arm/mach-omap2/board-3430sdp.c             |   2 +-
 arch/arm/mach-omap2/board-apollon.c             |   2 +-
 arch/arm/mach-omap2/board-cm-t35.c              |   5 +-
 arch/arm/mach-omap2/board-cm-t3517.c            |   5 +-
 arch/arm/mach-omap2/board-devkit8000.c          |   2 +-
 arch/arm/mach-omap2/board-flash.c               |   7 +-
 arch/arm/mach-omap2/board-flash.h               |   2 +-
 arch/arm/mach-omap2/board-h4.c                  |   2 +-
 arch/arm/mach-omap2/board-igep0020.c            |   3 +-
 arch/arm/mach-omap2/board-ldp.c                 |   2 +-
 arch/arm/mach-omap2/board-n8x0.c                |   1 +
 arch/arm/mach-omap2/board-omap3beagle.c         |   2 +-
 arch/arm/mach-omap2/board-omap3logic.c          |   2 +-
 arch/arm/mach-omap2/board-omap3pandora.c        |   3 +-
 arch/arm/mach-omap2/board-omap3stalker.c        |   2 +-
 arch/arm/mach-omap2/board-omap3touchbook.c      |   2 +-
 arch/arm/mach-omap2/board-overo.c               |   2 +-
 arch/arm/mach-omap2/board-rm680.c               |   3 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c    |   3 +-
 arch/arm/mach-omap2/board-rx51.c                |   2 +-
 arch/arm/mach-omap2/board-zoom-debugboard.c     |   2 +-
 arch/arm/mach-omap2/common-board-devices.c      |   1 -
 arch/arm/mach-omap2/gpmc-nand.c                 |  81 +++--
 arch/arm/mach-omap2/gpmc-nand.h                 |  27 ++
 arch/arm/mach-omap2/gpmc-onenand.c              |   9 +-
 arch/arm/mach-omap2/gpmc-onenand.h              |  24 ++
 arch/arm/mach-omap2/gpmc-smc91x.c               |   2 +-
 arch/arm/mach-omap2/gpmc-smsc911x.c             |   2 +-
 arch/arm/mach-omap2/gpmc.c                      | 459 ++----------------------
 arch/arm/mach-omap2/gpmc.h                      | 154 ++++++++
 arch/arm/mach-omap2/pm34xx.c                    |   2 +-
 arch/arm/mach-omap2/usb-tusb6010.c              |   2 +-
 arch/arm/plat-omap/include/plat/gpmc.h          | 209 -----------
 drivers/mtd/nand/omap2.c                        | 125 +++++--
 drivers/mtd/onenand/omap2.c                     |   9 +-
 include/linux/platform_data/mtd-nand-omap2.h    |  46 ++-
 include/linux/platform_data/mtd-onenand-omap2.h |  20 +-
 38 files changed, 472 insertions(+), 758 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-nand.h
 create mode 100644 arch/arm/mach-omap2/gpmc-onenand.h
 create mode 100644 arch/arm/mach-omap2/gpmc.h
 delete mode 100644 arch/arm/plat-omap/include/plat/gpmc.h

-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:36:43 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:06:43 +0530
Subject: [PATCH v2 01/14] ARM: OMAP2+: gpmc: annotate exit sections properly
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <a517afd9ed3be069b475caae791156b9c4663849.1349672877.git.afzal@ti.com>

compiler complained,
`gpmc_remove' referenced in section `.data' of arch/arm/mach-omap2/built-in.o: defined in discarded section `.exit.text' of arch/arm/mach-omap2/built-in.o

Annotate gpmc_remove function and dependents with __devexit.

Reported-by: Tony Lindgren <tony at atomide.com>
Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 2cbdcb9..163458d 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -886,7 +886,7 @@ static int gpmc_setup_irq(void)
 	return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
 }
 
-static __exit int gpmc_free_irq(void)
+static __devexit int gpmc_free_irq(void)
 {
 	int i;
 
@@ -992,7 +992,7 @@ static __devinit int gpmc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static __exit int gpmc_remove(struct platform_device *pdev)
+static __devexit int gpmc_remove(struct platform_device *pdev)
 {
 	gpmc_free_irq();
 	gpmc_mem_exit();
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:36:50 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:06:50 +0530
Subject: [PATCH v2 02/14] mtd: onenand: omap: cleanup gpmc dependency
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <77643c064b9d0d639f75f793130bb40768b015e1.1349672877.git.afzal@ti.com>

requesting, freeing gpmc cs is now handled fully
by gpmc, remove left out gpmc dependency as well
as unnecessary include of gpmc.h

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/onenand/omap2.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 1961be9..d7ef2c9 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -38,7 +38,6 @@
 #include <linux/regulator/consumer.h>
 
 #include <asm/mach/flash.h>
-#include <plat/gpmc.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 #include <asm/gpio.h>
 
@@ -803,7 +802,6 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
 	}
 	iounmap(c->onenand.base);
 	release_mem_region(c->phys_base, c->mem_size);
-	gpmc_cs_free(c->gpmc_cs);
 	kfree(c);
 
 	return 0;
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:36:56 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:06:56 +0530
Subject: [PATCH v2 03/14] mtd: nand: omap: free region as per resource size
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <011a0d90343de9204cfd977381b36cace032482b.1349672877.git.afzal@ti.com>

memory as is now obtained via resource, upon freeing use
resource size. This also helps get rid of one macro.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..4c33135 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1513,7 +1513,7 @@ static int omap_nand_remove(struct platform_device *pdev)
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
-	release_mem_region(info->phys_base, NAND_IO_SIZE);
+	release_mem_region(info->phys_base, info->mem_size);
 	kfree(info);
 	return 0;
 }
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:03 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:03 +0530
Subject: [PATCH v2 04/14] mtd: nand: omap: read nand using register address
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <571607de9b49c4d44a03e793a9b36654e5ff4570.1349672877.git.afzal@ti.com>

Now that gpmc-nand registers are available in driver, use it
to read nand data.

"65b97cf  mtd: nand: omap2: handle nand on gpmc" modified all
other instances. After initial versions of that patch, a new
change added reading nand data using gpmc exposed function.
In the final version this change was not taken care.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4c33135..abfc602 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -996,7 +996,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 		cond_resched();
 	}
 
-	status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA);
+	status = readb(info->reg.gpmc_nand_data);
 	return status;
 }
 
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:11 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:11 +0530
Subject: [PATCH v2 05/14] ARM: OMAP2+: onenand: connected soc info in pdata
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <6065bed749924f28a3d268145d1b7c980a3c97eb.1349672877.git.afzal@ti.com>

onenand driver needs to know whether soc is falling under
34xx family to properly handle onenand. But driver is not
supposed to do cpu_is_* check, hence educate platform data
with this information. Driver can make use of it to avoid
cpu_is_* check.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc-onenand.c              | 5 +++++
 include/linux/platform_data/mtd-onenand-omap2.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 544d501..f0b677a 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -409,6 +409,11 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
 		gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
 	}
 
+	if (cpu_is_omap34xx())
+		gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
+	else
+		gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
+
 	err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
 				(unsigned long *)&gpmc_onenand_resource.start);
 	if (err < 0) {
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
index 21bb0ff..ef9c60d 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -14,6 +14,7 @@
 
 #define ONENAND_SYNC_READ	(1 << 0)
 #define ONENAND_SYNC_READWRITE	(1 << 1)
+#define	ONENAND_IN_OMAP34XX	(1 << 2)
 
 struct omap_onenand_platform_data {
 	int			cs;
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:21 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:21 +0530
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of cpu_is
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>

platform data now contains a field to indicate whether
soc belongs to omap34xx family, use it instead of
cpu_is_* check.

This helps in removing dependency of platform specific
header file - cpu.h

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/onenand/omap2.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d7ef2c9..959f465 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -42,7 +42,6 @@
 #include <asm/gpio.h>
 
 #include <plat/dma.h>
-#include <plat/cpu.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -62,6 +61,7 @@ struct omap2_onenand {
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
 	struct regulator *regulator;
+	u8 flags;
 };
 
 static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
@@ -154,7 +154,7 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
 			syscfg |= ONENAND_SYS_CFG1_IOBE;
 			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
-			if (cpu_is_omap34xx())
+			if (c->flags & ONENAND_IN_OMAP34XX)
 				/* Add a delay to let GPIO settle */
 				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
 		}
@@ -638,6 +638,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
+	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
 	c->dma_channel = pdata->dma_channel;
@@ -728,7 +729,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
 	this = &c->onenand;
 	if (c->dma_channel >= 0) {
 		this->wait = omap2_onenand_wait;
-		if (cpu_is_omap34xx()) {
+		if (c->flags & ONENAND_IN_OMAP34XX) {
 			this->read_bufferram = omap3_onenand_read_bufferram;
 			this->write_bufferram = omap3_onenand_write_bufferram;
 		} else {
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:28 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:28 +0530
Subject: [PATCH v2 07/14] ARM: OMAP2+: onenand: header cleanup
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <4a5b5b27c74ef2a18dfcea7102104924812946b3.1349672877.git.afzal@ti.com>

For common arm zImage existing onenand header file
in platform specific location was moved to generic
platform data location, but it contained more than
platform data, remove it. New local header has been
created for exposing functions.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-flash.c               |  1 +
 arch/arm/mach-omap2/board-igep0020.c            |  1 +
 arch/arm/mach-omap2/board-n8x0.c                |  1 +
 arch/arm/mach-omap2/board-rm680.c               |  1 +
 arch/arm/mach-omap2/board-rx51-peripherals.c    |  1 +
 arch/arm/mach-omap2/gpmc-onenand.c              |  1 +
 arch/arm/mach-omap2/gpmc-onenand.h              | 24 ++++++++++++++++++++++++
 include/linux/platform_data/mtd-onenand-omap2.h | 19 +++----------------
 8 files changed, 33 insertions(+), 16 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-onenand.h

diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index f8b30cb..de68fdf 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -25,6 +25,7 @@
 
 #include "common.h"
 #include "board-flash.h"
+#include "gpmc-onenand.h"
 
 #define REG_FPGA_REV			0x10
 #define REG_FPGA_DIP_SWITCH_INPUT2	0x60
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index f6b3ed0..83c6efa 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -43,6 +43,7 @@
 #include "common-board-devices.h"
 #include "board-flash.h"
 #include "control.h"
+#include "gpmc-onenand.h"
 
 #define IGEP2_SMSC911X_CS       5
 #define IGEP2_SMSC911X_GPIO     176
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index d95f727..92b1916 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -32,6 +32,7 @@
 #include <plat/mmc.h>
 
 #include "mux.h"
+#include "gpmc-onenand.h"
 
 #define TUSB6010_ASYNC_CS	1
 #define TUSB6010_SYNC_CS	4
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 45997bf..154cf33 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -33,6 +33,7 @@
 #include "hsmmc.h"
 #include "sdram-nokia.h"
 #include "common-board-devices.h"
+#include "gpmc-onenand.h"
 
 static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ed85fb8..aa6a2a4 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -54,6 +54,7 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-onenand.h"
 
 #define SYSTEM_REV_B_USES_VAUX3	0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index f0b677a..29671cc 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -23,6 +23,7 @@
 #include <plat/gpmc.h>
 
 #include "soc.h"
+#include "gpmc-onenand.h"
 
 #define	ONENAND_IO_SIZE	SZ_128K
 
diff --git a/arch/arm/mach-omap2/gpmc-onenand.h b/arch/arm/mach-omap2/gpmc-onenand.h
new file mode 100644
index 0000000..216f23a
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.h
@@ -0,0 +1,24 @@
+/*
+ *  arch/arm/mach-omap2/gpmc-onenand.h
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef	__OMAP2_GPMC_ONENAND_H
+#define	__OMAP2_GPMC_ONENAND_H
+
+#include <linux/platform_data/mtd-onenand-omap2.h>
+
+#if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2)
+extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+#else
+#define board_onenand_data	NULL
+static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+{
+}
+#endif
+
+#endif
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
index ef9c60d..685af7e 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -9,6 +9,9 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef	__MTD_ONENAND_OMAP2_H
+#define	__MTD_ONENAND_OMAP2_H
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
@@ -27,20 +30,4 @@ struct omap_onenand_platform_data {
 	u8			regulator_can_sleep;
 	u8			skip_initial_unlocking;
 };
-
-#define ONENAND_MAX_PARTITIONS 8
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
-
-extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
-
-#else
-
-#define board_onenand_data	NULL
-
-static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
-{
-}
-
 #endif
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:34 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:34 +0530
Subject: [PATCH v2 08/14] ARM: OMAP2+: nand: header cleanup
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <54e9d6980d2159855b18fcbec3795c669bd51dce.1349672877.git.afzal@ti.com>

For common arm zImage existing nand header file
in platform specific location was moved to generic
platform data location, but it contained more than
platform data, remove it. New local header has been
created for exposing functions.

Also move gpmc-nand platform data to platform header
meant for nand from gpmc header file

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-cm-t35.c           |  3 +-
 arch/arm/mach-omap2/board-cm-t3517.c         |  3 +-
 arch/arm/mach-omap2/board-flash.c            |  4 +--
 arch/arm/mach-omap2/board-omap3pandora.c     |  3 +-
 arch/arm/mach-omap2/common-board-devices.c   |  1 -
 arch/arm/mach-omap2/gpmc-nand.c              | 54 +++++++++++++++-------------
 arch/arm/mach-omap2/gpmc-nand.h              | 27 ++++++++++++++
 arch/arm/mach-omap2/gpmc.c                   |  2 ++
 arch/arm/plat-omap/include/plat/gpmc.h       | 28 ++-------------
 include/linux/platform_data/mtd-nand-omap2.h | 41 ++++++++++++++-------
 10 files changed, 98 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc-nand.h

diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 376d26e..fef68de 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -53,6 +53,7 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-nand.h"
 
 #define CM_T35_GPIO_PENDOWN		57
 #define SB_T35_USB_HUB_RESET_GPIO	167
@@ -181,7 +182,7 @@ static struct omap_nand_platform_data cm_t35_nand_data = {
 
 static void __init cm_t35_init_nand(void)
 {
-	if (gpmc_nand_init(&cm_t35_nand_data) < 0)
+	if (gpmc_nand_init(&cm_t35_nand_data, NULL) < 0)
 		pr_err("CM-T35: Unable to register NAND device\n");
 }
 #else
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 59c0a45..3a19e80 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -49,6 +49,7 @@
 #include "control.h"
 #include "common-board-devices.h"
 #include "am35xx-emac.h"
+#include "gpmc-nand.h"
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 static struct gpio_led cm_t3517_leds[] = {
@@ -240,7 +241,7 @@ static struct omap_nand_platform_data cm_t3517_nand_data = {
 
 static void __init cm_t3517_init_nand(void)
 {
-	if (gpmc_nand_init(&cm_t3517_nand_data) < 0)
+	if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0)
 		pr_err("CM-T3517: NAND initialization failed\n");
 }
 #else
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index de68fdf..776e57a 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -26,6 +26,7 @@
 #include "common.h"
 #include "board-flash.h"
 #include "gpmc-onenand.h"
+#include "gpmc-nand.h"
 
 #define REG_FPGA_REV			0x10
 #define REG_FPGA_DIP_SWITCH_INPUT2	0x60
@@ -139,10 +140,9 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.parts		= nand_parts;
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
-	board_nand_data.gpmc_t		= gpmc_t;
 
 	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
-	gpmc_nand_init(&board_nand_data);
+	gpmc_nand_init(&board_nand_data, gpmc_t);
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
 
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 00a1f4a..f286b4b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -50,6 +50,7 @@
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
+#include "gpmc-nand.h"
 
 #define PANDORA_WIFI_IRQ_GPIO		21
 #define PANDORA_WIFI_NRESET_GPIO	23
@@ -602,7 +603,7 @@ static void __init omap3pandora_init(void)
 	omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
 	usbhs_init(&usbhs_bdata);
 	usb_musb_init(NULL);
-	gpmc_nand_init(&pandora_nand_data);
+	gpmc_nand_init(&pandora_nand_data, NULL);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 90e0597..ad85609 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -25,7 +25,6 @@
 #include <linux/spi/ads7846.h>
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/platform_data/mtd-nand-omap2.h>
 
 #include "common.h"
 #include "common-board-devices.h"
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 4eceaca..c1b9b1d 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -20,6 +20,10 @@
 #include <plat/gpmc.h>
 
 #include "soc.h"
+#include "gpmc-nand.h"
+
+/* minimum size for IO mapping */
+#define	NAND_IO_SIZE	4
 
 static struct resource gpmc_nand_resource[] = {
 	{
@@ -40,37 +44,36 @@ static struct platform_device gpmc_nand_device = {
 	.resource	= gpmc_nand_resource,
 };
 
-static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data)
+static int omap2_nand_gpmc_retime(
+				struct omap_nand_platform_data *gpmc_nand_data,
+				struct gpmc_timings *gpmc_t)
 {
 	struct gpmc_timings t;
 	int err;
 
-	if (!gpmc_nand_data->gpmc_t)
-		return 0;
-
 	memset(&t, 0, sizeof(t));
-	t.sync_clk = gpmc_nand_data->gpmc_t->sync_clk;
-	t.cs_on = gpmc_nand_data->gpmc_t->cs_on;
-	t.adv_on = gpmc_nand_data->gpmc_t->adv_on;
+	t.sync_clk = gpmc_t->sync_clk;
+	t.cs_on = gpmc_t->cs_on;
+	t.adv_on = gpmc_t->adv_on;
 
 	/* Read */
-	t.adv_rd_off = gpmc_nand_data->gpmc_t->adv_rd_off;
+	t.adv_rd_off = gpmc_t->adv_rd_off;
 	t.oe_on  = t.adv_on;
-	t.access = gpmc_nand_data->gpmc_t->access;
-	t.oe_off = gpmc_nand_data->gpmc_t->oe_off;
-	t.cs_rd_off = gpmc_nand_data->gpmc_t->cs_rd_off;
-	t.rd_cycle = gpmc_nand_data->gpmc_t->rd_cycle;
+	t.access = gpmc_t->access;
+	t.oe_off = gpmc_t->oe_off;
+	t.cs_rd_off = gpmc_t->cs_rd_off;
+	t.rd_cycle = gpmc_t->rd_cycle;
 
 	/* Write */
-	t.adv_wr_off = gpmc_nand_data->gpmc_t->adv_wr_off;
+	t.adv_wr_off = gpmc_t->adv_wr_off;
 	t.we_on  = t.oe_on;
 	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = gpmc_nand_data->gpmc_t->wr_data_mux_bus;
-		t.wr_access = gpmc_nand_data->gpmc_t->wr_access;
+		t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
+		t.wr_access = gpmc_t->wr_access;
 	}
-	t.we_off = gpmc_nand_data->gpmc_t->we_off;
-	t.cs_wr_off = gpmc_nand_data->gpmc_t->cs_wr_off;
-	t.wr_cycle = gpmc_nand_data->gpmc_t->wr_cycle;
+	t.we_off = gpmc_t->we_off;
+	t.cs_wr_off = gpmc_t->cs_wr_off;
+	t.wr_cycle = gpmc_t->wr_cycle;
 
 	/* Configure GPMC */
 	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
@@ -87,7 +90,8 @@ static int omap2_nand_gpmc_retime(struct omap_nand_platform_data *gpmc_nand_data
 	return 0;
 }
 
-int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
+int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+			  struct gpmc_timings *gpmc_t)
 {
 	int err	= 0;
 	struct device *dev = &gpmc_nand_device.dev;
@@ -108,11 +112,13 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data)
 				gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
 	gpmc_nand_resource[2].start =
 				gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
-	 /* Set timings in GPMC */
-	err = omap2_nand_gpmc_retime(gpmc_nand_data);
-	if (err < 0) {
-		dev_err(dev, "Unable to set gpmc timings: %d\n", err);
-		return err;
+
+	if (gpmc_t) {
+		err = omap2_nand_gpmc_retime(gpmc_nand_data, gpmc_t);
+		if (err < 0) {
+			dev_err(dev, "Unable to set gpmc timings: %d\n", err);
+			return err;
+		}
 	}
 
 	/* Enable RD PIN Monitoring Reg */
diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h
new file mode 100644
index 0000000..11a377f
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-nand.h
@@ -0,0 +1,27 @@
+/*
+ *  arch/arm/mach-omap2/gpmc-nand.h
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef	__OMAP2_GPMC_NAND_H
+#define	__OMAP2_GPMC_NAND_H
+
+#include <plat/gpmc.h>
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+#if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
+extern int gpmc_nand_init(struct omap_nand_platform_data *d,
+			  struct gpmc_timings *gpmc_t);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d,
+				 struct gpmc_timings *gpmc_t)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 163458d..3a73196 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -26,6 +26,8 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
+#include <linux/platform_data/mtd-nand-omap2.h>
+
 #include <asm/mach-types.h>
 #include <plat/gpmc.h>
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 1cafbfd..17fc1e7 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -11,6 +11,8 @@
 #ifndef __OMAP2_GPMC_H
 #define __OMAP2_GPMC_H
 
+#include <linux/platform_data/mtd-nand-omap2.h>
+
 /* Maximum Number of Chip Selects */
 #define GPMC_CS_NUM		8
 
@@ -86,16 +88,6 @@
 #define PREFETCH_FIFOTHRESHOLD_MAX	0x40
 #define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
 
-enum omap_ecc {
-		/* 1-bit ecc: stored at end of spare area */
-	OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */
-	OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */
-		/* 1-bit ecc: stored at beginning of spare area as romcode */
-	OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */
-	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
-	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
-};
-
 /* bool type time settings */
 struct gpmc_bool_timings {
 	bool cycle2cyclediffcsen;
@@ -152,22 +144,6 @@ struct gpmc_timings {
 	struct gpmc_bool_timings bool_timings;
 };
 
-struct gpmc_nand_regs {
-	void __iomem	*gpmc_status;
-	void __iomem	*gpmc_nand_command;
-	void __iomem	*gpmc_nand_address;
-	void __iomem	*gpmc_nand_data;
-	void __iomem	*gpmc_prefetch_config1;
-	void __iomem	*gpmc_prefetch_config2;
-	void __iomem	*gpmc_prefetch_control;
-	void __iomem	*gpmc_prefetch_status;
-	void __iomem	*gpmc_ecc_config;
-	void __iomem	*gpmc_ecc_control;
-	void __iomem	*gpmc_ecc_size_config;
-	void __iomem	*gpmc_ecc1_result;
-	void __iomem	*gpmc_bch_result0;
-};
-
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 1a68c1e..e1965fe 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -8,7 +8,9 @@
  * published by the Free Software Foundation.
  */
 
-#include <plat/gpmc.h>
+#ifndef	_MTD_NAND_OMAP2_H
+#define	_MTD_NAND_OMAP2_H
+
 #include <linux/mtd/partitions.h>
 
 enum nand_io {
@@ -18,10 +20,35 @@ enum nand_io {
 	NAND_OMAP_PREFETCH_IRQ		/* prefetch enabled irq mode */
 };
 
+enum omap_ecc {
+		/* 1-bit ecc: stored at end of spare area */
+	OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */
+	OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */
+		/* 1-bit ecc: stored at beginning of spare area as romcode */
+	OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */
+	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
+	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
+};
+
+struct gpmc_nand_regs {
+	void __iomem	*gpmc_status;
+	void __iomem	*gpmc_nand_command;
+	void __iomem	*gpmc_nand_address;
+	void __iomem	*gpmc_nand_data;
+	void __iomem	*gpmc_prefetch_config1;
+	void __iomem	*gpmc_prefetch_config2;
+	void __iomem	*gpmc_prefetch_control;
+	void __iomem	*gpmc_prefetch_status;
+	void __iomem	*gpmc_ecc_config;
+	void __iomem	*gpmc_ecc_control;
+	void __iomem	*gpmc_ecc_size_config;
+	void __iomem	*gpmc_ecc1_result;
+	void __iomem	*gpmc_bch_result0;
+};
+
 struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
-	struct gpmc_timings	*gpmc_t;
 	int			nr_parts;
 	bool			dev_ready;
 	enum nand_io		xfer_type;
@@ -30,14 +57,4 @@ struct omap_nand_platform_data {
 	struct gpmc_nand_regs	reg;
 };
 
-/* minimum size for IO mapping */
-#define	NAND_IO_SIZE	4
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-extern int gpmc_nand_init(struct omap_nand_platform_data *d);
-#else
-static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
-{
-	return 0;
-}
 #endif
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:40 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:40 +0530
Subject: [PATCH v2 09/14] mtd: nand: omap: bring in gpmc nand macros
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <2c357dd43c39a04e7f7fc773e425381fb1b2febe.1349672877.git.afzal@ti.com>

Bring onto driver the macros defined in gpmc.h that are
not necessary outside driver, helps in removing inclusion
of gpmc.h too. Also remove GPMC prefix on those macros to
make clear it's independence with gpmc header.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index abfc602..f0a1b1d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -110,6 +110,11 @@
 #define	ECC1RESULTSIZE			0x1
 #define	ECCCLEAR			0x100
 #define	ECC1				0x1
+#define	PREFETCH_FIFOTHRESHOLD_MAX	0x40
+#define	PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
+#define	PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
+#define	PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
+#define	STATUS_BUFF_EMPTY		0x00000001
 
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
@@ -269,7 +274,7 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
 		/* wait until buffer is available for write */
 		do {
 			status = readl(info->reg.gpmc_status) &
-					GPMC_STATUS_BUFF_EMPTY;
+					STATUS_BUFF_EMPTY;
 		} while (!status);
 	}
 }
@@ -307,7 +312,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 		/* wait until buffer is available for write */
 		do {
 			status = readl(info->reg.gpmc_status) &
-					GPMC_STATUS_BUFF_EMPTY;
+					STATUS_BUFF_EMPTY;
 		} while (!status);
 	}
 }
@@ -348,7 +353,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
 	} else {
 		do {
 			r_count = readl(info->reg.gpmc_prefetch_status);
-			r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count);
+			r_count = PREFETCH_STATUS_FIFO_CNT(r_count);
 			r_count = r_count >> 2;
 			ioread32_rep(info->nand.IO_ADDR_R, p, r_count);
 			p += r_count;
@@ -395,7 +400,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
 	} else {
 		while (len) {
 			w_count = readl(info->reg.gpmc_prefetch_status);
-			w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count);
+			w_count = PREFETCH_STATUS_FIFO_CNT(w_count);
 			w_count = w_count >> 1;
 			for (i = 0; (i < w_count) && len; i++, len -= 2)
 				iowrite16(*p++, info->nand.IO_ADDR_W);
@@ -407,7 +412,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
 		do {
 			cpu_relax();
 			val = readl(info->reg.gpmc_prefetch_status);
-			val = GPMC_PREFETCH_STATUS_COUNT(val);
+			val = PREFETCH_STATUS_COUNT(val);
 		} while (val && (tim++ < limit));
 
 		/* disable and stop the PFPW engine */
@@ -493,7 +498,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
 	do {
 		cpu_relax();
 		val = readl(info->reg.gpmc_prefetch_status);
-		val = GPMC_PREFETCH_STATUS_COUNT(val);
+		val = PREFETCH_STATUS_COUNT(val);
 	} while (val && (tim++ < limit));
 
 	/* disable and stop the PFPW engine */
@@ -556,7 +561,7 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
 	u32 bytes;
 
 	bytes = readl(info->reg.gpmc_prefetch_status);
-	bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
+	bytes = PREFETCH_STATUS_FIFO_CNT(bytes);
 	bytes = bytes  & 0xFFFC; /* io in multiple of 4 bytes */
 	if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
 		if (this_irq == info->gpmc_irq_count)
@@ -682,7 +687,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
 	limit = (loops_per_jiffy *  msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
 	do {
 		val = readl(info->reg.gpmc_prefetch_status);
-		val = GPMC_PREFETCH_STATUS_COUNT(val);
+		val = PREFETCH_STATUS_COUNT(val);
 		cpu_relax();
 	} while (val && (tim++ < limit));
 
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:46 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:46 +0530
Subject: [PATCH v2 10/14] ARM: OMAP2+: nand: bch capability check
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <9575950c712e397fa9ddca535d167e6c77e1934d.1349672877.git.afzal@ti.com>

Capability of bch schemes could be discovered using soc
revision checks. If soc revision indicates that selected
ecc scheme is not supported bail out.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc-nand.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index c1b9b1d..7983d54 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -90,6 +90,27 @@ static int omap2_nand_gpmc_retime(
 	return 0;
 }
 
+static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
+{
+	/* support only OMAP3 class */
+	if (!cpu_is_omap34xx()) {
+		pr_err("BCH ecc is not supported on this CPU\n");
+		return 0;
+	}
+
+	/*
+	 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
+	 * Other chips may be added if confirmed to work.
+	 */
+	if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) &&
+	    (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
+		pr_err("BCH 4-bit mode is not supported on this CPU\n");
+		return 0;
+	}
+
+	return 1;
+}
+
 int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 			  struct gpmc_timings *gpmc_t)
 {
@@ -128,6 +149,9 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 
 	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
 
+	if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt))
+		return -EINVAL;
+
 	err = platform_device_register(&gpmc_nand_device);
 	if (err < 0) {
 		dev_err(dev, "Unable to register NAND device\n");
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:52 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:52 +0530
Subject: [PATCH v2 11/14] ARM: OMAP2+: gpmc: nand register helper bch update
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <1b75c64a6f2674faa9dce3b3a7ff5793b1f65d0c.1349672877.git.afzal@ti.com>

Update helper function that provides gpmc-nand register
details for nand driver with bch register information.
Using this nand driver can be made self sufficient to
handle remaining gpmc-nand operations by itself instead
of relying on gpmc exported nand functions.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c                   | 18 +++++++++++++++++-
 include/linux/platform_data/mtd-nand-omap2.h |  7 ++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 3a73196..eb577c5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -61,6 +61,9 @@
 #define GPMC_ECC_SIZE_CONFIG	0x1fc
 #define GPMC_ECC1_RESULT        0x200
 #define GPMC_ECC_BCH_RESULT_0   0x240   /* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_1	0x244	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_2	0x248	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_3	0x24c	/* not available on OMAP2 */
 
 /* GPMC ECC control settings */
 #define GPMC_ECC_CTRL_ECCCLEAR		0x100
@@ -84,6 +87,7 @@
 
 #define GPMC_CS0_OFFSET		0x60
 #define GPMC_CS_SIZE		0x30
+#define	GPMC_BCH_SIZE		0x10
 
 #define GPMC_MEM_START		0x00000000
 #define GPMC_MEM_END		0x3FFFFFFF
@@ -779,6 +783,8 @@ EXPORT_SYMBOL(gpmc_prefetch_reset);
 
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
+	int i;
+
 	reg->gpmc_status = gpmc_base + GPMC_STATUS;
 	reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
 				GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
@@ -794,7 +800,17 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
 	reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
 	reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
-	reg->gpmc_bch_result0 = gpmc_base + GPMC_ECC_BCH_RESULT_0;
+
+	for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
+		reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
+					   GPMC_BCH_SIZE * i;
+		reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
+					   GPMC_BCH_SIZE * i;
+	}
 }
 
 int gpmc_get_client_irq(unsigned irq_config)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index e1965fe..24d32ca 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -13,6 +13,8 @@
 
 #include <linux/mtd/partitions.h>
 
+#define	GPMC_BCH_NUM_REMAINDER	8
+
 enum nand_io {
 	NAND_OMAP_PREFETCH_POLLED = 0,	/* prefetch polled mode, default */
 	NAND_OMAP_POLLED,		/* polled mode, without prefetch */
@@ -43,7 +45,10 @@ struct gpmc_nand_regs {
 	void __iomem	*gpmc_ecc_control;
 	void __iomem	*gpmc_ecc_size_config;
 	void __iomem	*gpmc_ecc1_result;
-	void __iomem	*gpmc_bch_result0;
+	void __iomem	*gpmc_bch_result0[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result1[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result2[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result3[GPMC_BCH_NUM_REMAINDER];
 };
 
 struct omap_nand_platform_data {
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:37:58 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:07:58 +0530
Subject: [PATCH v2 12/14] mtd: nand: omap: handle gpmc bch[48]
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <56c6e40a80097282f0c5bce9175c540717bd7eb8.1349672877.git.afzal@ti.com>

gpmc-nand bch registers are now available in driver,
make use of it to handle bch[48] instead of relying
on gpmc exported functions.

And so nand driver no longer needs gpmc header, remove it.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 drivers/mtd/nand/omap2.c | 100 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 89 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f0a1b1d..3282b15 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -28,7 +28,6 @@
 #endif
 
 #include <plat/dma.h>
-#include <plat/gpmc.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #define	DRIVER_NAME	"omap2-nand"
@@ -106,6 +105,7 @@
 #define	CS_MASK				0x7
 #define	ENABLE_PREFETCH			(0x1 << 7)
 #define	DMA_MPU_MODE_SHIFT		2
+#define	ECCSIZE0_SHIFT			12
 #define	ECCSIZE1_SHIFT			22
 #define	ECC1RESULTSIZE			0x1
 #define	ECCCLEAR			0x100
@@ -1034,19 +1034,45 @@ static int omap_dev_ready(struct mtd_info *mtd)
 static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 {
 	int nerrors;
-	unsigned int dev_width;
+	unsigned int dev_width, nsectors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 	struct nand_chip *chip = mtd->priv;
+	u32 val;
 
 	nerrors = (info->nand.ecc.bytes == 13) ? 8 : 4;
 	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+	nsectors = 1;
 	/*
 	 * Program GPMC to perform correction on one 512-byte sector at a time.
 	 * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
 	 * gives a slight (5%) performance gain (but requires additional code).
 	 */
-	(void)gpmc_enable_hwecc_bch(info->gpmc_cs, mode, dev_width, 1, nerrors);
+
+	writel(ECC1, info->reg.gpmc_ecc_control);
+
+	/*
+	 * When using BCH, sector size is hardcoded to 512 bytes.
+	 * Here we are using wrapping mode 6 both for reading and writing, with:
+	 *  size0 = 0  (no additional protected byte in spare area)
+	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
+	 */
+	val = (32 << ECCSIZE1_SHIFT) | (0 << ECCSIZE0_SHIFT);
+	writel(val, info->reg.gpmc_ecc_size_config);
+
+	/* BCH configuration */
+	val = ((1                        << 16) | /* enable BCH */
+	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
+	       (0x06                     <<  8) | /* wrap mode = 6 */
+	       (dev_width                <<  7) | /* bus width */
+	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
+	       (info->gpmc_cs            <<  1) | /* ECC CS */
+	       (0x1));                            /* enable ECC */
+
+	writel(val, info->reg.gpmc_ecc_config);
+
+	/* clear ecc and enable bits */
+	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
 
 /**
@@ -1060,7 +1086,32 @@ static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat,
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	return gpmc_calculate_ecc_bch4(info->gpmc_cs, dat, ecc_code);
+	unsigned long nsectors, val1, val2;
+	int i;
+
+	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
+
+	for (i = 0; i < nsectors; i++) {
+
+		/* Read hw-computed remainder */
+		val1 = readl(info->reg.gpmc_bch_result0[i]);
+		val2 = readl(info->reg.gpmc_bch_result1[i]);
+
+		/*
+		 * Add constant polynomial to remainder, in order to get an ecc
+		 * sequence of 0xFFs for a buffer filled with 0xFFs; and
+		 * left-justify the resulting polynomial.
+		 */
+		*ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF);
+		*ecc_code++ = 0x13 ^ ((val2 >>  4) & 0xFF);
+		*ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
+		*ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF);
+		*ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF);
+		*ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF);
+		*ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4);
+	}
+
+	return 0;
 }
 
 /**
@@ -1074,7 +1125,39 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	return gpmc_calculate_ecc_bch8(info->gpmc_cs, dat, ecc_code);
+	unsigned long nsectors, val1, val2, val3, val4;
+	int i;
+
+	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
+
+	for (i = 0; i < nsectors; i++) {
+
+		/* Read hw-computed remainder */
+		val1 = readl(info->reg.gpmc_bch_result0[i]);
+		val2 = readl(info->reg.gpmc_bch_result1[i]);
+		val3 = readl(info->reg.gpmc_bch_result2[i]);
+		val4 = readl(info->reg.gpmc_bch_result3[i]);
+
+		/*
+		 * Add constant polynomial to remainder, in order to get an ecc
+		 * sequence of 0xFFs for a buffer filled with 0xFFs.
+		 */
+		*ecc_code++ = 0xef ^ (val4 & 0xFF);
+		*ecc_code++ = 0x51 ^ ((val3 >> 24) & 0xFF);
+		*ecc_code++ = 0x2e ^ ((val3 >> 16) & 0xFF);
+		*ecc_code++ = 0x09 ^ ((val3 >> 8) & 0xFF);
+		*ecc_code++ = 0xed ^ (val3 & 0xFF);
+		*ecc_code++ = 0x93 ^ ((val2 >> 24) & 0xFF);
+		*ecc_code++ = 0x9a ^ ((val2 >> 16) & 0xFF);
+		*ecc_code++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
+		*ecc_code++ = 0x97 ^ (val2 & 0xFF);
+		*ecc_code++ = 0x79 ^ ((val1 >> 24) & 0xFF);
+		*ecc_code++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
+		*ecc_code++ = 0x24 ^ ((val1 >> 8) & 0xFF);
+		*ecc_code++ = 0xb5 ^ (val1 & 0xFF);
+	}
+
+	return 0;
 }
 
 /**
@@ -1130,7 +1213,7 @@ static void omap3_free_bch(struct mtd_info *mtd)
  */
 static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 {
-	int ret, max_errors;
+	int max_errors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 #ifdef CONFIG_MTD_NAND_OMAP_BCH8
@@ -1147,11 +1230,6 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 		goto fail;
 	}
 
-	/* initialize GPMC BCH engine */
-	ret = gpmc_init_hwecc_bch(info->gpmc_cs, 1, max_errors);
-	if (ret)
-		goto fail;
-
 	/* software bch library is only used to detect and locate errors */
 	info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
 	if (!info->bch)
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:38:03 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:08:03 +0530
Subject: [PATCH v2 13/14] ARM: OMAP2+: gpmc: remove exported nand functions
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <12e68d50bc2d163d620169d696a2b909a16c49b0.1349672877.git.afzal@ti.com>

nand driver handles gpmc-nand block fully, hence no more
users for these exported nand functions, remove it.

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/gpmc.c             | 432 ---------------------------------
 arch/arm/plat-omap/include/plat/gpmc.h |  31 ---
 2 files changed, 463 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index eb577c5..1121248 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -150,7 +150,6 @@ static struct resource	gpmc_mem_root;
 static struct resource	gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
-static int gpmc_ecc_used = -EINVAL;	/* cs using ecc engine */
 static struct device *gpmc_dev;
 static int gpmc_irq;
 static resource_size_t phys_base, mem_size;
@@ -171,22 +170,6 @@ static u32 gpmc_read_reg(int idx)
 	return __raw_readl(gpmc_base + idx);
 }
 
-static void gpmc_cs_write_byte(int cs, int idx, u8 val)
-{
-	void __iomem *reg_addr;
-
-	reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
-	__raw_writeb(val, reg_addr);
-}
-
-static u8 gpmc_cs_read_byte(int cs, int idx)
-{
-	void __iomem *reg_addr;
-
-	reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
-	return __raw_readb(reg_addr);
-}
-
 void gpmc_cs_write_reg(int cs, int idx, u32 val)
 {
 	void __iomem *reg_addr;
@@ -563,44 +546,6 @@ void gpmc_cs_free(int cs)
 EXPORT_SYMBOL(gpmc_cs_free);
 
 /**
- * gpmc_read_status - read access request to get the different gpmc status
- * @cmd: command type
- * @return status
- */
-int gpmc_read_status(int cmd)
-{
-	int	status = -EINVAL;
-	u32	regval = 0;
-
-	switch (cmd) {
-	case GPMC_GET_IRQ_STATUS:
-		status = gpmc_read_reg(GPMC_IRQSTATUS);
-		break;
-
-	case GPMC_PREFETCH_FIFO_CNT:
-		regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
-		status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval);
-		break;
-
-	case GPMC_PREFETCH_COUNT:
-		regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
-		status = GPMC_PREFETCH_STATUS_COUNT(regval);
-		break;
-
-	case GPMC_STATUS_BUFFER:
-		regval = gpmc_read_reg(GPMC_STATUS);
-		/* 1 : buffer is available to write */
-		status = regval & GPMC_STATUS_BUFF_EMPTY;
-		break;
-
-	default:
-		printk(KERN_ERR "gpmc_read_status: Not supported\n");
-	}
-	return status;
-}
-EXPORT_SYMBOL(gpmc_read_status);
-
-/**
  * gpmc_cs_configure - write request to configure gpmc
  * @cs: chip select number
  * @cmd: command type
@@ -668,119 +613,6 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
 }
 EXPORT_SYMBOL(gpmc_cs_configure);
 
-/**
- * gpmc_nand_read - nand specific read access request
- * @cs: chip select number
- * @cmd: command type
- */
-int gpmc_nand_read(int cs, int cmd)
-{
-	int rval = -EINVAL;
-
-	switch (cmd) {
-	case GPMC_NAND_DATA:
-		rval = gpmc_cs_read_byte(cs, GPMC_CS_NAND_DATA);
-		break;
-
-	default:
-		printk(KERN_ERR "gpmc_read_nand_ctrl: Not supported\n");
-	}
-	return rval;
-}
-EXPORT_SYMBOL(gpmc_nand_read);
-
-/**
- * gpmc_nand_write - nand specific write request
- * @cs: chip select number
- * @cmd: command type
- * @wval: value to write
- */
-int gpmc_nand_write(int cs, int cmd, int wval)
-{
-	int err = 0;
-
-	switch (cmd) {
-	case GPMC_NAND_COMMAND:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_COMMAND, wval);
-		break;
-
-	case GPMC_NAND_ADDRESS:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_ADDRESS, wval);
-		break;
-
-	case GPMC_NAND_DATA:
-		gpmc_cs_write_byte(cs, GPMC_CS_NAND_DATA, wval);
-
-	default:
-		printk(KERN_ERR "gpmc_write_nand_ctrl: Not supported\n");
-		err = -EINVAL;
-	}
-	return err;
-}
-EXPORT_SYMBOL(gpmc_nand_write);
-
-
-
-/**
- * gpmc_prefetch_enable - configures and starts prefetch transfer
- * @cs: cs (chip select) number
- * @fifo_th: fifo threshold to be used for read/ write
- * @dma_mode: dma mode enable (1) or disable (0)
- * @u32_count: number of bytes to be transferred
- * @is_write: prefetch read(0) or write post(1) mode
- */
-int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
-				unsigned int u32_count, int is_write)
-{
-
-	if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
-		pr_err("gpmc: fifo threshold is not supported\n");
-		return -1;
-	} else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
-		/* Set the amount of bytes to be prefetched */
-		gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
-
-		/* Set dma/mpu mode, the prefetch read / post write and
-		 * enable the engine. Set which cs is has requested for.
-		 */
-		gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
-					PREFETCH_FIFOTHRESHOLD(fifo_th) |
-					ENABLE_PREFETCH |
-					(dma_mode << DMA_MPU_MODE) |
-					(0x1 & is_write)));
-
-		/*  Start the prefetch engine */
-		gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1);
-	} else {
-		return -EBUSY;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(gpmc_prefetch_enable);
-
-/**
- * gpmc_prefetch_reset - disables and stops the prefetch engine
- */
-int gpmc_prefetch_reset(int cs)
-{
-	u32 config1;
-
-	/* check if the same module/cs is trying to reset */
-	config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
-	if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs)
-		return -EINVAL;
-
-	/* Stop the PFPW engine */
-	gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0);
-
-	/* Reset/disable the PFPW engine */
-	gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0);
-
-	return 0;
-}
-EXPORT_SYMBOL(gpmc_prefetch_reset);
-
 void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
 	int i;
@@ -1145,267 +977,3 @@ void omap3_gpmc_restore_context(void)
 	}
 }
 #endif /* CONFIG_ARCH_OMAP3 */
-
-/**
- * gpmc_enable_hwecc - enable hardware ecc functionality
- * @cs: chip select number
- * @mode: read/write mode
- * @dev_width: device bus width(1 for x16, 0 for x8)
- * @ecc_size: bytes for which ECC will be generated
- */
-int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
-{
-	unsigned int val;
-
-	/* check if ecc module is in used */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	gpmc_ecc_used = cs;
-
-	/* clear ecc and enable bits */
-	gpmc_write_reg(GPMC_ECC_CONTROL,
-			GPMC_ECC_CTRL_ECCCLEAR |
-			GPMC_ECC_CTRL_ECCREG1);
-
-	/* program ecc and result sizes */
-	val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F));
-	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val);
-
-	switch (mode) {
-	case GPMC_ECC_READ:
-	case GPMC_ECC_WRITE:
-		gpmc_write_reg(GPMC_ECC_CONTROL,
-				GPMC_ECC_CTRL_ECCCLEAR |
-				GPMC_ECC_CTRL_ECCREG1);
-		break;
-	case GPMC_ECC_READSYN:
-		gpmc_write_reg(GPMC_ECC_CONTROL,
-				GPMC_ECC_CTRL_ECCCLEAR |
-				GPMC_ECC_CTRL_ECCDISABLE);
-		break;
-	default:
-		printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode);
-		break;
-	}
-
-	/* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
-	val = (dev_width << 7) | (cs << 1) | (0x1);
-	gpmc_write_reg(GPMC_ECC_CONFIG, val);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_enable_hwecc);
-
-/**
- * gpmc_calculate_ecc - generate non-inverted ecc bytes
- * @cs: chip select number
- * @dat: data pointer over which ecc is computed
- * @ecc_code: ecc code buffer
- *
- * Using non-inverted ECC is considered ugly since writing a blank
- * page (padding) will clear the ECC bytes. This is not a problem as long
- * no one is trying to write data on the seemingly unused page. Reading
- * an erased page will produce an ECC mismatch between generated and read
- * ECC bytes that has to be dealt with separately.
- */
-int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code)
-{
-	unsigned int val = 0x0;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	/* read ecc result */
-	val = gpmc_read_reg(GPMC_ECC1_RESULT);
-	*ecc_code++ = val;          /* P128e, ..., P1e */
-	*ecc_code++ = val >> 16;    /* P128o, ..., P1o */
-	/* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
-	*ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc);
-
-#ifdef CONFIG_ARCH_OMAP3
-
-/**
- * gpmc_init_hwecc_bch - initialize hardware BCH ecc functionality
- * @cs: chip select number
- * @nsectors: how many 512-byte sectors to process
- * @nerrors: how many errors to correct per sector (4 or 8)
- *
- * This function must be executed before any call to gpmc_enable_hwecc_bch.
- */
-int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors)
-{
-	/* check if ecc module is in use */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	/* support only OMAP3 class */
-	if (!cpu_is_omap34xx()) {
-		printk(KERN_ERR "BCH ecc is not supported on this CPU\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1.
-	 * Other chips may be added if confirmed to work.
-	 */
-	if ((nerrors == 4) &&
-	    (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) {
-		printk(KERN_ERR "BCH 4-bit mode is not supported on this CPU\n");
-		return -EINVAL;
-	}
-
-	/* sanity check */
-	if (nsectors > 8) {
-		printk(KERN_ERR "BCH cannot process %d sectors (max is 8)\n",
-		       nsectors);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_init_hwecc_bch);
-
-/**
- * gpmc_enable_hwecc_bch - enable hardware BCH ecc functionality
- * @cs: chip select number
- * @mode: read/write mode
- * @dev_width: device bus width(1 for x16, 0 for x8)
- * @nsectors: how many 512-byte sectors to process
- * @nerrors: how many errors to correct per sector (4 or 8)
- */
-int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
-			  int nerrors)
-{
-	unsigned int val;
-
-	/* check if ecc module is in use */
-	if (gpmc_ecc_used != -EINVAL)
-		return -EINVAL;
-
-	gpmc_ecc_used = cs;
-
-	/* clear ecc and enable bits */
-	gpmc_write_reg(GPMC_ECC_CONTROL, 0x1);
-
-	/*
-	 * When using BCH, sector size is hardcoded to 512 bytes.
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
-	 */
-	gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, (32 << 22) | (0 << 12));
-
-	/* BCH configuration */
-	val = ((1                        << 16) | /* enable BCH */
-	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
-	       (0x06                     <<  8) | /* wrap mode = 6 */
-	       (dev_width                <<  7) | /* bus width */
-	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
-	       (cs                       <<  1) | /* ECC CS */
-	       (0x1));                            /* enable ECC */
-
-	gpmc_write_reg(GPMC_ECC_CONFIG, val);
-	gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_enable_hwecc_bch);
-
-/**
- * gpmc_calculate_ecc_bch4 - Generate 7 ecc bytes per sector of 512 data bytes
- * @cs:  chip select number
- * @dat: The pointer to data on which ecc is computed
- * @ecc: The ecc output buffer
- */
-int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc)
-{
-	int i;
-	unsigned long nsectors, reg, val1, val2;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
-
-		/* Read hw-computed remainder */
-		val1 = gpmc_read_reg(reg + 0);
-		val2 = gpmc_read_reg(reg + 4);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs; and
-		 * left-justify the resulting polynomial.
-		 */
-		*ecc++ = 0x28 ^ ((val2 >> 12) & 0xFF);
-		*ecc++ = 0x13 ^ ((val2 >>  4) & 0xFF);
-		*ecc++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
-		*ecc++ = 0x39 ^ ((val1 >> 20) & 0xFF);
-		*ecc++ = 0x96 ^ ((val1 >> 12) & 0xFF);
-		*ecc++ = 0xac ^ ((val1 >> 4) & 0xFF);
-		*ecc++ = 0x7f ^ ((val1 & 0xF) << 4);
-	}
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch4);
-
-/**
- * gpmc_calculate_ecc_bch8 - Generate 13 ecc bytes per block of 512 data bytes
- * @cs:  chip select number
- * @dat: The pointer to data on which ecc is computed
- * @ecc: The ecc output buffer
- */
-int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc)
-{
-	int i;
-	unsigned long nsectors, reg, val1, val2, val3, val4;
-
-	if (gpmc_ecc_used != cs)
-		return -EINVAL;
-
-	nsectors = ((gpmc_read_reg(GPMC_ECC_CONFIG) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		reg = GPMC_ECC_BCH_RESULT_0 + 16*i;
-
-		/* Read hw-computed remainder */
-		val1 = gpmc_read_reg(reg + 0);
-		val2 = gpmc_read_reg(reg + 4);
-		val3 = gpmc_read_reg(reg + 8);
-		val4 = gpmc_read_reg(reg + 12);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs.
-		 */
-		*ecc++ = 0xef ^ (val4 & 0xFF);
-		*ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
-		*ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
-		*ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
-		*ecc++ = 0xed ^ (val3 & 0xFF);
-		*ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
-		*ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
-		*ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
-		*ecc++ = 0x97 ^ (val2 & 0xFF);
-		*ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
-		*ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
-		*ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
-		*ecc++ = 0xb5 ^ (val1 & 0xFF);
-	}
-
-	gpmc_ecc_used = -EINVAL;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gpmc_calculate_ecc_bch8);
-
-#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index 17fc1e7..e08a51a 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -34,15 +34,6 @@
 #define GPMC_SET_IRQ_STATUS	0x00000004
 #define GPMC_CONFIG_WP		0x00000005
 
-#define GPMC_GET_IRQ_STATUS	0x00000006
-#define GPMC_PREFETCH_FIFO_CNT	0x00000007 /* bytes available in FIFO for r/w */
-#define GPMC_PREFETCH_COUNT	0x00000008 /* remaining bytes to be read/write*/
-#define GPMC_STATUS_BUFFER	0x00000009 /* 1: buffer is available to write */
-
-#define GPMC_NAND_COMMAND	0x0000000a
-#define GPMC_NAND_ADDRESS	0x0000000b
-#define GPMC_NAND_DATA		0x0000000c
-
 #define GPMC_ENABLE_IRQ		0x0000000d
 
 /* ECC commands */
@@ -78,15 +69,10 @@
 #define GPMC_DEVICETYPE_NOR		0
 #define GPMC_DEVICETYPE_NAND		2
 #define GPMC_CONFIG_WRITEPROTECT	0x00000010
-#define GPMC_STATUS_BUFF_EMPTY		0x00000001
 #define WR_RD_PIN_MONITORING		0x00600000
-#define GPMC_PREFETCH_STATUS_FIFO_CNT(val)	((val >> 24) & 0x7F)
-#define GPMC_PREFETCH_STATUS_COUNT(val)	(val & 0x00003fff)
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
-#define PREFETCH_FIFOTHRESHOLD_MAX	0x40
-#define PREFETCH_FIFOTHRESHOLD(val)	((val) << 8)
 
 /* bool type time settings */
 struct gpmc_bool_timings {
@@ -161,25 +147,8 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern int gpmc_cs_set_reserved(int cs, int reserved);
 extern int gpmc_cs_reserved(int cs);
-extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
-					unsigned int u32_count, int is_write);
-extern int gpmc_prefetch_reset(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern int gpmc_read_status(int cmd);
 extern int gpmc_cs_configure(int cs, int cmd, int wval);
-extern int gpmc_nand_read(int cs, int cmd);
-extern int gpmc_nand_write(int cs, int cmd, int wval);
-
-int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size);
-int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code);
-
-#ifdef CONFIG_ARCH_OMAP3
-int gpmc_init_hwecc_bch(int cs, int nsectors, int nerrors);
-int gpmc_enable_hwecc_bch(int cs, int mode, int dev_width, int nsectors,
-			  int nerrors);
-int gpmc_calculate_ecc_bch4(int cs, const u_char *dat, u_char *ecc);
-int gpmc_calculate_ecc_bch8(int cs, const u_char *dat, u_char *ecc);
-#endif /* CONFIG_ARCH_OMAP3 */
 
 #endif
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:38:10 2012
From: afzal at ti.com (Afzal Mohammed)
Date: Mon, 8 Oct 2012 11:08:10 +0530
Subject: [PATCH v2 14/14] ARM: OMAP2+: gpmc: localize gpmc header
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <b16a67d2527cba70fcab85e1b4ff906ecf65b3ff.1349672877.git.afzal@ti.com>

Requirement of gpmc header outside of mach-omap2 has been
cutoff, move gpmc header file in plat-omap folder to local
mach-omap2 folder

Objective - common zImage participation of omap

Signed-off-by: Afzal Mohammed <afzal at ti.com>
---
 arch/arm/mach-omap2/board-2430sdp.c          |   2 +-
 arch/arm/mach-omap2/board-3430sdp.c          |   2 +-
 arch/arm/mach-omap2/board-apollon.c          |   2 +-
 arch/arm/mach-omap2/board-cm-t35.c           |   2 +-
 arch/arm/mach-omap2/board-cm-t3517.c         |   2 +-
 arch/arm/mach-omap2/board-devkit8000.c       |   2 +-
 arch/arm/mach-omap2/board-flash.c            |   2 +-
 arch/arm/mach-omap2/board-flash.h            |   2 +-
 arch/arm/mach-omap2/board-h4.c               |   2 +-
 arch/arm/mach-omap2/board-igep0020.c         |   2 +-
 arch/arm/mach-omap2/board-ldp.c              |   2 +-
 arch/arm/mach-omap2/board-omap3beagle.c      |   2 +-
 arch/arm/mach-omap2/board-omap3logic.c       |   2 +-
 arch/arm/mach-omap2/board-omap3stalker.c     |   2 +-
 arch/arm/mach-omap2/board-omap3touchbook.c   |   2 +-
 arch/arm/mach-omap2/board-overo.c            |   2 +-
 arch/arm/mach-omap2/board-rm680.c            |   2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c |   2 +-
 arch/arm/mach-omap2/board-rx51.c             |   2 +-
 arch/arm/mach-omap2/board-zoom-debugboard.c  |   2 +-
 arch/arm/mach-omap2/gpmc-nand.c              |   3 +-
 arch/arm/mach-omap2/gpmc-nand.h              |   2 +-
 arch/arm/mach-omap2/gpmc-onenand.c           |   3 +-
 arch/arm/mach-omap2/gpmc-smc91x.c            |   2 +-
 arch/arm/mach-omap2/gpmc-smsc911x.c          |   2 +-
 arch/arm/mach-omap2/gpmc.c                   |   3 +-
 arch/arm/mach-omap2/gpmc.h                   | 154 +++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm34xx.c                 |   2 +-
 arch/arm/mach-omap2/usb-tusb6010.c           |   2 +-
 arch/arm/plat-omap/include/plat/gpmc.h       | 154 ---------------------------
 30 files changed, 182 insertions(+), 185 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc.h
 delete mode 100644 arch/arm/plat-omap/include/plat/gpmc.h

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 95b384d..49e49d0 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -34,7 +34,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 #include "gpmc-smc91x.h"
 
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 96cd369..5ad0901 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -33,7 +33,7 @@
 #include <plat/usb.h>
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <video/omapdss.h>
 #include <video/omap-panel-tfp410.h>
 
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index cea3aba..8cdd186 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -35,7 +35,7 @@
 
 #include <plat/led.h>
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index fef68de..73e2ba9 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -40,7 +40,7 @@
 
 #include "common.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 3a19e80..b5495e4 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -41,7 +41,7 @@
 #include "common.h"
 #include <plat/usb.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include "am35xx.h"
 
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 9933966..3eedb8f 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -39,7 +39,7 @@
 #include <asm/mach/flash.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 776e57a..c56986f 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -18,7 +18,7 @@
 #include <linux/io.h>
 
 #include <plat/cpu.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 #include <plat/tc.h>
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index a3aa5fc..2fb5d41 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -12,7 +12,7 @@
  */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #define PDC_NOR		1
 #define PDC_NAND	2
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 8d04bf8..65ebf58 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -33,7 +33,6 @@
 
 #include <plat/menelaus.h>
 #include <plat/dma.h>
-#include <plat/gpmc.h>
 #include "debug-devices.h"
 
 #include <video/omapdss.h>
@@ -42,6 +41,7 @@
 #include "common.h"
 #include "mux.h"
 #include "control.h"
+#include "gpmc.h"
 
 #define H4_FLASH_CS	0
 #define H4_SMC91X_CS	1
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 83c6efa..9a9a9b5 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -30,7 +30,7 @@
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 83383f3..e1628cd 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -35,7 +35,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <mach/board-zoom.h>
 #include <plat/usb.h>
 #include "gpmc-smsc911x.h"
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index f240e21..65eaaee 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -41,7 +41,7 @@
 #include "common.h"
 #include <video/omapdss.h>
 #include <video/omap-panel-tfp410.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <plat/omap_device.h>
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 7bd8253..5cfade2 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -35,7 +35,7 @@
 #include <asm/mach/map.h>
 
 #include "gpmc-smsc911x.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/sdrc.h>
 #include <plat/usb.h>
 
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c7f3d02..11fcc73 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -40,7 +40,7 @@
 #include <asm/mach/flash.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 3f013c8..cd282ae 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -44,7 +44,7 @@
 #include <asm/system_info.h>
 
 #include "common.h"
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 #include <plat/usb.h>
 
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index e2cf0f7..3a9d1fa 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -49,7 +49,7 @@
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
 #include <video/omap-panel-tfp410.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 154cf33..3c3a473 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -25,7 +25,7 @@
 #include <plat/i2c.h>
 #include <plat/mmc.h>
 #include <plat/usb.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "common.h"
 #include <plat/serial.h>
 
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index aa6a2a4..5ba8942 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -32,7 +32,7 @@
 
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/omap-pm.h>
 #include "gpmc-smc91x.h"
 
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 7bbb05d..88ba5be 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -25,7 +25,7 @@
 
 #include "common.h"
 #include <plat/dma.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/usb.h>
 
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index afb2278..be9f71d 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -17,7 +17,7 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smsc911x.h"
 
 #include <mach/board-zoom.h>
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 7983d54..db969a5 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -17,8 +17,7 @@
 
 #include <asm/mach/flash.h>
 
-#include <plat/gpmc.h>
-
+#include "gpmc.h"
 #include "soc.h"
 #include "gpmc-nand.h"
 
diff --git a/arch/arm/mach-omap2/gpmc-nand.h b/arch/arm/mach-omap2/gpmc-nand.h
index 11a377f..d59e128 100644
--- a/arch/arm/mach-omap2/gpmc-nand.h
+++ b/arch/arm/mach-omap2/gpmc-nand.h
@@ -10,7 +10,7 @@
 #ifndef	__OMAP2_GPMC_NAND_H
 #define	__OMAP2_GPMC_NAND_H
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #if IS_ENABLED(CONFIG_MTD_NAND_OMAP2)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 29671cc..54e2255 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -20,8 +20,7 @@
 
 #include <asm/mach/flash.h>
 
-#include <plat/gpmc.h>
-
+#include "gpmc.h"
 #include "soc.h"
 #include "gpmc-onenand.h"
 
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 5654753..6eed907 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <linux/smc91x.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smc91x.h"
 
 #include "soc.h"
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 249a0b4..ef99011 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -20,7 +20,7 @@
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include "gpmc-smsc911x.h"
 
 static struct resource gpmc_smsc911x_resources[] = {
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1121248..285070e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -29,15 +29,14 @@
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #include <asm/mach-types.h>
-#include <plat/gpmc.h>
 
 #include <plat/cpu.h>
-#include <plat/gpmc.h>
 #include <plat/sdrc.h>
 #include <plat/omap_device.h>
 
 #include "soc.h"
 #include "common.h"
+#include "gpmc.h"
 
 #define	DEVICE_NAME		"omap-gpmc"
 
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
new file mode 100644
index 0000000..e08a51a
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -0,0 +1,154 @@
+/*
+ * General-Purpose Memory Controller for OMAP2
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * 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.
+ */
+
+#ifndef __OMAP2_GPMC_H
+#define __OMAP2_GPMC_H
+
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM		8
+
+#define GPMC_CS_CONFIG1		0x00
+#define GPMC_CS_CONFIG2		0x04
+#define GPMC_CS_CONFIG3		0x08
+#define GPMC_CS_CONFIG4		0x0c
+#define GPMC_CS_CONFIG5		0x10
+#define GPMC_CS_CONFIG6		0x14
+#define GPMC_CS_CONFIG7		0x18
+#define GPMC_CS_NAND_COMMAND	0x1c
+#define GPMC_CS_NAND_ADDRESS	0x20
+#define GPMC_CS_NAND_DATA	0x24
+
+/* Control Commands */
+#define GPMC_CONFIG_RDY_BSY	0x00000001
+#define GPMC_CONFIG_DEV_SIZE	0x00000002
+#define GPMC_CONFIG_DEV_TYPE	0x00000003
+#define GPMC_SET_IRQ_STATUS	0x00000004
+#define GPMC_CONFIG_WP		0x00000005
+
+#define GPMC_ENABLE_IRQ		0x0000000d
+
+/* ECC commands */
+#define GPMC_ECC_READ		0 /* Reset Hardware ECC for read */
+#define GPMC_ECC_WRITE		1 /* Reset Hardware ECC for write */
+#define GPMC_ECC_READSYN	2 /* Reset before syndrom is read back */
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
+#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
+#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
+#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
+#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
+#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
+#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
+#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
+#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
+#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
+#define GPMC_CONFIG7_CSVALID		(1 << 6)
+
+#define GPMC_DEVICETYPE_NOR		0
+#define GPMC_DEVICETYPE_NAND		2
+#define GPMC_CONFIG_WRITEPROTECT	0x00000010
+#define WR_RD_PIN_MONITORING		0x00600000
+#define GPMC_IRQ_FIFOEVENTENABLE	0x01
+#define GPMC_IRQ_COUNT_EVENT		0x02
+
+
+/* bool type time settings */
+struct gpmc_bool_timings {
+	bool cycle2cyclediffcsen;
+	bool cycle2cyclesamecsen;
+	bool we_extra_delay;
+	bool oe_extra_delay;
+	bool adv_extra_delay;
+	bool cs_extra_delay;
+	bool time_para_granularity;
+};
+
+/*
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+	/* Minimum clock period for synchronous mode (in picoseconds) */
+	u32 sync_clk;
+
+	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
+	u16 cs_on;		/* Assertion time */
+	u16 cs_rd_off;		/* Read deassertion time */
+	u16 cs_wr_off;		/* Write deassertion time */
+
+	/* ADV signal timings corresponding to GPMC_CONFIG3 */
+	u16 adv_on;		/* Assertion time */
+	u16 adv_rd_off;		/* Read deassertion time */
+	u16 adv_wr_off;		/* Write deassertion time */
+
+	/* WE signals timings corresponding to GPMC_CONFIG4 */
+	u16 we_on;		/* WE assertion time */
+	u16 we_off;		/* WE deassertion time */
+
+	/* OE signals timings corresponding to GPMC_CONFIG4 */
+	u16 oe_on;		/* OE assertion time */
+	u16 oe_off;		/* OE deassertion time */
+
+	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+	u16 page_burst_access;	/* Multiple access word delay */
+	u16 access;		/* Start-cycle to first data valid delay */
+	u16 rd_cycle;		/* Total read cycle time */
+	u16 wr_cycle;		/* Total write cycle time */
+
+	u16 bus_turnaround;
+	u16 cycle2cycle_delay;
+
+	u16 wait_monitoring;
+	u16 clk_activation;
+
+	/* The following are only on OMAP3430 */
+	u16 wr_access;		/* WRACCESSTIME */
+	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+
+	struct gpmc_bool_timings bool_timings;
+};
+
+extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+extern int gpmc_get_client_irq(unsigned irq_config);
+
+extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
+extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
+extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
+extern unsigned long gpmc_get_fclk_period(void);
+
+extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+extern u32 gpmc_cs_read_reg(int cs, int idx);
+extern int gpmc_calc_divider(unsigned int sync_clk);
+extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+extern void gpmc_cs_free(int cs);
+extern int gpmc_cs_set_reserved(int cs, int reserved);
+extern int gpmc_cs_reserved(int cs);
+extern void omap3_gpmc_save_context(void);
+extern void omap3_gpmc_restore_context(void);
+extern int gpmc_cs_configure(int cs, int cmd, int wval);
+
+#endif
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ba670db..ed98f4f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -40,7 +40,7 @@
 #include "powerdomain.h"
 #include <plat/sdrc.h>
 #include <plat/prcm.h>
-#include <plat/gpmc.h>
+#include "gpmc.h"
 #include <plat/dma.h>
 
 #include "common.h"
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 7a85ebe..8ee73fc 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -18,7 +18,7 @@
 
 #include <linux/usb/musb.h>
 
-#include <plat/gpmc.h>
+#include "gpmc.h"
 
 #include "mux.h"
 
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
deleted file mode 100644
index e08a51a..0000000
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * General-Purpose Memory Controller for OMAP2
- *
- * Copyright (C) 2005-2006 Nokia Corporation
- *
- * 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.
- */
-
-#ifndef __OMAP2_GPMC_H
-#define __OMAP2_GPMC_H
-
-#include <linux/platform_data/mtd-nand-omap2.h>
-
-/* Maximum Number of Chip Selects */
-#define GPMC_CS_NUM		8
-
-#define GPMC_CS_CONFIG1		0x00
-#define GPMC_CS_CONFIG2		0x04
-#define GPMC_CS_CONFIG3		0x08
-#define GPMC_CS_CONFIG4		0x0c
-#define GPMC_CS_CONFIG5		0x10
-#define GPMC_CS_CONFIG6		0x14
-#define GPMC_CS_CONFIG7		0x18
-#define GPMC_CS_NAND_COMMAND	0x1c
-#define GPMC_CS_NAND_ADDRESS	0x20
-#define GPMC_CS_NAND_DATA	0x24
-
-/* Control Commands */
-#define GPMC_CONFIG_RDY_BSY	0x00000001
-#define GPMC_CONFIG_DEV_SIZE	0x00000002
-#define GPMC_CONFIG_DEV_TYPE	0x00000003
-#define GPMC_SET_IRQ_STATUS	0x00000004
-#define GPMC_CONFIG_WP		0x00000005
-
-#define GPMC_ENABLE_IRQ		0x0000000d
-
-/* ECC commands */
-#define GPMC_ECC_READ		0 /* Reset Hardware ECC for read */
-#define GPMC_ECC_WRITE		1 /* Reset Hardware ECC for write */
-#define GPMC_ECC_READSYN	2 /* Reset before syndrom is read back */
-
-#define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
-#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
-#define GPMC_CONFIG1_READTYPE_ASYNC     (0 << 29)
-#define GPMC_CONFIG1_READTYPE_SYNC      (1 << 29)
-#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
-#define GPMC_CONFIG1_WRITETYPE_ASYNC    (0 << 27)
-#define GPMC_CONFIG1_WRITETYPE_SYNC     (1 << 27)
-#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
-#define GPMC_CONFIG1_PAGE_LEN(val)      ((val & 3) << 23)
-#define GPMC_CONFIG1_WAIT_READ_MON      (1 << 22)
-#define GPMC_CONFIG1_WAIT_WRITE_MON     (1 << 21)
-#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
-#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val & 3) << 16)
-#define GPMC_CONFIG1_DEVICESIZE(val)    ((val & 3) << 12)
-#define GPMC_CONFIG1_DEVICESIZE_16      GPMC_CONFIG1_DEVICESIZE(1)
-#define GPMC_CONFIG1_DEVICETYPE(val)    ((val & 3) << 10)
-#define GPMC_CONFIG1_DEVICETYPE_NOR     GPMC_CONFIG1_DEVICETYPE(0)
-#define GPMC_CONFIG1_MUXADDDATA         (1 << 9)
-#define GPMC_CONFIG1_TIME_PARA_GRAN     (1 << 4)
-#define GPMC_CONFIG1_FCLK_DIV(val)      (val & 3)
-#define GPMC_CONFIG1_FCLK_DIV2          (GPMC_CONFIG1_FCLK_DIV(1))
-#define GPMC_CONFIG1_FCLK_DIV3          (GPMC_CONFIG1_FCLK_DIV(2))
-#define GPMC_CONFIG1_FCLK_DIV4          (GPMC_CONFIG1_FCLK_DIV(3))
-#define GPMC_CONFIG7_CSVALID		(1 << 6)
-
-#define GPMC_DEVICETYPE_NOR		0
-#define GPMC_DEVICETYPE_NAND		2
-#define GPMC_CONFIG_WRITEPROTECT	0x00000010
-#define WR_RD_PIN_MONITORING		0x00600000
-#define GPMC_IRQ_FIFOEVENTENABLE	0x01
-#define GPMC_IRQ_COUNT_EVENT		0x02
-
-
-/* bool type time settings */
-struct gpmc_bool_timings {
-	bool cycle2cyclediffcsen;
-	bool cycle2cyclesamecsen;
-	bool we_extra_delay;
-	bool oe_extra_delay;
-	bool adv_extra_delay;
-	bool cs_extra_delay;
-	bool time_para_granularity;
-};
-
-/*
- * Note that all values in this struct are in nanoseconds except sync_clk
- * (which is in picoseconds), while the register values are in gpmc_fck cycles.
- */
-struct gpmc_timings {
-	/* Minimum clock period for synchronous mode (in picoseconds) */
-	u32 sync_clk;
-
-	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
-
-	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
-
-	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
-
-	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
-
-	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
-
-	u16 bus_turnaround;
-	u16 cycle2cycle_delay;
-
-	u16 wait_monitoring;
-	u16 clk_activation;
-
-	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
-
-	struct gpmc_bool_timings bool_timings;
-};
-
-extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
-extern int gpmc_get_client_irq(unsigned irq_config);
-
-extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
-extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
-extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
-extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
-extern unsigned long gpmc_get_fclk_period(void);
-
-extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
-extern u32 gpmc_cs_read_reg(int cs, int idx);
-extern int gpmc_calc_divider(unsigned int sync_clk);
-extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
-extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
-extern void gpmc_cs_free(int cs);
-extern int gpmc_cs_set_reserved(int cs, int reserved);
-extern int gpmc_cs_reserved(int cs);
-extern void omap3_gpmc_save_context(void);
-extern void omap3_gpmc_restore_context(void);
-extern int gpmc_cs_configure(int cs, int cmd, int wval);
-
-#endif
-- 
1.7.12



From afzal at ti.com  Mon Oct  8 01:39:22 2012
From: afzal at ti.com (Mohammed, Afzal)
Date: Mon, 8 Oct 2012 05:39:22 +0000
Subject: [PATCH 00/15] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <cover.1349450454.git.afzal@ti.com>
References: <cover.1349450454.git.afzal@ti.com>
Message-ID: <C8443D0743D26F4388EA172BF4E2A7A93E9F7A62@DBDE01.ent.ti.com>

Hi,

On Fri, Oct 05, 2012 at 21:22:50, Mohammed, Afzal wrote:

> This series cleans up omap-gpmc related code so that omap can
> be a part of common zImage.

Upon selecting BCH CONFIG option, build breaks, updated
series - v2 that fixes it has been posted.

Regards
Afzal

From panhuangaebu at sohu.com  Mon Oct  8 01:40:57 2012
From: panhuangaebu at sohu.com (=?GB2312?B?MjAxM7n6vNK/xry8z+7Ev9eoz+7Xyr3wyeqxqA==?=)
Date: Mon, 08 Oct 2012 05:40:57 -0000
Subject: =?GB2312?B?MjAxM7n6vNK/xry8z+7Ev9eoz+7Xyr3wyeqxqPTftLTQws/uxL/J6rGoudzA?=
 =?GB2312?B?7cqmxeDRtSCxsb6pIKOoMTEuMi0xMS41o6k=?=
Message-ID: <201210081334587425571@sohu.com>

?????????????????????
??? ? ?? ???            
   ?? ?  ??010?58546979
?? ?   ??010?58546980         
??EMAIL?china_gyhxxhb at vip.188.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121008/33e84c3c/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 2013???????????????????????? ?? ?11.2-11.5?.doc
Type: application/octet-stream
Size: 258560 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121008/33e84c3c/attachment.obj>

From afzal at ti.com  Mon Oct  8 02:08:08 2012
From: afzal at ti.com (Mohammed, Afzal)
Date: Mon, 8 Oct 2012 06:08:08 +0000
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <cover.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
Message-ID: <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>

Hi Ivan,

On Mon, Oct 08, 2012 at 11:05:56, Mohammed, Afzal wrote:

> This series cleans up omap-gpmc related code so that omap can
> be a part of common zImage.

> This series moves gpmc.h from plat-omap/include/plat to mach-omap2
> so that header file is local.

> Patches 7 & 8 cleans up the already moved platform data header files
> to contain only platform data. Also gpmc-nand information is moved
> to nand platform data header.
> 
> Patches 9-13 makes nand driver independent of gpmc header file
> 
> And the final patch localizes gpmc header.

BCH[48] support that you have added on OMAP using gpmc exported
symbols has been changed such that nand driver now takes care
of BCH support without relying on gpmc exported symbols.

This is more or less a cut & paste of your implementation, which was
necessitated now due to common ARM zImage cleanup w.r.t header files.

Please verify that BCH[48] works as earlier with this series.

Regards
Afzal

> This series is available
>         @ git://gitorious.org/x0148406-public/linux-kernel.git gpmc-czimage-v2
> and is based on
>         linux-next (next-20121005)
> and is dependent on
> 	http://marc.info/?l=linux-omap&m=134945131602622&w=2

From josh.wu at atmel.com  Mon Oct  8 02:46:49 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Mon,  8 Oct 2012 14:46:49 +0800
Subject: [PATCH] MTD: atmel_nand: fix compile error when use
 avr32-atstk1006_defconfig
Message-ID: <1349678809-12092-1-git-send-email-josh.wu@atmel.com>

fixed the following compile error when use avr32 config:
drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'

Since in ARCH avr32, there is no macro "writel_relaxed" defined. In this patch we use macro "writel" instead.

Signed-off-by: Josh Wu <josh.wu at atmel.com>
---
 drivers/mtd/nand/atmel_nand_ecc.h |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
index 8a1e9a6..e87af84 100644
--- a/drivers/mtd/nand/atmel_nand_ecc.h
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -129,8 +129,13 @@
 #define pmerrloc_writel(addr, reg, value) \
 	writel((value), (addr) + ATMEL_PMERRLOC_##reg)
 
+#if defined(CONFIG_ARCH_AT91)
 #define pmerrloc_writel_sigma_relaxed(addr, n, value) \
 	writel_relaxed((value), (addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+#elif defined(CONFIG_AVR32)
+#define pmerrloc_writel_sigma_relaxed(addr, n, value) \
+	writel((value), (addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+#endif
 
 #define pmerrloc_readl_sigma_relaxed(addr, n) \
 	readl_relaxed((addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
-- 
1.7.9.5



From gregor.boirie at parrot.com  Mon Oct  8 04:10:06 2012
From: gregor.boirie at parrot.com (=?UTF-8?B?R3LDqWdvciBCb2lyaWU=?=)
Date: Mon, 8 Oct 2012 10:10:06 +0200
Subject: [PATCH] mtd: m25p80: fix missing MTD module owner
Message-ID: <50728A5E.3020102@parrot.com>

Marek,

Sorry about that. I didn't really mean to submit an official patch at
first...
Nevermind, please find one just below.

Regards,
gregor

---
 drivers/mtd/devices/m25p80.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 1924d24..06beb3f 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -873,6 +873,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
 	else
 		flash->mtd.name = dev_name(&spi->dev);
 +	flash->mtd.owner = THIS_MODULE;
 	flash->mtd.type = MTD_NORFLASH;
 	flash->mtd.writesize = 1;
 	flash->mtd.flags = MTD_CAP_NORFLASH;
-- 
1.7.4.1



From Thomas.Betker at rohde-schwarz.com  Mon Oct  8 04:25:59 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Mon, 8 Oct 2012 10:25:59 +0200
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
In-Reply-To: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>
References: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>
Message-ID: <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>

Hello Joakim,

I am not sure if it is okay to call jffs2_complete_reservation() without a 
previous jffs2_reserve_space(), so I have avoided that in my own patch.

Also, I am not happy with using ret to check if 
jffs2_complete_reservation() was done; I am using alloc_len for that.

"jffs2_dbg(1, "%s()\n", __func__);" comes a bit late.

And "be be" in the first comment should probably read "be done".

I am attaching my own patch for comparison (sorry, I haven't found yet a 
way to send the patch inline); the tests are running this morning.

Best regards,
Thomas

-------------- next part --------------
A non-text attachment was scrubbed...
Name: jffs2_write_begin-v2.patch
Type: application/octet-stream
Size: 2569 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121008/2fa5b545/attachment.obj>

From joakim.tjernlund at transmode.se  Mon Oct  8 04:48:04 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Mon, 8 Oct 2012 10:48:04 +0200
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
In-Reply-To: <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>
References: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>
 <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>
Message-ID: <OFDA2AD2F6.2BD9C5E0-ONC1257A91.003021EB-C1257A91.003058E4@transmode.se>

>
> Hello Joakim,
>
> I am not sure if it is okay to call jffs2_complete_reservation() without a
> previous jffs2_reserve_space(), so I have avoided that in my own patch.
>
> Also, I am not happy with using ret to check if
> jffs2_complete_reservation() was done; I am using alloc_len for that.
>
> "jffs2_dbg(1, "%s()\n", __func__);" comes a bit late.
>
> And "be be" in the first comment should probably read "be done".

Agreed on all above points, thanks.

>
> I am attaching my own patch for comparison (sorry, I haven't found yet a
> way to send the patch inline); the tests are running this morning.

Right, I don't send inline paches with Notes, I use git send-email

 Jocke



From dedekind1 at gmail.com  Mon Oct  8 07:17:10 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 08 Oct 2012 14:17:10 +0300
Subject: [GIT PULL] UBI fastmap for 3.7-rc1
Message-ID: <1349695030.1992.48.camel@sauron.fi.intel.com>

Hi Linus,

here is the second UBI pull request which contains a big new
experimental feature. Please, pull with my apologies that it was exposed
to linux-next for shorter time than I usually do. Details are in the
signed tag.

Thanks!

The following changes since commit 55393ba1bdedc5ded79b34b4cc08898a7776cddb:

  UBI: fix trivial typo 'it' => 'is' (2012-09-26 13:22:50 +0300)

are available in the git repository at:

  git://git.infradead.org/linux-ubi.git tags/upstream-3.7-rc1-fastmap

for you to fetch changes up to 76ac66e469f084d41742ba08923de76fbdc7dce3:

  UBI: Wire-up fastmap (2012-10-03 16:39:37 +0300)

----------------------------------------------------------------
This pull request contains the UBI fastmap support implemented by Richard
Weinberger from Linutronix. Fastmap is designed to address UBI's slow scanning
issues. Namely, it introduces a new on-flash data-structure called "fastmap",
which stores the information about logical<->physical eraseblocks mappings.
So now to get this information just read the fastmap, instead of doing full
scan. More information here can be found in Richard's announcement in LKML
(Subject: UBI: Fastmap request for inclusion (v19)):

http://thread.gmane.org/gmane.linux.kernel/1364922/focus=1369109

One thing I want to explicitly say is that fastmap did not have large
enough linux-next exposure. It is partially my fault - I did not respond
quickly enough. I _really_ apologize for this. But it had good testing and
disabled by default, so I do not expect that we'll break anything.

Fastmap is declared as experimental so far, and it is off by default. We
did declare that the on-flash format may be changed. The reason for this is
that no one used it in real production so far, so there is a high risk that
something is missing. Besides, we do not have user-space tools supporting
fastmap so far.

Nevertheless, I suggest we merge this feature. Many people want UBI's scanning
bottleneck to be fixed and merging fastmap now should accelerate its production
use. The plan is to make it bullet-prove, somewhat clean-up, and make it the
default for UBI. I do not know how many kernel releases will it take.

Basically, I what I want to do for fastmap is something like Linus did for
btrfs few years ago.

----------------------------------------------------------------
Richard Weinberger (10):
      UBI: Add fastmap on-flash data structures
      UBI: Add fastmap stuff to ubi.h
      UBI: Export next_sqnum()
      UBI: Add self_check_eba()
      UBI: Add fastmap bits to build.c
      UBI: Wire-up ->fm_sem
      UBI: Add fastmap stuff to attach.c
      UBI: Add fastmap support to the WL sub-system
      UBI: Add fastmap core
      UBI: Wire-up fastmap

 MAINTAINERS                 |    6 +
 drivers/mtd/ubi/Kconfig     |   21 +++
 drivers/mtd/ubi/Makefile    |    1 +
 drivers/mtd/ubi/attach.c    |  386 ++++++++++++++++++++++++++++++++----------------
 drivers/mtd/ubi/build.c     |   70 ++++++++-
 drivers/mtd/ubi/eba.c       |  126 ++++++++++++++--
 drivers/mtd/ubi/fastmap.c   | 1537 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/ubi/ubi-media.h |  137 +++++++++++++++++
 drivers/mtd/ubi/ubi.h       |  118 ++++++++++++++-
 drivers/mtd/ubi/wl.c        |  599 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 10 files changed, 2790 insertions(+), 211 deletions(-)
 create mode 100644 drivers/mtd/ubi/fastmap.c

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121008/4019a1b6/attachment.sig>

From marex at denx.de  Mon Oct  8 09:09:44 2012
From: marex at denx.de (Marek Vasut)
Date: Mon, 8 Oct 2012 15:09:44 +0200
Subject: [PATCH] mtd: m25p80: fix missing MTD module owner
In-Reply-To: <50728A5E.3020102@parrot.com>
References: <50728A5E.3020102@parrot.com>
Message-ID: <201210081509.44802.marex@denx.de>

Dear Gr?gor Boirie,

> Marek,
> 
> Sorry about that. I didn't really mean to submit an official patch at
> first...

No no, nothing to be sorry about actually, we're really grateful you spotted the 
issue and reported it!

> Nevermind, please find one just below.

Actually, can you try one more time and after commiting the change to your local 
git tree, do "git send-email --to="linux-mtd at lists.infradead.org" HEAD~1" 
please?

Also, it is a good idea to add "Cc: Name Surname <e at ma.il>" lines to the patch 
description just before the Signed-off-by line so that the people who will end 
up applying it are CCed. That's at least Artem.

> Regards,
> gregor
> 
> ---
>  drivers/mtd/devices/m25p80.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 1924d24..06beb3f 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -873,6 +873,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
>  	else
>  		flash->mtd.name = dev_name(&spi->dev);
>  +	flash->mtd.owner = THIS_MODULE;
>  	flash->mtd.type = MTD_NORFLASH;
>  	flash->mtd.writesize = 1;
>  	flash->mtd.flags = MTD_CAP_NORFLASH;

Best regards,
Marek Vasut


From ricard.wanderlof at axis.com  Mon Oct  8 09:57:58 2012
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Mon, 8 Oct 2012 15:57:58 +0200
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.LNX.2.02.1210051949390.1375@bas>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
Message-ID: <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>


On Fri, 5 Oct 2012, kyak wrote:

> I observe the same problem with any other directory (namely, with my
> /home, which is not reabable).
>
> When one of the directories in "-d" hierarchy is not readable, 
> mkfs.ubifs will fail all the time, thinking that the output file is 
> located in UBIFS root directory.

I can agree with you that the error message looks wrong for this case, but 
what is the point of attempting to create a file system image from a 
directory tree which is not readable?

/Ricard

>
> On Wed, 3 Oct 2012, kyak wrote:
>
>> Hi,
>>
>> Consider the following sequence of commands:
>>
>> cd ~
>> mkdir -p /tmp/wtf/wtf1
>> chmod u-r /tmp/wtf
>> mkfs.ubifs -m 4096 -e 516096 -c 4095 -d /tmp/wtf/wtf1 -o mytest.img
>> Error: output file cannot be in the UBIFS root directory
>>
>> mytest.img is not inside /tmp/wtf/wtf1, but mkfs.ubifs fails because /tmp/wtf
>> is not readable.
>> It seems that implementation of in_path(..) in mkfs.ubifs.c is not quite
>> correct to handle this type of situations.
>>
>> If you are wondering, my /home is not readable, and this prevents me from
>> building any ubifs image inside of /home/user.
>>
>> Thanks in advance.
>>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>

-- 
Ricard Wolf Wanderl?f                           ricardw(at)axis.com
Axis Communications AB, Lund, Sweden            www.axis.com
Phone +46 46 272 2016                           Fax +46 46 13 61 30


From bas at bmail.ru  Mon Oct  8 10:40:38 2012
From: bas at bmail.ru (kyak)
Date: Mon, 8 Oct 2012 18:40:38 +0400 (MSK)
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
 <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
Message-ID: <alpine.LNX.2.02.1210081833560.1375@bas>

If a directory is not readable it only means that you can't list its 
contents. But it doesn't mean that you can't list contents of directories 
below that directory.

Once again, here is a simple (my) use case. My /home is not readable (i 
can't list its contents), and this prevents me from building any ubifs 
image inside of /home/user (which is readable).

I really hope i made myself clear this time.

On Mon, 8 Oct 2012, Ricard Wanderlof wrote:

>
> On Fri, 5 Oct 2012, kyak wrote:
>
>> I observe the same problem with any other directory (namely, with my
>> /home, which is not reabable).
>> 
>> When one of the directories in "-d" hierarchy is not readable, mkfs.ubifs 
>> will fail all the time, thinking that the output file is located in UBIFS 
>> root directory.
>
> I can agree with you that the error message looks wrong for this case, but 
> what is the point of attempting to create a file system image from a 
> directory tree which is not readable?
>
> /Ricard
>
>> 
>> On Wed, 3 Oct 2012, kyak wrote:
>> 
>>> Hi,
>>> 
>>> Consider the following sequence of commands:
>>> 
>>> cd ~
>>> mkdir -p /tmp/wtf/wtf1
>>> chmod u-r /tmp/wtf
>>> mkfs.ubifs -m 4096 -e 516096 -c 4095 -d /tmp/wtf/wtf1 -o mytest.img
>>> Error: output file cannot be in the UBIFS root directory
>>> 
>>> mytest.img is not inside /tmp/wtf/wtf1, but mkfs.ubifs fails because 
>>> /tmp/wtf
>>> is not readable.
>>> It seems that implementation of in_path(..) in mkfs.ubifs.c is not quite
>>> correct to handle this type of situations.
>>> 
>>> If you are wondering, my /home is not readable, and this prevents me from
>>> building any ubifs image inside of /home/user.
>>> 
>>> Thanks in advance.
>>> 
>> 
>> ______________________________________________________
>> Linux MTD discussion mailing list
>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>> 
>
> -- 
> Ricard Wolf Wanderl?f                           ricardw(at)axis.com
> Axis Communications AB, Lund, Sweden            www.axis.com
> Phone +46 46 272 2016                           Fax +46 46 13 61 30
>

From ricard.wanderlof at axis.com  Mon Oct  8 10:53:51 2012
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Mon, 8 Oct 2012 16:53:51 +0200
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.LNX.2.02.1210081833560.1375@bas>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
 <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081833560.1375@bas>
Message-ID: <alpine.DEB.2.00.1210081650200.19047@lnxricardw.se.axis.com>


On Mon, 8 Oct 2012, kyak wrote:

> If a directory is not readable it only means that you can't list its
> contents. But it doesn't mean that you can't list contents of directories
> below that directory.
>
> Once again, here is a simple (my) use case. My /home is not readable (i
> can't list its contents), and this prevents me from building any ubifs
> image inside of /home/user (which is readable).
>
> I really hope i made myself clear this time.

Definitely. I see your point now. This must be a definite bug in 
in_path().

One problem though is that when in_path() traverses the tree upwards, and 
encounters a directory which it can't read it can't complete its job. On 
the other hand, it shouldn't have to do that, it really only needs to see 
that the output file is not below the top level of the input tree. Or am I 
missing a case here?

/Ricard
-- 
Ricard Wolf Wanderl?f                           ricardw(at)axis.com
Axis Communications AB, Lund, Sweden            www.axis.com
Phone +46 46 272 2016                           Fax +46 46 13 61 30


From dinguyen at altera.com  Mon Oct  8 11:59:16 2012
From: dinguyen at altera.com (dinguyen at altera.com)
Date: Mon, 8 Oct 2012 09:59:16 -0600
Subject: nand/denali: split the driver into 3 parts: generic, PCI and DT
Message-ID: <1349711958-19362-1-git-send-email-dinguyen@altera.com>

Hi,

Resend. Would appreciate any kinda of comments.

---
The following 2 patches attempts to make the current Denali NAND controller,
which is PCI-based, to be both PCI and device tree drivers.

The first patch is a resend of Jami Iles patch with only minor changes on the
commit message and checkpatch errors and warnings. This patch was originally
sent in this message:

http://lists.infradead.org/pipermail/linux-mtd/2011-May/035334.html

The second patch is also based on Jamie Iles' patch to add a MMIO version of
the Denali NAND driver. I converted to be DT based.

I think there were comments to make it fully DT, but since I don't have a
PCI-base hardware to test this, I don't want to break it. I can only test the
DT version on the HW that I have access to.

.../devicetree/bindings/mtd/denali-nand.txt        |   23 +++
 drivers/mtd/nand/Kconfig                           |   20 ++-
 drivers/mtd/nand/Makefile                          |    2 +
 drivers/mtd/nand/denali.c                          |  160 ++++---------------
 drivers/mtd/nand/denali.h                          |    5 +
 drivers/mtd/nand/denali_dt.c                       |  167 ++++++++++++++++++++
 drivers/mtd/nand/denali_pci.c                      |  144 +++++++++++++++++
 7 files changed, 386 insertions(+), 135 deletions(-)


Thanks,
Dinh



From dinguyen at altera.com  Mon Oct  8 11:59:17 2012
From: dinguyen at altera.com (dinguyen at altera.com)
Date: Mon, 8 Oct 2012 09:59:17 -0600
Subject: =?UTF-8?q?=5BRESEND=20PATCHv1=201/2=5D=20nand/denali=3A=20split=20the=20generic=20driver=20and=20PCI=20layer?=
In-Reply-To: <1349711958-19362-1-git-send-email-dinguyen@altera.com>
References: <1349711958-19362-1-git-send-email-dinguyen@altera.com>
Message-ID: <1349711958-19362-2-git-send-email-dinguyen@altera.com>

From: Dinh Nguyen <dinguyen at altera.com>

The Denali controller can also be found in SoC devices attached to a
simple bus.  Move the PCI specific parts into denali_pci so that we can
add a denali_dt that uses the same driver but for a device tree driver
instead of a PCI based device.

Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: Chuanxiao Dong <chuanxiao.dong at intel.com>
Signed-off-by: Jamie Iles <jamie at jamieiles.com>
---
 drivers/mtd/nand/Kconfig      |   11 ++-
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/denali.c     |  160 ++++++++---------------------------------
 drivers/mtd/nand/denali.h     |    4 ++
 drivers/mtd/nand/denali_pci.c |  144 +++++++++++++++++++++++++++++++++++++
 5 files changed, 186 insertions(+), 134 deletions(-)
 create mode 100644 drivers/mtd/nand/denali_pci.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8ca4176..f5659c1 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -66,8 +66,15 @@ config MTD_NAND_AUTCPU12
 	  access the SmartMediaCard.
 
 config MTD_NAND_DENALI
-       depends on PCI
+        tristate "Support Denali NAND controller"
+        help
+	  Enable support for the Denali NAND controller.  This should be
+	  combined with either the PCI or platform drivers to provide device
+	  registration.
+
+config MTD_NAND_DENALI_PCI
         tristate "Support Denali NAND controller on Intel Moorestown"
+	depends on PCI && MTD_NAND_DENALI
         help
           Enable the driver for NAND flash on Intel Moorestown, using the
           Denali NAND controller core.
@@ -75,7 +82,7 @@ config MTD_NAND_DENALI
 config MTD_NAND_DENALI_SCRATCH_REG_ADDR
         hex "Denali NAND size scratch register address"
         default "0xFF108018"
-        depends on MTD_NAND_DENALI
+        depends on MTD_NAND_DENALI_PCI
         help
           Some platforms place the NAND chip size in a scratch register
           because (some versions of) the driver aren't able to automatically
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4b4d87..0b3c9e2 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_NAND_SPIA)		+= spia.o
 obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)		+= autcpu12.o
 obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
+obj-$(CONFIG_MTD_NAND_DENALI_PCI)	+= denali_pci.o
 obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 0650aaf..870c542 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -16,14 +16,12 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
-
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/mtd/mtd.h>
 #include <linux/module.h>
 
@@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."
  * format the bank into the proper bits for the controller */
 #define BANK(x) ((x) << 24)
 
-/* List of platforms this NAND controller has be integrated into */
-static const struct pci_device_id denali_pci_ids[] = {
-	{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
-	{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
-	{ /* end: all zeroes */ }
-};
-
 /* forward declarations */
 static void clear_interrupts(struct denali_nand_info *denali);
 static uint32_t wait_for_irq(struct denali_nand_info *denali,
@@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)
 
 	if (comp_res == 0) {
 		/* timeout */
-		printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n",
+		pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n",
 				intr_status, irq_mask);
 
 		intr_status = 0;
@@ -1303,8 +1294,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
 		/* TODO: Read OOB data */
 		break;
 	default:
-		printk(KERN_ERR ": unsupported command"
-				" received 0x%x\n", cmd);
+		pr_err(": unsupported command received 0x%x\n", cmd);
 		break;
 	}
 }
@@ -1423,107 +1413,48 @@ void denali_drv_init(struct denali_nand_info *denali)
 	denali->irq_status = 0;
 }
 
-/* driver entry point */
-static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+int denali_init(struct denali_nand_info *denali)
 {
-	int ret = -ENODEV;
-	resource_size_t csr_base, mem_base;
-	unsigned long csr_len, mem_len;
-	struct denali_nand_info *denali;
-
-	denali = kzalloc(sizeof(*denali), GFP_KERNEL);
-	if (!denali)
-		return -ENOMEM;
+	int ret;
 
-	ret = pci_enable_device(dev);
-	if (ret) {
-		printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
-		goto failed_alloc_memery;
-	}
-
-	if (id->driver_data == INTEL_CE4100) {
+	if (denali->platform == INTEL_CE4100) {
 		/* Due to a silicon limitation, we can only support
 		 * ONFI timing mode 1 and below.
 		 */
 		if (onfi_timing_mode < -1 || onfi_timing_mode > 1) {
-			printk(KERN_ERR "Intel CE4100 only supports"
-					" ONFI timing mode 1 or below\n");
-			ret = -EINVAL;
-			goto failed_enable_dev;
-		}
-		denali->platform = INTEL_CE4100;
-		mem_base = pci_resource_start(dev, 0);
-		mem_len = pci_resource_len(dev, 1);
-		csr_base = pci_resource_start(dev, 1);
-		csr_len = pci_resource_len(dev, 1);
-	} else {
-		denali->platform = INTEL_MRST;
-		csr_base = pci_resource_start(dev, 0);
-		csr_len = pci_resource_len(dev, 0);
-		mem_base = pci_resource_start(dev, 1);
-		mem_len = pci_resource_len(dev, 1);
-		if (!mem_len) {
-			mem_base = csr_base + csr_len;
-			mem_len = csr_len;
+			pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n");
+			return -EINVAL;
 		}
 	}
 
 	/* Is 32-bit DMA supported? */
-	ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
 	if (ret) {
-		printk(KERN_ERR "Spectra: no usable DMA configuration\n");
-		goto failed_enable_dev;
+		pr_err("Spectra: no usable DMA configuration\n");
+		return ret;
 	}
-	denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf,
+	denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
 					     DENALI_BUF_SIZE,
 					     DMA_BIDIRECTIONAL);
 
-	if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) {
-		dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n");
-		goto failed_enable_dev;
-	}
-
-	pci_set_master(dev);
-	denali->dev = &dev->dev;
-	denali->mtd.dev.parent = &dev->dev;
-
-	ret = pci_request_regions(dev, DENALI_NAND_NAME);
-	if (ret) {
-		printk(KERN_ERR "Spectra: Unable to request memory regions\n");
-		goto failed_dma_map;
-	}
-
-	denali->flash_reg = ioremap_nocache(csr_base, csr_len);
-	if (!denali->flash_reg) {
-		printk(KERN_ERR "Spectra: Unable to remap memory region\n");
-		ret = -ENOMEM;
-		goto failed_req_regions;
-	}
-
-	denali->flash_mem = ioremap_nocache(mem_base, mem_len);
-	if (!denali->flash_mem) {
-		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
-		ret = -ENOMEM;
-		goto failed_remap_reg;
+	if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
+		dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
+		return -EIO;
 	}
-
+	denali->mtd.dev.parent = denali->dev;
 	denali_hw_init(denali);
 	denali_drv_init(denali);
 
 	/* denali_isr register is done after all the hardware
 	 * initilization is finished*/
-	if (request_irq(dev->irq, denali_isr, IRQF_SHARED,
+	if (request_irq(denali->irq, denali_isr, IRQF_SHARED,
 			DENALI_NAND_NAME, denali)) {
-		printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
-		ret = -ENODEV;
-		goto failed_remap_mem;
+		pr_err("Spectra: Unable to allocate IRQ\n");
+		return -ENODEV;
 	}
 
 	/* now that our ISR is registered, we can enable interrupts */
 	denali_set_intr_modes(denali, true);
-
-	pci_set_drvdata(dev, denali);
-
 	denali->mtd.name = "denali-nand";
 	denali->mtd.owner = THIS_MODULE;
 	denali->mtd.priv = &denali->nand;
@@ -1547,8 +1478,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	 */
 	if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
 		ret = -ENODEV;
-		printk(KERN_ERR "Spectra: device size not supported by this "
-			"version of MTD.");
+		pr_err("Spectra: device size not supported by this version of MTD.");
 		goto failed_req_irq;
 	}
 
@@ -1600,8 +1530,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	} else if (denali->mtd.oobsize < (denali->bbtskipbytes +
 			ECC_8BITS * (denali->mtd.writesize /
 			ECC_SECTOR_SIZE))) {
-		printk(KERN_ERR "Your NAND chip OOB is not large enough to"
-				" contain 8bit ECC correction codes");
+		pr_err("Your NAND chip OOB is not large enough to \
+				contain 8bit ECC correction codes");
 		goto failed_req_irq;
 	} else {
 		denali->nand.ecc.strength = 8;
@@ -1653,56 +1583,22 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
 	ret = mtd_device_register(&denali->mtd, NULL, 0);
 	if (ret) {
-		dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n",
+		dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",
 				ret);
 		goto failed_req_irq;
 	}
 	return 0;
 
 failed_req_irq:
-	denali_irq_cleanup(dev->irq, denali);
-failed_remap_mem:
-	iounmap(denali->flash_mem);
-failed_remap_reg:
-	iounmap(denali->flash_reg);
-failed_req_regions:
-	pci_release_regions(dev);
-failed_dma_map:
-	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-			 DMA_BIDIRECTIONAL);
-failed_enable_dev:
-	pci_disable_device(dev);
-failed_alloc_memery:
-	kfree(denali);
+	denali_irq_cleanup(denali->irq, denali);
+
 	return ret;
 }
 
 /* driver exit point */
-static void denali_pci_remove(struct pci_dev *dev)
+void denali_remove(struct denali_nand_info *denali)
 {
-	struct denali_nand_info *denali = pci_get_drvdata(dev);
-
-	nand_release(&denali->mtd);
-
-	denali_irq_cleanup(dev->irq, denali);
-
-	iounmap(denali->flash_reg);
-	iounmap(denali->flash_mem);
-	pci_release_regions(dev);
-	pci_disable_device(dev);
-	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-			 DMA_BIDIRECTIONAL);
-	pci_set_drvdata(dev, NULL);
-	kfree(denali);
+	denali_irq_cleanup(denali->irq, denali);
+	dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
+			DMA_BIDIRECTIONAL);
 }
-
-MODULE_DEVICE_TABLE(pci, denali_pci_ids);
-
-static struct pci_driver denali_pci_driver = {
-	.name = DENALI_NAND_NAME,
-	.id_table = denali_pci_ids,
-	.probe = denali_pci_probe,
-	.remove = denali_pci_remove,
-};
-
-module_pci_driver(denali_pci_driver);
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index fabb9d5..e5aa995 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -487,6 +487,7 @@ struct denali_nand_info {
 	uint32_t irq_status;
 	int irq_debug_array[32];
 	int idx;
+	int irq;
 
 	uint32_t devnum;	/* represent how many nands connected */
 	uint32_t fwblks; /* represent how many blocks FW used */
@@ -496,4 +497,7 @@ struct denali_nand_info {
 	uint32_t max_banks;
 };
 
+extern int denali_init(struct denali_nand_info *denali);
+extern void denali_remove(struct denali_nand_info *denali);
+
 #endif /*_LLD_NAND_*/
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
new file mode 100644
index 0000000..ea074e6
--- /dev/null
+++ b/drivers/mtd/nand/denali_pci.c
@@ -0,0 +1,144 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright ? 2009-2010, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#include "denali.h"
+
+#define DENALI_NAND_NAME    "denali-nand-pci"
+
+/* List of platforms this NAND controller has be integrated into */
+static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = {
+	{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
+	{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
+	{ /* end: all zeroes */ }
+};
+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;
+	resource_size_t csr_base, mem_base;
+	unsigned long csr_len, mem_len;
+	struct denali_nand_info *denali;
+
+	denali = kzalloc(sizeof(*denali), GFP_KERNEL);
+	if (!denali)
+		return -ENOMEM;
+
+	ret = pci_enable_device(dev);
+	if (ret) {
+		pr_err("Spectra: pci_enable_device failed.\n");
+		goto failed_alloc_memery;
+	}
+
+	if (id->driver_data == INTEL_CE4100) {
+		denali->platform = INTEL_CE4100;
+		mem_base = pci_resource_start(dev, 0);
+		mem_len = pci_resource_len(dev, 1);
+		csr_base = pci_resource_start(dev, 1);
+		csr_len = pci_resource_len(dev, 1);
+	} else {
+		denali->platform = INTEL_MRST;
+		csr_base = pci_resource_start(dev, 0);
+		csr_len = pci_resource_len(dev, 0);
+		mem_base = pci_resource_start(dev, 1);
+		mem_len = pci_resource_len(dev, 1);
+		if (!mem_len) {
+			mem_base = csr_base + csr_len;
+			mem_len = csr_len;
+		}
+	}
+
+	pci_set_master(dev);
+	denali->dev = &dev->dev;
+	denali->irq = dev->irq;
+
+	ret = pci_request_regions(dev, DENALI_NAND_NAME);
+	if (ret) {
+		pr_err("Spectra: Unable to request memory regions\n");
+		goto failed_enable_dev;
+	}
+
+	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;
+	}
+
+	denali->flash_mem = ioremap_nocache(mem_base, mem_len);
+	if (!denali->flash_mem) {
+		pr_err("Spectra: ioremap_nocache failed!");
+		ret = -ENOMEM;
+		goto failed_remap_reg;
+	}
+
+	ret = denali_init(denali);
+	if (ret)
+		goto failed_remap_mem;
+
+	pci_set_drvdata(dev, denali);
+
+	return 0;
+
+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;
+}
+
+/* driver exit point */
+static void denali_pci_remove(struct pci_dev *dev)
+{
+	struct denali_nand_info *denali = pci_get_drvdata(dev);
+
+	denali_remove(denali);
+	iounmap(denali->flash_reg);
+	iounmap(denali->flash_mem);
+	pci_release_regions(dev);
+	pci_disable_device(dev);
+	pci_set_drvdata(dev, NULL);
+	kfree(denali);
+}
+
+static struct pci_driver denali_pci_driver = {
+	.name = DENALI_NAND_NAME,
+	.id_table = denali_pci_ids,
+	.probe = denali_pci_probe,
+	.remove = denali_pci_remove,
+};
+
+static int __devinit denali_init_pci(void)
+{
+	pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__);
+	return pci_register_driver(&denali_pci_driver);
+}
+module_init(denali_init_pci);
+
+static void __devexit denali_exit_pci(void)
+{
+	pci_unregister_driver(&denali_pci_driver);
+}
+module_exit(denali_exit_pci);
-- 
1.7.9.5




From dinguyen at altera.com  Mon Oct  8 11:59:18 2012
From: dinguyen at altera.com (dinguyen at altera.com)
Date: Mon, 8 Oct 2012 09:59:18 -0600
Subject: =?UTF-8?q?=5BRESEND=20PATCHv1=202/2=5D=20nand/denali=3A=20add=20a=20DT=20driver?=
In-Reply-To: <1349711958-19362-1-git-send-email-dinguyen@altera.com>
References: <1349711958-19362-1-git-send-email-dinguyen@altera.com>
Message-ID: <1349711958-19362-3-git-send-email-dinguyen@altera.com>

From: Dinh Nguyen <dinguyen at altera.com>

Add a device tree version of the Denali NAND driver. Based
on an original patch from Jamie Iles to add a MMIO version
of this driver.

Signed-off-by: Dinh Nguyen <dinguyen at altera.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: Chuanxiao Dong <chuanxiao.dong at intel.com>
Cc: Jamie Iles <jamie at jamieiles.com>
---
 .../devicetree/bindings/mtd/denali-nand.txt        |   23 +++
 drivers/mtd/nand/Kconfig                           |    9 +-
 drivers/mtd/nand/Makefile                          |    1 +
 drivers/mtd/nand/denali.h                          |    1 +
 drivers/mtd/nand/denali_dt.c                       |  167 ++++++++++++++++++++
 5 files changed, 200 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/denali-nand.txt
 create mode 100644 drivers/mtd/nand/denali_dt.c

diff --git a/Documentation/devicetree/bindings/mtd/denali-nand.txt b/Documentation/devicetree/bindings/mtd/denali-nand.txt
new file mode 100644
index 0000000..b04d03a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/denali-nand.txt
@@ -0,0 +1,23 @@
+* Denali NAND controller
+
+Required properties:
+  - compatible : should be "denali,denali-nand-dt"
+  - reg : should contain registers location and length for data and reg.
+  - reg-names: Should contain the reg names "nand_data" and "denali_reg"
+  - interrupts : The interrupt number.
+  - dm-mask : DMA bit mask
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Examples:
+
+nand: nand at ff900000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "denali,denali-nand-dt";
+	reg = <0xff900000 0x100000>, <0xffb80000 0x10000>;
+	reg-names = "nand_data", "denali_reg";
+	interrupts = <0 144 4>;
+	dma-mask = <0xffffffff>;
+};
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index f5659c1..2f6ace3 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -78,7 +78,14 @@ config MTD_NAND_DENALI_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
+	help
+	  Enable the driver for NAND flash on platforms using a Denali NAND
+	  controller as a DT device.
+
 config MTD_NAND_DENALI_SCRATCH_REG_ADDR
         hex "Denali NAND size scratch register address"
         default "0xFF108018"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 0b3c9e2..50d6970 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AMS_DELTA)	+= ams-delta.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)		+= autcpu12.o
 obj-$(CONFIG_MTD_NAND_DENALI)		+= denali.o
 obj-$(CONFIG_MTD_NAND_DENALI_PCI)	+= denali_pci.o
+obj-$(CONFIG_MTD_NAND_DENALI_DT)	+= denali_dt.o
 obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index e5aa995..cec5712 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -466,6 +466,7 @@ struct nand_buf {
 
 #define INTEL_CE4100	1
 #define INTEL_MRST	2
+#define DT		3
 
 struct denali_nand_info {
 	struct mtd_info mtd;
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c
new file mode 100644
index 0000000..fbabbaa
--- /dev/null
+++ b/drivers/mtd/nand/denali_dt.c
@@ -0,0 +1,167 @@
+/*
+ * NAND Flash Controller Device Driver for DT
+ *
+ * Copyright ? 2011, Picochip.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "denali.h"
+
+struct denali_dt {
+	struct denali_nand_info	denali;
+	struct clk		*clk;
+};
+
+static void __iomem *request_and_map(struct device *dev,
+				     const struct resource *res)
+{
+	void __iomem *ptr;
+
+	if (!devm_request_mem_region(dev, res->start, resource_size(res),
+				     "denali-dt")) {
+		dev_err(dev, "unable to request %s\n", res->name);
+		return NULL;
+	}
+
+	ptr = devm_ioremap_nocache(dev, res->start, resource_size(res));
+	if (!res)
+		dev_err(dev, "ioremap_nocache of %s failed!", res->name);
+
+	return ptr;
+}
+
+static const struct of_device_id denali_nand_dt_ids[] = {
+		{ .compatible = "denali,denali-nand-dt" },
+		{ /* sentinel */ }
+	};
+
+MODULE_DEVICE_TABLE(of, denali_nand_dt_ids);
+
+static u64 denali_dma_mask;
+
+static int __devinit denali_dt_probe(struct platform_device *ofdev)
+{
+	struct resource *denali_reg, *nand_data;
+	struct denali_dt *dt;
+	struct denali_nand_info *denali;
+	int ret;
+	const struct of_device_id *of_id;
+
+	of_id = of_match_device(denali_nand_dt_ids, &ofdev->dev);
+	if (of_id) {
+		ofdev->id_entry = of_id->data;
+	} else {
+		pr_err("Failed to find the right device id.\n");
+		return -ENOMEM;
+	}
+
+	dt = devm_kzalloc(&ofdev->dev, sizeof(*dt), GFP_KERNEL);
+	if (!dt)
+		return -ENOMEM;
+	denali = &dt->denali;
+
+	denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg");
+	nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data");
+	if (!denali_reg || !nand_data) {
+		dev_err(&ofdev->dev, "resources not completely defined\n");
+		return -EINVAL;
+	}
+
+	denali->platform = DT;
+	denali->dev = &ofdev->dev;
+	denali->irq = platform_get_irq(ofdev, 0);
+	if (denali->irq < 0) {
+		dev_err(&ofdev->dev, "no irq defined\n");
+		return -ENXIO;
+	}
+
+	denali->flash_reg = request_and_map(&ofdev->dev, denali_reg);
+	if (!denali->flash_reg)
+		return -ENOMEM;
+
+	denali->flash_mem = request_and_map(&ofdev->dev, nand_data);
+	if (!denali->flash_mem)
+		return -ENOMEM;
+
+	if (!of_property_read_u32(ofdev->dev.of_node,
+		"dma-mask", (u32 *)&denali_dma_mask)) {
+		denali->dev->dma_mask = &denali_dma_mask;
+	} else {
+		denali->dev->dma_mask = NULL;
+	}
+
+	dt->clk = clk_get(&ofdev->dev, NULL);
+	if (IS_ERR(dt->clk)) {
+		dev_err(&ofdev->dev, "no clk available\n");
+		return PTR_ERR(dt->clk);
+	}
+	clk_prepare_enable(dt->clk);
+
+	ret = denali_init(denali);
+	if (ret)
+		goto out_disable_clk;
+
+	platform_set_drvdata(ofdev, dt);
+	return 0;
+
+out_disable_clk:
+	clk_disable_unprepare(dt->clk);
+	clk_put(dt->clk);
+
+	return ret;
+}
+
+static int __devexit denali_dt_remove(struct platform_device *ofdev)
+{
+	struct denali_dt *dt = platform_get_drvdata(ofdev);
+
+	denali_remove(&dt->denali);
+	clk_disable(dt->clk);
+	clk_put(dt->clk);
+
+	return 0;
+}
+
+static struct platform_driver denali_dt_driver = {
+	.probe		= denali_dt_probe,
+	.remove		= __devexit_p(denali_dt_remove),
+	.driver		= {
+		.name	= "denali-nand-dt",
+		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(denali_nand_dt_ids),
+	},
+};
+
+static int __init denali_init_dt(void)
+{
+	return platform_driver_register(&denali_dt_driver);
+}
+module_init(denali_init_dt);
+
+static void __exit denali_exit_dt(void)
+{
+	platform_driver_unregister(&denali_dt_driver);
+}
+module_exit(denali_exit_dt);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamie Iles");
+MODULE_DESCRIPTION("DT driver for Denali NAND controller");
-- 
1.7.9.5




From marcus.prebble at axis.com  Mon Oct  8 11:04:56 2012
From: marcus.prebble at axis.com (Marcus Prebble)
Date: Mon, 8 Oct 2012 17:04:56 +0200
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349367416.20373.75.camel@sauron.fi.intel.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
Message-ID: <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>

Hi Artem,

Thanks for your reply - please see below.


On Thu, 2012-10-04 at 18:16 +0200, Artem Bityutskiy wrote:
> On Fri, 2012-09-21 at 17:41 +0200, Marcus Prebble wrote:
> > Hi,
> > 
> > We are working on a project using UBI/UBIFS and I have run into a
> > problem with mkfs.ubifs which I am hoping someone can advise on.
> > Apologies if I have already missed the answer to this in the archives
> > somewhere.
> > 
> > A requirement of the project is to take an image of the root filesystem
> > (/) which is implemented as a static UBI read only volume. Obviously its
> > not possible to unmount /, but it seems to be possible to re-mount the
> > UBI volume, read only, onto another location e.g. /tmp/mnt/new_rootfs.
> > 
> > The problem arises when running mkfs.ubifs is that it fails saying that
> > the output file cannot be in the UBIFS root directory.
> > This sounds like a reasonable constraint if the output file really was
> > in the root, but this is not the case for us seeing root is mounted
> > somewhere belowtmp. To give a concrete example of the command we are
> > running:
> > 
> > mkfs.ubifs --output=/tmp/rootfs.img  --leb-size=129024
> > --root=/tmp/rootfs_mnt --min-io-size=2048 --max-leb-cnt=147 
> > 
> > Where /dev/ubi0_11 is mounted read-only on both / and /tmp/rootfs_mnt/.
> > 
> > Having a look at the source for mkfs.ubifs it seems that the function
> > in_path(..) is the problem - it works up the directory tree using ../
> > until it either reaches the top_dir (/) or the inode number/dev match in
> > which case it fails. It doesn't seem that this section of code has
> > changed in the latest version of mtd-utils (we are running 1.4.3-2) and
> > I wonder if this is a bug in in_path(..) or a genuine safeguard against
> > screwing something up? I suspect the former for when I disabled this
> > check in mkfs.ubifs.c the resulting image was completely OK.
> 
> Well, obviously this is a safeguard check. If your source FS is
> in /a/path/, and the output image file is /a/path/image, then we will
> loop forever reading /a/path/image and writing the output
> to /a/path/image.

I am well aware of the need for a safe-guard check, but I think you
mis-understood my question.

We have remounted a static UBI volume which happens to be the rootfs (/)
onto another location, /tmp/newrootfs
We are trying to make an image of /tmp/newrootfs with mkfs.ubifs and
where the output file is /tmp/newrootfs.img.

In other words, we have /foo/bar/ and /foo/out.img. 
out.img is not in the same directory as bar, so it should be legal to
make an image of /foo/bar/

The problem is that in_path() compares inode numbers, and seeing the
inode numbers are apparently the same for / and /tmp/newrootfs
mkfs.ubifs (wrongly) says the output is in the root directory.

My original question was is there any technical reason why in_path()
compares inode numbers? I.e. is there a risk if you make an image of a
re-mounted RO filesystem of the resulting image being corrupt (or
something)

We have a workaround at moment --disable-root-check but its clearly not
an optimal solution. Another user is also having problems with in_path()
so this function needs looking at. Once we know that this is not the
intended behaviour of in_path() then we are happy to look for a
solution.

Kind regards,

/Marcus Prebble






From bas at bmail.ru  Mon Oct  8 11:13:58 2012
From: bas at bmail.ru (kyak)
Date: Mon, 8 Oct 2012 19:13:58 +0400 (MSK)
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.DEB.2.00.1210081650200.19047@lnxricardw.se.axis.com>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
 <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081833560.1375@bas>
 <alpine.DEB.2.00.1210081650200.19047@lnxricardw.se.axis.com>
Message-ID: <alpine.LNX.2.02.1210081900410.1375@bas>

On Mon, 8 Oct 2012, Ricard Wanderlof wrote:

> Definitely. I see your point now. This must be a definite bug in in_path().
>
> One problem though is that when in_path() traverses the tree upwards, and 
> encounters a directory which it can't read it can't complete its job. On the 
> other hand, it shouldn't have to do that, it really only needs to see that 
> the output file is not below the top level of the input tree. Or am I missing 
> a case here?
>
Yes, it only needs to check if the output file is above the top level
of the input tree. But I guess it's not that easy - first things that come 
into my mind are symbolic links and mount --bind.


From u.kleine-koenig at pengutronix.de  Mon Oct  8 11:25:52 2012
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Mon,  8 Oct 2012 17:25:52 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
Message-ID: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>

This allows to put the filesystem at a defined address in ROM allowing
to save more precious RAM.

I think it's save to default to ROM because the intention of using the
uclinux map is to use a romfs and so mtd-ram doesn't give you anything
that mtd-rom doesn't.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/mtd/maps/Kconfig   |    2 +-
 drivers/mtd/maps/uclinux.c |   30 +++++++++++++++++++++++-------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 5ba2458..d945950 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -443,7 +443,7 @@ config MTD_GPIO_ADDR
 
 config MTD_UCLINUX
 	bool "Generic uClinux RAM/ROM filesystem support"
-	depends on MTD_RAM=y && !MMU
+	depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
 	help
 	  Map driver to support image based filesystems for uClinux.
 
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index c3bb304..a8a5929 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -23,12 +23,13 @@
 
 /****************************************************************************/
 
-struct map_info uclinux_ram_map = {
-	.name = "RAM",
-	.phys = (unsigned long)__bss_stop,
+static struct map_info uclinux_ram_map = {
 	.size = 0,
 };
 
+static unsigned long physaddr = -1;
+module_param(physaddr, ulong, S_IRUGO);
+
 static struct mtd_info *uclinux_ram_mtdinfo;
 
 /****************************************************************************/
@@ -60,11 +61,17 @@ static int __init uclinux_mtd_init(void)
 	struct map_info *mapp;
 
 	mapp = &uclinux_ram_map;
+
+	if (physaddr == -1)
+		mapp->phys = (resource_size_t)__bss_stop;
+	else
+		mapp->phys = physaddr;
+
 	if (!mapp->size)
 		mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
 	mapp->bankwidth = 4;
 
-	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
+	printk("uclinux[mtd]: RAM/ROM probe address=0x%x size=0x%x\n",
 	       	(int) mapp->phys, (int) mapp->size);
 
 	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
@@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
 
 	simple_map_init(mapp);
 
-	mtd = do_map_probe("map_ram", mapp);
+	mapp->name = "ROM";
+	mtd = do_map_probe("map_rom", mapp);
+	if (!mtd) {
+		/* fall back to ram probing for compatibility reasons */
+		mapp->name = "RAM";
+		mtd = do_map_probe("map_ram", mapp);
+		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
+			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
+	}
+
 	if (!mtd) {
-		printk("uclinux[mtd]: failed to find a mapping?\n");
+		printk("uclinux[mtd]: failed to find a rom/ram mapping?\n");
 		iounmap(mapp->virt);
 		return(-ENXIO);
 	}
@@ -115,6 +131,6 @@ module_exit(uclinux_mtd_cleanup);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Greg Ungerer <gerg at snapgear.com>");
-MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
+MODULE_DESCRIPTION("Generic RAM/ROM based MTD for uClinux");
 
 /****************************************************************************/
-- 
1.7.10.4



From vikram186 at gmail.com  Mon Oct  8 12:44:05 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Mon, 08 Oct 2012 22:14:05 +0530
Subject: i.MX6S/GPMI-NAND issue on 3.5.4
In-Reply-To: <50723FCE.4000708@freescale.com>
References: <505CB1ED.8010909@gmail.com> <50723FCE.4000708@freescale.com>
Message-ID: <507302D5.5050802@gmail.com>

On 10/8/2012 8:21 AM, Huang Shijie wrote:
> ? 2012?09?22? 02:29, Vikram Narayanan ??:
>> Hello,
>>
>> I'm facing some issue with GPMI-NAND driver on i.MX6 solo.
> Does the MX6Q solo support the NAND?

Yes. i.Mx6Solo supports NAND.

> I have the solo board in my hand. But it can not support the NAND.
> 
> You make the board yourself?
> If so, please check the pinmux for solo.

Yeah I figured out that pinctrl driver was the problem.Anyway thanks for
the pointing it out.

Regards,
Vikram


From vikram186 at gmail.com  Mon Oct  8 12:58:02 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Mon, 08 Oct 2012 22:28:02 +0530
Subject: [PATCH] imx/gpmi: Make debug prints more clear
In-Reply-To: <505EDAF0.2040708@gmail.com>
References: <505EDAF0.2040708@gmail.com>
Message-ID: <5073061A.5040405@gmail.com>

Hello Huang,

Can you please give an ACK for this?

Thanks,
Vikram

On 9/23/2012 3:18 PM, Vikram Narayanan wrote:
> Make the error messages more debugging friendly
>
> Signed-off-by: Vikram Narayanan<vikram186 at gmail.com>
> Cc: Huang Shijie<b32955 at freescale.com>
> ---
>   drivers/mtd/nand/gpmi-nand/gpmi-nand.c |   14 ++++++++------
>   1 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 5999b15..24fbfb8 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -222,7 +222,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
>
>   		ret = dma_map_sg(this->dev, sgl, 1, dr);
>   		if (ret == 0)
> -			pr_err("map failed.\n");
> +			pr_err("DMA mapping failed.\n");
>
>   		this->direct_dma_map_ok = false;
>   	}
> @@ -456,7 +456,7 @@ static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
>
>   	dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
>   	if (!dma_chan) {
> -		pr_err("dma_request_channel failed.\n");
> +		pr_err("Failed to request DMA channel.\n");
>   		goto acquire_err;
>   	}
>
> @@ -630,7 +630,8 @@ static int read_page_prepare(struct gpmi_nand_data *this,
>   						length, DMA_FROM_DEVICE);
>   		if (dma_mapping_error(dev, dest_phys)) {
>   			if (alt_size<  length) {
> -				pr_err("Alternate buffer is too small\n");
> +				pr_err("%s, Alternate buffer is too small\n",
> +					__func__);
>   				return -ENOMEM;
>   			}
>   			goto map_failed;
> @@ -680,7 +681,8 @@ static int send_page_prepare(struct gpmi_nand_data *this,
>   						DMA_TO_DEVICE);
>   		if (dma_mapping_error(dev, source_phys)) {
>   			if (alt_size<  length) {
> -				pr_err("Alternate buffer is too small\n");
> +				pr_err("%s, Alternate buffer is too small\n",
> +					__func__);
>   				return -ENOMEM;
>   			}
>   			goto map_failed;
> @@ -768,7 +770,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
>
>   error_alloc:
>   	gpmi_free_dma_buffer(this);
> -	pr_err("allocate DMA buffer ret!!\n");
> +	pr_err("Error allocating DMA buffers!\n");
>   	return -ENOMEM;
>   }
>
> @@ -1479,7 +1481,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this)
>   	/* Set up the NFC geometry which is used by BCH. */
>   	ret = bch_set_geometry(this);
>   	if (ret) {
> -		pr_err("set geometry ret : %d\n", ret);
> +		pr_err("Error setting BCH geometry : %d\n", ret);
>   		return ret;
>   	}
>



From b32955 at freescale.com  Mon Oct  8 21:43:33 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 9 Oct 2012 09:43:33 +0800
Subject: [PATCH] imx/gpmi: Make debug prints more clear
In-Reply-To: <5073061A.5040405@gmail.com>
References: <505EDAF0.2040708@gmail.com> <5073061A.5040405@gmail.com>
Message-ID: <50738145.4020102@freescale.com>

? 2012?10?09? 00:58, Vikram Narayanan ??:
> Hello Huang,
>
> Can you please give an ACK for this?
>
> Thanks,
> Vikram
>
> On 9/23/2012 3:18 PM, Vikram Narayanan wrote:
>> Make the error messages more debugging friendly
>>
>> Signed-off-by: Vikram Narayanan<vikram186 at gmail.com>
>> Cc: Huang Shijie<b32955 at freescale.com>
>> ---
>> drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 14 ++++++++------
>> 1 files changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c 
>> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> index 5999b15..24fbfb8 100644
>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>> @@ -222,7 +222,7 @@ void prepare_data_dma(struct gpmi_nand_data 
>> *this, enum dma_data_direction dr)
>>
>> ret = dma_map_sg(this->dev, sgl, 1, dr);
>> if (ret == 0)
>> - pr_err("map failed.\n");
>> + pr_err("DMA mapping failed.\n");
>>
>> this->direct_dma_map_ok = false;
>> }
>> @@ -456,7 +456,7 @@ static int __devinit acquire_dma_channels(struct 
>> gpmi_nand_data *this)
>>
>> dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
>> if (!dma_chan) {
>> - pr_err("dma_request_channel failed.\n");
>> + pr_err("Failed to request DMA channel.\n");
>> goto acquire_err;
>> }
>>
>> @@ -630,7 +630,8 @@ static int read_page_prepare(struct 
>> gpmi_nand_data *this,
>> length, DMA_FROM_DEVICE);
>> if (dma_mapping_error(dev, dest_phys)) {
>> if (alt_size< length) {
>> - pr_err("Alternate buffer is too small\n");
>> + pr_err("%s, Alternate buffer is too small\n",
>> + __func__);
>> return -ENOMEM;
>> }
>> goto map_failed;
>> @@ -680,7 +681,8 @@ static int send_page_prepare(struct 
>> gpmi_nand_data *this,
>> DMA_TO_DEVICE);
>> if (dma_mapping_error(dev, source_phys)) {
>> if (alt_size< length) {
>> - pr_err("Alternate buffer is too small\n");
>> + pr_err("%s, Alternate buffer is too small\n",
>> + __func__);
>> return -ENOMEM;
>> }
>> goto map_failed;
>> @@ -768,7 +770,7 @@ static int gpmi_alloc_dma_buffer(struct 
>> gpmi_nand_data *this)
>>
>> error_alloc:
>> gpmi_free_dma_buffer(this);
>> - pr_err("allocate DMA buffer ret!!\n");
>> + pr_err("Error allocating DMA buffers!\n");
>> return -ENOMEM;
>> }
>>
>> @@ -1479,7 +1481,7 @@ static int gpmi_set_geometry(struct 
>> gpmi_nand_data *this)
>> /* Set up the NFC geometry which is used by BCH. */
>> ret = bch_set_geometry(this);
>> if (ret) {
>> - pr_err("set geometry ret : %d\n", ret);
>> + pr_err("Error setting BCH geometry : %d\n", ret);
>> return ret;
>> }
>>
>
>
thanks.

Acked-by: Huang Shijie <b32955 at freescale.com>





From shijie8 at gmail.com  Mon Oct  8 22:10:48 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Tue, 9 Oct 2012 10:10:48 +0800
Subject: MTD in mainline status
In-Reply-To: <50724E5C.1010809@atmel.com>
References: <50724E5C.1010809@atmel.com>
Message-ID: <CAMiH66HGfSKSo9rE8od-=fYvXkx=Xa2SdU1jGQ0tCOVdPwvixQ@mail.gmail.com>

just a ping.

We all do not want to miss this merge-window.

thanks.
Huang Shijie


On Mon, Oct 8, 2012 at 11:54 AM, Josh Wu <josh.wu at atmel.com> wrote:
> Hi,
>
> Just a little reminder: it would be good time to send out the pull request
> to mainline for MTD in current merge window :-)
>
> Best Regards,
> Josh Wu
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/


From gerg at snapgear.com  Mon Oct  8 23:29:46 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Tue, 9 Oct 2012 13:29:46 +1000
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <50739A2A.9070405@snapgear.com>

Hi Uwe,

On 09/10/12 01:25, Uwe Kleine-K?nig wrote:
> This allows to put the filesystem at a defined address in ROM allowing
> to save more precious RAM.
>
> I think it's save to default to ROM because the intention of using the
> uclinux map is to use a romfs and so mtd-ram doesn't give you anything
> that mtd-rom doesn't.
>
> Signed-off-by: Uwe Kleine-K??nig <u.kleine-koenig at pengutronix.de>

Looks good to me, so:

Acked-by: Greg Ungerer <gerg at uclinux.org>

Couple of things to be aware of. Artem currently has a couple of
patches against this file (looks like at least 1 of them is currently
in linux-next). It will probably conflict with your changes, should
be easy enough to fix up.

The change to this file in linux-next changes the call to ioremap
to be a phys_to_virt - which is because it was always going to be
in real RAM. This may no longer be true with your change, it could
be in ROM. For non-MMU I expect no problems. But this could be an
issue if used on systems with MMU enabled. (And one of the other
changes that I generated for this allows this for at least one
architecture type - ColdFire/m68k). Just flagging this, I don't expect
it will cause any current users any problems.

Regards
Greg



> ---
>   drivers/mtd/maps/Kconfig   |    2 +-
>   drivers/mtd/maps/uclinux.c |   30 +++++++++++++++++++++++-------
>   2 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> index 5ba2458..d945950 100644
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -443,7 +443,7 @@ config MTD_GPIO_ADDR
>
>   config MTD_UCLINUX
>   	bool "Generic uClinux RAM/ROM filesystem support"
> -	depends on MTD_RAM=y && !MMU
> +	depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
>   	help
>   	  Map driver to support image based filesystems for uClinux.
>
> diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
> index c3bb304..a8a5929 100644
> --- a/drivers/mtd/maps/uclinux.c
> +++ b/drivers/mtd/maps/uclinux.c
> @@ -23,12 +23,13 @@
>
>   /****************************************************************************/
>
> -struct map_info uclinux_ram_map = {
> -	.name = "RAM",
> -	.phys = (unsigned long)__bss_stop,
> +static struct map_info uclinux_ram_map = {
>   	.size = 0,
>   };
>
> +static unsigned long physaddr = -1;
> +module_param(physaddr, ulong, S_IRUGO);
> +
>   static struct mtd_info *uclinux_ram_mtdinfo;
>
>   /****************************************************************************/
> @@ -60,11 +61,17 @@ static int __init uclinux_mtd_init(void)
>   	struct map_info *mapp;
>
>   	mapp = &uclinux_ram_map;
> +
> +	if (physaddr == -1)
> +		mapp->phys = (resource_size_t)__bss_stop;
> +	else
> +		mapp->phys = physaddr;
> +
>   	if (!mapp->size)
>   		mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
>   	mapp->bankwidth = 4;
>
> -	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
> +	printk("uclinux[mtd]: RAM/ROM probe address=0x%x size=0x%x\n",
>   	       	(int) mapp->phys, (int) mapp->size);
>
>   	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
> @@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
>
>   	simple_map_init(mapp);
>
> -	mtd = do_map_probe("map_ram", mapp);
> +	mapp->name = "ROM";
> +	mtd = do_map_probe("map_rom", mapp);
> +	if (!mtd) {
> +		/* fall back to ram probing for compatibility reasons */
> +		mapp->name = "RAM";
> +		mtd = do_map_probe("map_ram", mapp);
> +		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
> +			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
> +	}
> +
>   	if (!mtd) {
> -		printk("uclinux[mtd]: failed to find a mapping?\n");
> +		printk("uclinux[mtd]: failed to find a rom/ram mapping?\n");
>   		iounmap(mapp->virt);
>   		return(-ENXIO);
>   	}
> @@ -115,6 +131,6 @@ module_exit(uclinux_mtd_cleanup);
>
>   MODULE_LICENSE("GPL");
>   MODULE_AUTHOR("Greg Ungerer <gerg at snapgear.com>");
> -MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
> +MODULE_DESCRIPTION("Generic RAM/ROM based MTD for uClinux");
>
>   /****************************************************************************/
>


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From weiyj.lk at gmail.com  Tue Oct  9 02:14:21 2012
From: weiyj.lk at gmail.com (Wei Yongjun)
Date: Tue, 9 Oct 2012 14:14:21 +0800
Subject: [PATCH] ubi: use list_move_tail instead of list_del/list_add_tail
Message-ID: <CAPgLHd_AHHe7=H18K54LvbiS0M7_w1vTMOxwwxgVdRaiXNN-OA@mail.gmail.com>

From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Using list_move_tail() instead of list_del() + list_add_tail().

dpatch engine is used to auto generate this patch.
(https://github.com/weiyj/dpatch)

Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
---
 drivers/mtd/ubi/fastmap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 1a5f53c..5f540c5 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -815,8 +815,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
 		ai->max_sqnum = max_sqnum;
 
 	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
-		list_del(&tmp_aeb->u.list);
-		list_add_tail(&tmp_aeb->u.list, &ai->free);
+		list_move_tail(&tmp_aeb->u.list, &ai->free);
 	}
 
 	/*



From u.kleine-koenig at pengutronix.de  Tue Oct  9 04:44:18 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Tue, 9 Oct 2012 10:44:18 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <50739A2A.9070405@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com>
Message-ID: <20121009084418.GH18531@pengutronix.de>

Hi Greg,

On Tue, Oct 09, 2012 at 01:29:46PM +1000, Greg Ungerer wrote:
> On 09/10/12 01:25, Uwe Kleine-K?nig wrote:
> >This allows to put the filesystem at a defined address in ROM allowing
> >to save more precious RAM.
> >
> >I think it's save to default to ROM because the intention of using the
> >uclinux map is to use a romfs and so mtd-ram doesn't give you anything
> >that mtd-rom doesn't.
> >
> >Signed-off-by: Uwe Kleine-K??nig <u.kleine-koenig at pengutronix.de>
> 
> Looks good to me, so:
> 
> Acked-by: Greg Ungerer <gerg at uclinux.org>
> 
> Couple of things to be aware of. Artem currently has a couple of
> patches against this file (looks like at least 1 of them is currently
> in linux-next). It will probably conflict with your changes, should
> be easy enough to fix up.
If you tell me a branch to test, I can do so.

Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From hechtb at googlemail.com  Tue Oct  9 05:58:47 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  9 Oct 2012 11:58:47 +0200
Subject: [PATCH v2 0/2] Add DMA and device tree support to the flash
 controller FLCTL
Message-ID: <1349776729-9311-1-git-send-email-hechtb@gmail.com>

changelog v2: 	- cosmetic fixes in patch 1
		- added dmas and dma-names field in patch 2

This mini-series consists of 2 separately posted patch-sets that shrunk
to one patch each. It adds DMA support for the data part (not ECC) as
well as device tree support to the FLCTL flash controller.
As the 2nd patch is based on the 1st, I've decided to
collect them here to avoid any confusion.

The first set contained
[PATCH 1/2] mtd: sh_flctl: Setup and release DMA channels
[PATCH 2/2] mtd: sh_flctl: Use DMA for data fifo FLTDFIFO when available
and was merged after 2 reviews to
[PATCH] mtd: sh_flctl: Add DMA capabilty (same patch as in here)

The second set contained
[PATCH 1/3] mtd: sh_flctl: Probe SNAND_E flag from NAND chip
[PATCH 2/3] mtd: sh_flctl: Add device tree support
[PATCH 3/3] mtd: sh_flctl: Add sh7372 device tree config
and is merged here to
mtd: sh_flctl: Add device tree support

Patch 1 can be omitted as SNAND_E is handled in the FLCTL source anyway
correctly in set_cmd_regs() and the flag can be removed from existing board
codes without this patch.
Patch 2 without patch 3 may be confusing so I merged them too. Documentation
is added as well.

I've added linux-arm-kernel at lists.infradead.org as recipient for the
device tree part.

The patchset is based on
l2-mtd	git://git.infradead.org/users/dedekind/l2-mtd.git
with reverted commit e26c113b4130aefa1d8446602bb5b05cfd646bfe.


Bastian Hecht (2):
  mtd: sh_flctl: Add DMA capabilty
  mtd: sh_flctl: Add device tree support

 .../devicetree/bindings/mtd/flctl-nand.txt         |   37 +++
 drivers/mtd/nand/sh_flctl.c                        |  266 +++++++++++++++++++-
 include/linux/mtd/sh_flctl.h                       |   12 +
 3 files changed, 305 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

-- 
1.7.5.4



From hechtb at googlemail.com  Tue Oct  9 05:58:48 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  9 Oct 2012 11:58:48 +0200
Subject: [PATCH v2 1/2] mtd: sh_flctl: Add DMA capabilty
In-Reply-To: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
Message-ID: <1349776729-9311-2-git-send-email-hechtb@gmail.com>

The code probes if DMA channels can get allocated and tears them down at
removal/failure if needed.
If available it uses them to transfer the data part (not ECC). On
failure we fall back to PIO mode.

Based on Guennadi Liakhovetski's code from the sh_mmcif driver.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
Reviewed-by: Guennadi Liakhovetski <g.liakhovetski at gmx.de>
---
v2: added missing header complete.h and removed double tab.

 drivers/mtd/nand/sh_flctl.c  |  175 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/mtd/sh_flctl.h |   12 +++
 2 files changed, 184 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4fbfe96..1105fbb 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -23,11 +23,15 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
@@ -106,6 +110,84 @@ static void wait_completion(struct sh_flctl *flctl)
 	writeb(0x0, FLTRCR(flctl));
 }
 
+static void flctl_dma_complete(void *param)
+{
+	struct sh_flctl *flctl = param;
+
+	complete(&flctl->dma_complete);
+}
+
+static void flctl_release_dma(struct sh_flctl *flctl)
+{
+	if (flctl->chan_fifo0_rx) {
+		dma_release_channel(flctl->chan_fifo0_rx);
+		flctl->chan_fifo0_rx = NULL;
+	}
+	if (flctl->chan_fifo0_tx) {
+		dma_release_channel(flctl->chan_fifo0_tx);
+		flctl->chan_fifo0_tx = NULL;
+	}
+}
+
+static void flctl_setup_dma(struct sh_flctl *flctl)
+{
+	dma_cap_mask_t mask;
+	struct dma_slave_config cfg;
+	struct platform_device *pdev = flctl->pdev;
+	struct sh_flctl_platform_data *pdata = pdev->dev.platform_data;
+	int ret;
+
+	if (!pdata)
+		return;
+
+	if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0)
+		return;
+
+	/* We can only either use DMA for both Tx and Rx or not use it at all */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_tx);
+	dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__,
+		flctl->chan_fifo0_tx);
+
+	if (!flctl->chan_fifo0_tx)
+		return;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.slave_id = pdata->slave_id_fifo0_tx;
+	cfg.direction = DMA_MEM_TO_DEV;
+	cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl);
+	cfg.src_addr = 0;
+	ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_rx);
+	dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__,
+		flctl->chan_fifo0_rx);
+
+	if (!flctl->chan_fifo0_rx)
+		goto err;
+
+	cfg.slave_id = pdata->slave_id_fifo0_rx;
+	cfg.direction = DMA_DEV_TO_MEM;
+	cfg.dst_addr = 0;
+	cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl);
+	ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	init_completion(&flctl->dma_complete);
+
+	return;
+
+err:
+	flctl_release_dma(flctl);
+}
+
 static void set_addr(struct mtd_info *mtd, int column, int page_addr)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -261,6 +343,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
 	timeout_error(flctl, __func__);
 }
 
+static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
+					int len, enum dma_data_direction dir)
+{
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct dma_chan *chan;
+	enum dma_transfer_direction tr_dir;
+	dma_addr_t dma_addr;
+	dma_cookie_t cookie = -EINVAL;
+	uint32_t reg;
+	int ret;
+
+	if (dir == DMA_FROM_DEVICE) {
+		chan = flctl->chan_fifo0_rx;
+		tr_dir = DMA_DEV_TO_MEM;
+	} else {
+		chan = flctl->chan_fifo0_tx;
+		tr_dir = DMA_MEM_TO_DEV;
+	}
+
+	dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
+
+	if (dma_addr)
+		desc = dmaengine_prep_slave_single(chan, dma_addr, len,
+			tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+	if (desc) {
+		reg = readl(FLINTDMACR(flctl));
+		reg |= DREQ0EN;
+		writel(reg, FLINTDMACR(flctl));
+
+		desc->callback = flctl_dma_complete;
+		desc->callback_param = flctl;
+		cookie = dmaengine_submit(desc);
+
+		dma_async_issue_pending(chan);
+	} else {
+		/* DMA failed, fall back to PIO */
+		flctl_release_dma(flctl);
+		dev_warn(&flctl->pdev->dev,
+			 "DMA failed, falling back to PIO\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	ret =
+	wait_for_completion_timeout(&flctl->dma_complete,
+				msecs_to_jiffies(3000));
+
+	if (ret <= 0) {
+		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+		dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
+	}
+
+out:
+	reg = readl(FLINTDMACR(flctl));
+	reg &= ~DREQ0EN;
+	writel(reg, FLINTDMACR(flctl));
+
+	dma_unmap_single(chan->device->dev, dma_addr, len, dir);
+
+	/* ret > 0 is success */
+	return ret;
+}
+
 static void read_datareg(struct sh_flctl *flctl, int offset)
 {
 	unsigned long data;
@@ -279,11 +425,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 
 	len_4align = (rlen + 3) / 4;
 
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_rx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0)
+			goto convert;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_rfifo_ready(flctl);
 		buf[i] = readl(FLDTFIFO(flctl));
-		buf[i] = be32_to_cpu(buf[i]);
 	}
+
+convert:
+	for (i = 0; i < len_4align; i++)
+		buf[i] = be32_to_cpu(buf[i]);
 }
 
 static enum flctl_ecc_res_t read_ecfiforeg
@@ -308,13 +463,23 @@ static enum flctl_ecc_res_t read_ecfiforeg
 static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 {
 	int i, len_4align;
-	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 	void *fifo_addr = (void *)FLDTFIFO(flctl);
 
 	len_4align = (rlen + 3) / 4;
+
+	for (i = 0; i < len_4align; i++)
+		buf[i] = cpu_to_be32(buf[i]);
+
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_tx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0)
+			return;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_wfifo_ready(flctl);
-		writel(cpu_to_be32(data[i]), fifo_addr);
+		writel(buf[i], fifo_addr);
 	}
 }
 
@@ -930,6 +1095,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume(&pdev->dev);
 
+	flctl_setup_dma(flctl);
+
 	ret = nand_scan_ident(flctl_mtd, 1, NULL);
 	if (ret)
 		goto err_chip;
@@ -947,6 +1114,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	return 0;
 
 err_chip:
+	flctl_release_dma(flctl);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(irq, flctl);
 err_flste:
@@ -960,6 +1128,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
 {
 	struct sh_flctl *flctl = platform_get_drvdata(pdev);
 
+	flctl_release_dma(flctl);
 	nand_release(&flctl->mtd);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(platform_get_irq(pdev, 0), flctl);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 01e4b15..e98fe7e 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -20,6 +20,7 @@
 #ifndef __SH_FLCTL_H__
 #define __SH_FLCTL_H__
 
+#include <linux/completion.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
@@ -107,6 +108,7 @@
 #define ESTERINTE	(0x1 << 24)	/* ECC error interrupt enable */
 #define AC1CLR		(0x1 << 19)	/* ECC FIFO clear */
 #define AC0CLR		(0x1 << 18)	/* Data FIFO clear */
+#define DREQ0EN		(0x1 << 16)	/* FLDTFIFODMA Request Enable */
 #define ECERB		(0x1 << 9)	/* ECC error */
 #define STERB		(0x1 << 8)	/* Status error */
 #define STERINTE	(0x1 << 4)	/* Status error enable */
@@ -138,6 +140,8 @@ enum flctl_ecc_res_t {
 	FL_TIMEOUT
 };
 
+struct dma_chan;
+
 struct sh_flctl {
 	struct mtd_info		mtd;
 	struct nand_chip	chip;
@@ -161,6 +165,11 @@ struct sh_flctl {
 	unsigned hwecc:1;	/* Hardware ECC (0 = disabled, 1 = enabled) */
 	unsigned holden:1;	/* Hardware has FLHOLDCR and HOLDEN is set */
 	unsigned qos_request:1;	/* QoS request to prevent deep power shutdown */
+
+	/* DMA related objects */
+	struct dma_chan		*chan_fifo0_rx;
+	struct dma_chan		*chan_fifo0_tx;
+	struct completion	dma_complete;
 };
 
 struct sh_flctl_platform_data {
@@ -170,6 +179,9 @@ struct sh_flctl_platform_data {
 
 	unsigned has_hwecc:1;
 	unsigned use_holden:1;
+
+	unsigned int            slave_id_fifo0_tx;
+	unsigned int            slave_id_fifo0_rx;
 };
 
 static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
-- 
1.7.5.4



From hechtb at googlemail.com  Tue Oct  9 05:58:49 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Tue,  9 Oct 2012 11:58:49 +0200
Subject: [PATCH v2 2/2] mtd: sh_flctl: Add device tree support
In-Reply-To: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
Message-ID: <1349776729-9311-3-git-send-email-hechtb@gmail.com>

The flctl can now be probed via device tree setup in addition to the
existing platform data way.

SoC specific setup data is set in the .data member of the OF match, so
kept within the driver itself, while board/user specific setup - like
partitioning - is taken from the device tree.

Actual configuration is added for the SoC sh7372.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
---
v2: added dmas and dma-names fields to the bindings. These are not used yet
but are added for completing the bindings and will be needed later.

 .../devicetree/bindings/mtd/flctl-nand.txt         |   49 +++++++++++
 drivers/mtd/nand/sh_flctl.c                        |   92 ++++++++++++++++++--
 2 files changed, 134 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
new file mode 100644
index 0000000..427f46d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
@@ -0,0 +1,49 @@
+FLCTL NAND controller
+
+Required properties:
+- compatible : "renesas,shmobile-flctl-sh7372"
+- reg : Address range of the FLCTL
+- interrupts : flste IRQ number
+- nand-bus-width : bus width to NAND chip
+
+Optional properties:
+- dmas: DMA specifier(s)
+- dma-names: name for each DMA specifier. Valid names are
+	     "data_tx", "data_rx", "ecc_tx", "ecc_rx"
+
+The DMA fields are not used yet in the driver but are listed here for
+completing the bindings.
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+	flctl at e6a30000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "renesas,shmobile-flctl-sh7372";
+		reg = <0xe6a30000 0x100>;
+		interrupts = <0x0d80>;
+
+		nand-bus-width = <16>;
+
+		dmas = <&dmac 1 /* data_tx */
+			&dmac 2;> /* data_rx */
+		dma-names = "data_tx", "data_rx";
+
+		system at 0 {
+			label = "system";
+			reg = <0x0 0x8000000>;
+		};
+
+		userdata at 8000000 {
+			label = "userdata";
+			reg = <0x8000000 0x10000000>;
+		};
+
+		cache at 18000000 {
+			label = "cache";
+			reg = <0x18000000 0x8000000>;
+		};
+	};
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 1105fbb..02ff9d1 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -29,6 +29,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mtd.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/sh_dma.h>
@@ -1021,6 +1024,73 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+struct flctl_soc_config {
+	unsigned long flcmncr_val;
+	unsigned has_hwecc:1;
+	unsigned use_holden:1;
+};
+
+static struct flctl_soc_config flctl_sh7372_config = {
+	.flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL,
+	.has_hwecc = 1,
+	.use_holden = 1,
+};
+
+static const struct of_device_id of_flctl_match[] = {
+	{ .compatible = "renesas,shmobile-flctl-sh7372",
+				.data = &flctl_sh7372_config },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_flctl_match);
+
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	const struct of_device_id *match;
+	struct flctl_soc_config *config;
+	struct sh_flctl_platform_data *pdata;
+	struct device_node *dn = dev->of_node;
+	int ret;
+
+	match = of_match_device(of_flctl_match, dev);
+	if (match)
+		config = (struct flctl_soc_config *)match->data;
+	else {
+		dev_err(dev, "%s: no OF configuration attached\n", __func__);
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data),
+								GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "%s: failed to allocate config data\n", __func__);
+		return NULL;
+	}
+
+	/* set SoC specific options */
+	pdata->flcmncr_val = config->flcmncr_val;
+	pdata->has_hwecc = config->has_hwecc;
+	pdata->use_holden = config->use_holden;
+
+	/* parse user defined options */
+	ret = of_get_nand_bus_width(dn);
+	if (ret == 16)
+		pdata->flcmncr_val |= SEL_16BIT;
+	else if (ret != 8) {
+		dev_err(dev, "%s: invalid bus width\n", __func__);
+		return NULL;
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+#define of_flctl_match NULL
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit flctl_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -1030,12 +1100,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	struct sh_flctl_platform_data *pdata;
 	int ret = -ENXIO;
 	int irq;
-
-	pdata = pdev->dev.platform_data;
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
+	struct mtd_part_parser_data ppdata = {};
 
 	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
 	if (!flctl) {
@@ -1067,6 +1132,16 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 		goto err_flste;
 	}
 
+	if (pdev->dev.of_node)
+		pdata = flctl_parse_dt(&pdev->dev);
+	else
+		pdata = pdev->dev.platform_data;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no setup data defined\n");
+		return -EINVAL;
+	}
+
 	platform_set_drvdata(pdev, flctl);
 	flctl_mtd = &flctl->mtd;
 	nand = &flctl->chip;
@@ -1109,7 +1184,9 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_chip;
 
-	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+	ppdata.of_node = pdev->dev.of_node;
+	ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts,
+			pdata->nr_parts);
 
 	return 0;
 
@@ -1143,6 +1220,7 @@ static struct platform_driver flctl_driver = {
 	.driver = {
 		.name	= "sh_flctl",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_flctl_match,
 	},
 };
 
-- 
1.7.5.4



From vipin.kumar at st.com  Tue Oct  9 06:44:42 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:42 +0530
Subject: [PATCH 00/11] mtd/nand: fsmc driver updates
Message-ID: <cover.1349778820.git.vipin.kumar@st.com>

This patch-set contains several fixes and a few enhancements in fsmc driver.
Modifications include
- General enhancements
  * Add ready/busy support through a GPIO pin
  * Add software bch support
  * Increase ecc loactions to 640
  * Support multiple banks
  * Use relaxed io accessors for increased throughput
- Enhance DT support
  * Add timing parameters
- Several fixes
  * Fix the type for regs
  * Replace change_bit routine to handle unaligned addresses
  * Provide contiguous buffers for DMA operation

Vipin Kumar (11):
  fsmc/nand:FIX: Change the type for regs to void __iomem *
  fsmc/nand: Rearrange the fsmc_nand_data structure and update comments
  fsmc/nand: Support multiple banks connected to controller
  fsmc/nand: Accept nand timing parameters via DT
  fsmc: Implement ready/busy through gpio pin
  fsmc/nand: Modify the wait to uninterruptible
  fsmc/nand: Provide contiguous buffers to dma
  fsmc/nand: Use relaxed variants of io accessors
  fsmc/nand:FIX: replace change_bit routine
  fsmc/nand: Add sw bch support for ecc calculation/correction
  nand: Increase the ecc placement locations to 640

 .../devicetree/bindings/mtd/fsmc-nand.txt          |  29 ++
 arch/arm/boot/dts/spear300.dtsi                    |   1 +
 arch/arm/boot/dts/spear310.dtsi                    |   1 +
 arch/arm/boot/dts/spear320.dtsi                    |   1 +
 arch/arm/boot/dts/spear600.dtsi                    |   1 +
 arch/arm/mach-u300/core.c                          |   1 +
 drivers/mtd/nand/fsmc_nand.c                       | 419 ++++++++++++++-------
 include/linux/mtd/fsmc.h                           |  18 +-
 include/linux/mtd/mtd.h                            |   2 +-
 9 files changed, 332 insertions(+), 141 deletions(-)

-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:43 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:43 +0530
Subject: [PATCH 01/11] fsmc/nand:FIX: Change the type for regs to void __iomem
 *
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 38d2624..e96d7d1 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 	struct nand_chip *this = mtd->priv;
 	struct fsmc_nand_data *host = container_of(mtd,
 					struct fsmc_nand_data, mtd);
-	void *__iomem *regs = host->regs_va;
+	void __iomem *regs = host->regs_va;
 	unsigned int bank = host->bank;
 
 	if (ctrl & NAND_CTRL_CHANGE) {
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:44 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:44 +0530
Subject: [PATCH 02/11] fsmc/nand: Rearrange the fsmc_nand_data structure and
 update comments
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 51 ++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index e96d7d1..bd89580 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -278,52 +278,61 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
  * struct fsmc_nand_data - structure for FSMC NAND device state
  *
  * @pid:		Part ID on the AMBA PrimeCell format
- * @mtd:		MTD info for a NAND flash.
- * @nand:		Chip related info for a NAND flash.
- * @partitions:		Partition info for a NAND Flash.
- * @nr_partitions:	Total number of partition of a NAND flash.
- *
- * @ecc_place:		ECC placing locations in oobfree type format.
- * @bank:		Bank number for probed device.
- * @clk:		Clock structure for FSMC.
+ * @mtd:		MTD info for a NAND flash
+ * @nand:		Chip related info for a NAND flash
+ * @dev:		Device structure pointer
+ * @clk:		Clock structure for FSMC
+ * @ecc_place:		ECC placing locations in oobfree type format
+ * @bank:		Bank number for probed device
  *
  * @read_dma_chan:	DMA channel for read access
  * @write_dma_chan:	DMA channel for write access to NAND
  * @dma_access_complete: Completion structure
  *
- * @data_pa:		NAND Physical port for Data.
- * @data_va:		NAND port for Data.
- * @cmd_va:		NAND port for Command.
- * @addr_va:		NAND port for Address.
- * @regs_va:		FSMC regs base address.
+ * @dev_timings:	Timings to be programmed in controller
+ * @partitions:		Partition info for a NAND Flash
+ * @nr_partitions:	Total number of partition of a NAND flash
+ * @mode:		Defines the NAND device access mode
+ *			Can be one of:
+ *			- DMA access
+ *			- Word access (CPU)
+ *			- None (Use driver default ie bus width specific
+ *			  CPU access)
+ * @select_chip:	Select a particular bank
+ *
+ * @data_pa:		NAND Physical port for Data
+ * @data_va:		NAND port for Data
+ * @cmd_va:		NAND port for Command
+ * @addr_va:		NAND port for Address
+ * @regs_va:		FSMC regs base address
  */
 struct fsmc_nand_data {
 	u32			pid;
 	struct mtd_info		mtd;
 	struct nand_chip	nand;
-	struct mtd_partition	*partitions;
-	unsigned int		nr_partitions;
-
-	struct fsmc_eccplace	*ecc_place;
-	unsigned int		bank;
 	struct device		*dev;
-	enum access_mode	mode;
 	struct clk		*clk;
+	struct fsmc_eccplace	*ecc_place;
+	unsigned int		bank;
 
 	/* DMA related objects */
 	struct dma_chan		*read_dma_chan;
 	struct dma_chan		*write_dma_chan;
 	struct completion	dma_access_complete;
 
+	/* Recieved from plat data */
 	struct fsmc_nand_timings *dev_timings;
+	struct mtd_partition	*partitions;
+	unsigned int		nr_partitions;
+	enum access_mode	mode;
+	void			(*select_chip)(uint32_t bank, uint32_t busw);
 
+	/* Virtual/Physical addresses for CPU/DMA access */
 	dma_addr_t		data_pa;
 	void __iomem		*data_va;
 	void __iomem		*cmd_va;
 	void __iomem		*addr_va;
 	void __iomem		*regs_va;
-
-	void			(*select_chip)(uint32_t bank, uint32_t busw);
 };
 
 /* Assert CS signal based on chipnr */
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:45 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:45 +0530
Subject: [PATCH 03/11] fsmc/nand: Support multiple banks connected to
 controller
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>

Support up to max_banks number of banks in fsmc driver.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 .../devicetree/bindings/mtd/fsmc-nand.txt          |  2 ++
 arch/arm/boot/dts/spear300.dtsi                    |  1 +
 arch/arm/boot/dts/spear310.dtsi                    |  1 +
 arch/arm/boot/dts/spear320.dtsi                    |  1 +
 arch/arm/boot/dts/spear600.dtsi                    |  1 +
 arch/arm/mach-u300/core.c                          |  1 +
 drivers/mtd/nand/fsmc_nand.c                       | 26 +++++++++++++++-------
 include/linux/mtd/fsmc.h                           |  2 +-
 8 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
index e2c663b..29d1a2f 100644
--- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
@@ -6,6 +6,7 @@ Required properties:
 - reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
 - st,ale-off : Chip specific offset to ALE
 - st,cle-off : Chip specific offset to CLE
+- maxbanks: Number of banks supported by SoC
 
 Optional properties:
 - bank-width : Width (in bytes) of the device.  If not present, the width
@@ -23,6 +24,7 @@ Example:
 		reg-names = "fsmc_regs", "nand_data";
 		st,ale-off = <0x20000>;
 		st,cle-off = <0x10000>;
+		maxbanks = <1>;
 
 		bank-width = <1>;
 		nand-skip-bbtscan;
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
index ed3627c..19e2328 100644
--- a/arch/arm/boot/dts/spear300.dtsi
+++ b/arch/arm/boot/dts/spear300.dtsi
@@ -42,6 +42,7 @@
 			reg-names = "fsmc_regs", "nand_data";
 			st,ale-off = <0x20000>;
 			st,cle-off = <0x10000>;
+			maxbanks = <1>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
index 62fc4fb..0272afb3 100644
--- a/arch/arm/boot/dts/spear310.dtsi
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -36,6 +36,7 @@
 			reg-names = "fsmc_regs", "nand_data";
 			st,ale-off = <0x10000>;
 			st,cle-off = <0x20000>;
+			maxbanks = <1>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
index 1f49d69..69fe50d 100644
--- a/arch/arm/boot/dts/spear320.dtsi
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -42,6 +42,7 @@
 			reg-names = "fsmc_regs", "nand_data";
 			st,ale-off = <0x20000>;
 			st,cle-off = <0x10000>;
+			maxbanks = <1>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
index a3c36e4..6ed57c8 100644
--- a/arch/arm/boot/dts/spear600.dtsi
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -71,6 +71,7 @@
 			reg-names = "fsmc_regs", "nand_data";
 			st,ale-off = <0x20000>;
 			st,cle-off = <0x10000>;
+			maxbanks = <1>;
 			status = "disabled";
 		};
 
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 03acf18..5ea9f71 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -1546,6 +1546,7 @@ static struct fsmc_nand_platform_data nand_platform_data = {
 	.width = FSMC_NAND_BW8,
 	.ale_off = PLAT_NAND_ALE,
 	.cle_off = PLAT_NAND_CLE,
+	.max_banks = 1,
 };
 
 static struct platform_device nand_device = {
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index bd89580..fc6a044 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -298,6 +298,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
  *			- Word access (CPU)
  *			- None (Use driver default ie bus width specific
  *			  CPU access)
+ * @max_banks:		Maximum number of banks supported
  * @select_chip:	Select a particular bank
  *
  * @data_pa:		NAND Physical port for Data
@@ -325,6 +326,7 @@ struct fsmc_nand_data {
 	struct mtd_partition	*partitions;
 	unsigned int		nr_partitions;
 	enum access_mode	mode;
+	uint32_t		max_banks;
 	void			(*select_chip)(uint32_t bank, uint32_t busw);
 
 	/* Virtual/Physical addresses for CPU/DMA access */
@@ -343,6 +345,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
 
 	host = container_of(mtd, struct fsmc_nand_data, mtd);
 
+	host->bank = chipnr;
 	switch (chipnr) {
 	case -1:
 		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
@@ -889,6 +892,7 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 	of_property_read_u32(np, "st,cle-off", &pdata->cle_off);
 	if (of_get_property(np, "nand-skip-bbtscan", NULL))
 		pdata->options = NAND_SKIP_BBTSCAN;
+	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
 
 	return 0;
 }
@@ -915,7 +919,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	struct resource *res;
 	dma_cap_mask_t mask;
 	int ret = 0;
-	u32 pid;
+	u32 pid, bank;
 	int i;
 
 	if (np) {
@@ -1023,13 +1027,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 		 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
 		 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
 
-	host->bank = pdata->bank;
 	host->select_chip = pdata->select_bank;
 	host->partitions = pdata->partitions;
 	host->nr_partitions = pdata->nr_partitions;
 	host->dev = &pdev->dev;
 	host->dev_timings = pdata->nand_timings;
 	host->mode = pdata->mode;
+	host->max_banks = pdata->max_banks;
 
 	if (host->mode == USE_DMA_ACCESS)
 		init_completion(&host->dma_access_complete);
@@ -1083,9 +1087,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 		break;
 	}
 
-	fsmc_nand_setup(host->regs_va, host->bank,
-			nand->options & NAND_BUSWIDTH_16,
-			host->dev_timings);
+	for (bank = 0; bank < host->max_banks; bank++)
+		fsmc_nand_setup(host->regs_va, bank,
+				nand->options & NAND_BUSWIDTH_16,
+				host->dev_timings);
 
 	if (AMBA_REV_BITS(host->pid) >= 8) {
 		nand->ecc.read_page = fsmc_read_page_hwecc;
@@ -1230,11 +1235,16 @@ static int fsmc_nand_suspend(struct device *dev)
 static int fsmc_nand_resume(struct device *dev)
 {
 	struct fsmc_nand_data *host = dev_get_drvdata(dev);
+	uint32_t bank;
+
 	if (host) {
 		clk_prepare_enable(host->clk);
-		fsmc_nand_setup(host->regs_va, host->bank,
-				host->nand.options & NAND_BUSWIDTH_16,
-				host->dev_timings);
+
+		for (bank = 0; bank < host->max_banks; bank++)
+			fsmc_nand_setup(host->regs_va, bank,
+					host->nand.options & NAND_BUSWIDTH_16,
+					host->dev_timings);
+
 	}
 	return 0;
 }
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index b200292..f0ab734 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -153,7 +153,7 @@ struct fsmc_nand_platform_data {
 	unsigned int		nr_partitions;
 	unsigned int		options;
 	unsigned int		width;
-	unsigned int		bank;
+	unsigned int		max_banks;
 
 	/* CLE, ALE offsets */
 	unsigned int		cle_off;
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:46 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:46 +0530
Subject: [PATCH 04/11] fsmc/nand: Accept nand timing parameters via DT
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>

Add support to accept nand timing parameters via device tree

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 .../devicetree/bindings/mtd/fsmc-nand.txt          | 20 ++++++++
 drivers/mtd/nand/fsmc_nand.c                       | 59 ++++++++++++++--------
 include/linux/mtd/fsmc.h                           |  2 +-
 3 files changed, 59 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
index 29d1a2f..6a7fc43 100644
--- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
@@ -13,6 +13,18 @@ Optional properties:
   defaults to 1 byte
 - nand-skip-bbtscan: Indicates the the BBT scanning should be skipped
 
+- nand-timings-enabled: Indicates if the timing parameters are passed
+  via DT
+- nand-timings,tclr:
+- nand-timings,tar:
+- nand-timings,thiz:
+- nand-timings,thold:
+- nand-timings,twait:
+- nand-timings,tset: All these timing parameters come from the actual
+  nand device specification. Each of this represents a number of time
+  period of hclk ie a number 4 in thold with hclk = 166MHz means that
+  thold = (1000 / 166) * 4 ns = 24.09ns
+
 Example:
 
 	fsmc: flash at d1800000 {
@@ -26,6 +38,14 @@ Example:
 		st,cle-off = <0x10000>;
 		maxbanks = <1>;
 
+		nand-timings-enabled;
+		nand-timings,tclr = <1>;
+		nand-timings,tar = <1>;
+		nand-timings,thiz = <1>;
+		nand-timings,thold = <4>;
+		nand-timings,twait = <6>;
+		nand-timings,tset = <0>;
+
 		bank-width = <1>;
 		nand-skip-bbtscan;
 
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index fc6a044..f3d69b3 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -415,27 +415,13 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
 {
 	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
 	uint32_t tclr, tar, thiz, thold, twait, tset;
-	struct fsmc_nand_timings *tims;
-	struct fsmc_nand_timings default_timings = {
-		.tclr	= FSMC_TCLR_1,
-		.tar	= FSMC_TAR_1,
-		.thiz	= FSMC_THIZ_1,
-		.thold	= FSMC_THOLD_4,
-		.twait	= FSMC_TWAIT_6,
-		.tset	= FSMC_TSET_0,
-	};
-
-	if (timings)
-		tims = timings;
-	else
-		tims = &default_timings;
 
-	tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
-	tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
-	thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
-	thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
-	twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
-	tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
+	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
+	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
+	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
+	thold = (timings->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
+	twait = (timings->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
+	tset = (timings->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
 
 	if (busw)
 		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
@@ -876,6 +862,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 					       struct device_node *np)
 {
 	struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct fsmc_nand_timings default_timings = {
+		.tclr	= FSMC_TCLR_1,
+		.tar	= FSMC_TAR_1,
+		.thiz	= FSMC_THIZ_1,
+		.thold	= FSMC_THOLD_4,
+		.twait	= FSMC_TWAIT_6,
+		.tset	= FSMC_TSET_0,
+	};
 	u32 val;
 
 	/* Set default NAND width to 8 bits */
@@ -894,6 +888,29 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 		pdata->options = NAND_SKIP_BBTSCAN;
 	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
 
+	if (of_property_read_bool(np, "nand-timings-enabled")) {
+		of_property_read_u32(np, "nand-timings,tclr", &val);
+		pdata->nand_timings.tclr = (uint8_t)val;
+
+		of_property_read_u32(np, "nand-timings,tar", &val);
+		pdata->nand_timings.tar = (uint8_t)val;
+
+		of_property_read_u32(np, "nand-timings,thiz", &val);
+		pdata->nand_timings.thiz = (uint8_t)val;
+
+		of_property_read_u32(np, "nand-timings,thold", &val);
+		pdata->nand_timings.thold = (uint8_t)val;
+
+		of_property_read_u32(np, "nand-timings,twait", &val);
+		pdata->nand_timings.twait = (uint8_t)val;
+
+		of_property_read_u32(np, "nand-timings,tset", &val);
+		pdata->nand_timings.tset = (uint8_t)val;
+	} else {
+		memcpy(&pdata->nand_timings, &default_timings,
+				sizeof(default_timings));
+	}
+
 	return 0;
 }
 #else
@@ -1031,7 +1048,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	host->partitions = pdata->partitions;
 	host->nr_partitions = pdata->nr_partitions;
 	host->dev = &pdev->dev;
-	host->dev_timings = pdata->nand_timings;
+	host->dev_timings = &pdata->nand_timings;
 	host->mode = pdata->mode;
 	host->max_banks = pdata->max_banks;
 
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index f0ab734..4fbdce4 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -148,7 +148,7 @@ enum access_mode {
  * this may be set to NULL
  */
 struct fsmc_nand_platform_data {
-	struct fsmc_nand_timings *nand_timings;
+	struct fsmc_nand_timings nand_timings;
 	struct mtd_partition	*partitions;
 	unsigned int		nr_partitions;
 	unsigned int		options;
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:48 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:48 +0530
Subject: [PATCH 06/11] fsmc/nand: Modify the wait to uninterruptible
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <3dcb002d0ad03dde9a91e8128dbaa320b8a264a9.1349778821.git.vipin.kumar@st.com>

Interruptible wait caused trouble in fsmc hardware state machine if the
application was killed abruptly. To make fsmc operation safe turn wait in to
un-interruptible.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index eaffd3b..4b29a64 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -607,7 +607,7 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len,
 	dma_async_issue_pending(chan);
 
 	ret =
-	wait_for_completion_interruptible_timeout(&host->dma_access_complete,
+	wait_for_completion_timeout(&host->dma_access_complete,
 				msecs_to_jiffies(3000));
 	if (ret <= 0) {
 		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:47 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:47 +0530
Subject: [PATCH 05/11] fsmc: Implement ready/busy through gpio pin
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>

The NAND devices have a ready/busy (active low) output which is connected to the
FSMC controller FSMC_RnB pin

The CPU can work in following two ways
* CPU keeps waiting for a ready response and it halts until it receives a ready
  response from NAND device. This halts the ldr instruction in between and in
  effect holds the CPU down for a number of cycles. During this period, CPU
  can't even service interrupts. This behavior is enabled via WAIT_ON bit of
  FSMC controller
* CPU merely issues the command and does not wait for response. The NAND device
  is later probed for being ready by reading the NAND_RnB signal

Until now, WAIT_ON was enabled by default. This patch implements reading the
device ready state through a gpio. The gpio number is passed via DT and this
patch also adds a corresponding binding for fsmc

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 .../devicetree/bindings/mtd/fsmc-nand.txt          |  5 ++
 drivers/mtd/nand/fsmc_nand.c                       | 54 +++++++++++++++++++---
 include/linux/mtd/fsmc.h                           | 11 +++++
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
index 6a7fc43..598bca2 100644
--- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
@@ -25,6 +25,11 @@ Optional properties:
   period of hclk ie a number 4 in thold with hclk = 166MHz means that
   thold = (1000 / 166) * 4 ns = 24.09ns
 
+- st,ready-busy: Should contain either of "rb-gpio" or "rb-wait". When
+  this property is not defined, the default is to use rb-wait.
+- st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
+  pin number is defined in this property
+
 Example:
 
 	fsmc: flash at d1800000 {
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index f3d69b3..eaffd3b 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -22,6 +22,7 @@
 #include <linux/dma-direction.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/resource.h>
@@ -32,6 +33,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -289,6 +291,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
  * @write_dma_chan:	DMA channel for write access to NAND
  * @dma_access_complete: Completion structure
  *
+ * @rb_pin:		Ready/Busy data
  * @dev_timings:	Timings to be programmed in controller
  * @partitions:		Partition info for a NAND Flash
  * @nr_partitions:	Total number of partition of a NAND flash
@@ -322,6 +325,7 @@ struct fsmc_nand_data {
 	struct completion	dma_access_complete;
 
 	/* Recieved from plat data */
+	struct fsmc_rbpin	*rbpin;
 	struct fsmc_nand_timings *dev_timings;
 	struct mtd_partition	*partitions;
 	unsigned int		nr_partitions;
@@ -410,12 +414,16 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
  * This routine initializes timing parameters related to NAND memory access in
  * FSMC registers
  */
-static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
-			   uint32_t busw, struct fsmc_nand_timings *timings)
+static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, uint32_t busw,
+			   struct fsmc_nand_timings *timings,
+			   struct fsmc_rbpin *rbpin)
 {
-	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
+	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE;
 	uint32_t tclr, tar, thiz, thold, twait, tset;
 
+	if (!rbpin || (rbpin->use_pin == FSMC_RB_WAIT))
+		value |= FSMC_WAITON;
+
 	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
 	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
 	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
@@ -857,6 +865,14 @@ static bool filter(struct dma_chan *chan, void *slave)
 	return true;
 }
 
+static int fsmc_dev_ready(struct mtd_info *mtd)
+{
+	struct fsmc_nand_data *host = container_of(mtd,
+					struct fsmc_nand_data, mtd);
+
+	return !!gpio_get_value(host->rbpin->gpio_pin);
+}
+
 #ifdef CONFIG_OF
 static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 					       struct device_node *np)
@@ -870,7 +886,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 		.twait	= FSMC_TWAIT_6,
 		.tset	= FSMC_TSET_0,
 	};
+	const char *rb;
 	u32 val;
+	enum of_gpio_flags flags;
 
 	/* Set default NAND width to 8 bits */
 	pdata->width = 8;
@@ -911,6 +929,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 				sizeof(default_timings));
 	}
 
+	if (!of_property_read_string(np, "st,ready-busy", &rb) &&
+			!strcmp(rb, "rb-gpio")) {
+		pdata->rbpin.use_pin = FSMC_RB_GPIO;
+		pdata->rbpin.gpio_pin =
+			of_get_named_gpio_flags(np, "st,rb-gpios", 0, &flags);
+	} else
+		pdata->rbpin.use_pin = FSMC_RB_WAIT;
+
 	return 0;
 }
 #else
@@ -1049,6 +1075,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	host->nr_partitions = pdata->nr_partitions;
 	host->dev = &pdev->dev;
 	host->dev_timings = &pdata->nand_timings;
+	host->rbpin = &pdata->rbpin;
+
 	host->mode = pdata->mode;
 	host->max_banks = pdata->max_banks;
 
@@ -1074,6 +1102,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	nand->select_chip = fsmc_select_chip;
 	nand->badblockbits = 7;
 
+	if (host->rbpin->use_pin != FSMC_RB_WAIT)
+		nand->dev_ready = fsmc_dev_ready;
+
+	if (host->rbpin->use_pin == FSMC_RB_GPIO) {
+		ret = gpio_request(host->rbpin->gpio_pin, "fsmc-rb");
+		if (ret < 0) {
+			dev_err(&pdev->dev, "gpio request fail: %d\n",
+					host->rbpin->gpio_pin);
+			goto err_gpio_req;
+		}
+	}
+
 	if (pdata->width == FSMC_NAND_BW16)
 		nand->options |= NAND_BUSWIDTH_16;
 
@@ -1107,7 +1147,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	for (bank = 0; bank < host->max_banks; bank++)
 		fsmc_nand_setup(host->regs_va, bank,
 				nand->options & NAND_BUSWIDTH_16,
-				host->dev_timings);
+				host->dev_timings, host->rbpin);
 
 	if (AMBA_REV_BITS(host->pid) >= 8) {
 		nand->ecc.read_page = fsmc_read_page_hwecc;
@@ -1211,6 +1251,9 @@ err_req_write_chnl:
 	if (host->mode == USE_DMA_ACCESS)
 		dma_release_channel(host->read_dma_chan);
 err_req_read_chnl:
+	if (host->rbpin->use_pin == FSMC_RB_GPIO)
+		gpio_free(host->rbpin->gpio_pin);
+err_gpio_req:
 	clk_disable_unprepare(host->clk);
 err_clk_prepare_enable:
 	clk_put(host->clk);
@@ -1260,8 +1303,7 @@ static int fsmc_nand_resume(struct device *dev)
 		for (bank = 0; bank < host->max_banks; bank++)
 			fsmc_nand_setup(host->regs_va, bank,
 					host->nand.options & NAND_BUSWIDTH_16,
-					host->dev_timings);
-
+					host->dev_timings, host->rbpin);
 	}
 	return 0;
 }
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index 4fbdce4..eed22a1 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -130,6 +130,16 @@ struct fsmc_nand_timings {
 	uint8_t tset;
 };
 
+enum rbpin {
+	FSMC_RB_WAIT = 0,
+	FSMC_RB_GPIO,
+};
+
+struct fsmc_rbpin {
+	enum rbpin	use_pin;
+	uint32_t	gpio_pin;
+};
+
 enum access_mode {
 	USE_DMA_ACCESS = 1,
 	USE_WORD_ACCESS,
@@ -149,6 +159,7 @@ enum access_mode {
  */
 struct fsmc_nand_platform_data {
 	struct fsmc_nand_timings nand_timings;
+	struct fsmc_rbpin	rbpin;
 	struct mtd_partition	*partitions;
 	unsigned int		nr_partitions;
 	unsigned int		options;
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:49 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:49 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>

read_buf/write_buf callbacks should be able to accept a user space memory
address (virtually contiguous memory) as buffer pointer.

This patch allocates a logically contiguous memory area which is use for dma
xfers during read and write accesses.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 4b29a64..8de6dcf 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -323,6 +323,7 @@ struct fsmc_nand_data {
 	struct dma_chan		*read_dma_chan;
 	struct dma_chan		*write_dma_chan;
 	struct completion	dma_access_complete;
+	void			*dma_buf;
 
 	/* Recieved from plat data */
 	struct fsmc_rbpin	*rbpin;
@@ -675,7 +676,8 @@ static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len)
 	struct fsmc_nand_data *host;
 
 	host = container_of(mtd, struct fsmc_nand_data, mtd);
-	dma_xfer(host, buf, len, DMA_FROM_DEVICE);
+	dma_xfer(host, host->dma_buf, len, DMA_FROM_DEVICE);
+	memcpy(buf, (const void *)host->dma_buf, len);
 }
 
 /*
@@ -690,7 +692,8 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
 	struct fsmc_nand_data *host;
 
 	host = container_of(mtd, struct fsmc_nand_data, mtd);
-	dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE);
+	memcpy(host->dma_buf, buf, len);
+	dma_xfer(host, host->dma_buf, len, DMA_TO_DEVICE);
 }
 
 /*
@@ -1133,6 +1136,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Unable to get write dma channel\n");
 			goto err_req_write_chnl;
 		}
+
+		host->dma_buf = kmalloc(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE,
+				GFP_KERNEL);
+		if (!host->dma_buf) {
+			dev_err(&pdev->dev, "failed to allocate dma buffer\n");
+			goto err_req_dma_buf;
+		}
 		nand->read_buf = fsmc_read_buf_dma;
 		nand->write_buf = fsmc_write_buf_dma;
 		break;
@@ -1246,6 +1256,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 err_probe:
 err_scan_ident:
 	if (host->mode == USE_DMA_ACCESS)
+		kfree(host->dma_buf);
+err_req_dma_buf:
+	if (host->mode == USE_DMA_ACCESS)
 		dma_release_channel(host->write_dma_chan);
 err_req_write_chnl:
 	if (host->mode == USE_DMA_ACCESS)
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:50 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:50 +0530
Subject: [PATCH 08/11] fsmc/nand: Use relaxed variants of io accessors
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <88484dbae96f7db42ce615552a4c758844a5e6cc.1349778821.git.vipin.kumar@st.com>

Use relaxed variants of readl/writel accessors. readl/writel io accessors use
explicit dsb instruction which causes stalls in the processor core resulting
several cycles of delay for each access

Use relaxed variants where ever possible. This also results in an improved
read/write performance.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 54 ++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 8de6dcf..f48ee60 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -400,13 +400,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 			pc |= FSMC_ENABLE;
 		else
 			pc &= ~FSMC_ENABLE;
-		writel(pc, FSMC_NAND_REG(regs, bank, PC));
+		writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC));
 	}
 
 	mb();
 
 	if (cmd != NAND_CMD_NONE)
-		writeb(cmd, this->IO_ADDR_W);
+		writeb_relaxed(cmd, this->IO_ADDR_W);
 }
 
 /*
@@ -433,14 +433,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, uint32_t busw,
 	tset = (timings->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
 
 	if (busw)
-		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
+		writel_relaxed(value | FSMC_DEVWID_16,
+				FSMC_NAND_REG(regs, bank, PC));
 	else
-		writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC));
+		writel_relaxed(value | FSMC_DEVWID_8,
+				FSMC_NAND_REG(regs, bank, PC));
 
-	writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
+	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar,
 			FSMC_NAND_REG(regs, bank, PC));
-	writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM));
-	writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB));
+	writel_relaxed(thiz | thold | twait | tset,
+			FSMC_NAND_REG(regs, bank, COMM));
+	writel_relaxed(thiz | thold | twait | tset,
+			FSMC_NAND_REG(regs, bank, ATTRIB));
 }
 
 /*
@@ -453,11 +457,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
 	void __iomem *regs = host->regs_va;
 	uint32_t bank = host->bank;
 
-	writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
+	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256,
 			FSMC_NAND_REG(regs, bank, PC));
-	writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
+	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN,
 			FSMC_NAND_REG(regs, bank, PC));
-	writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
+	writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN,
 			FSMC_NAND_REG(regs, bank, PC));
 }
 
@@ -477,7 +481,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
 	unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
 
 	do {
-		if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
+		if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY)
 			break;
 		else
 			cond_resched();
@@ -488,25 +492,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
 		return -ETIMEDOUT;
 	}
 
-	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1));
+	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
 	ecc[0] = (uint8_t) (ecc_tmp >> 0);
 	ecc[1] = (uint8_t) (ecc_tmp >> 8);
 	ecc[2] = (uint8_t) (ecc_tmp >> 16);
 	ecc[3] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2));
+	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
 	ecc[4] = (uint8_t) (ecc_tmp >> 0);
 	ecc[5] = (uint8_t) (ecc_tmp >> 8);
 	ecc[6] = (uint8_t) (ecc_tmp >> 16);
 	ecc[7] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3));
+	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
 	ecc[8] = (uint8_t) (ecc_tmp >> 0);
 	ecc[9] = (uint8_t) (ecc_tmp >> 8);
 	ecc[10] = (uint8_t) (ecc_tmp >> 16);
 	ecc[11] = (uint8_t) (ecc_tmp >> 24);
 
-	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS));
+	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
 	ecc[12] = (uint8_t) (ecc_tmp >> 16);
 
 	return 0;
@@ -526,7 +530,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
 	uint32_t bank = host->bank;
 	uint32_t ecc_tmp;
 
-	ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1));
+	ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
 	ecc[0] = (uint8_t) (ecc_tmp >> 0);
 	ecc[1] = (uint8_t) (ecc_tmp >> 8);
 	ecc[2] = (uint8_t) (ecc_tmp >> 16);
@@ -635,10 +639,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 		uint32_t *p = (uint32_t *)buf;
 		len = len >> 2;
 		for (i = 0; i < len; i++)
-			writel(p[i], chip->IO_ADDR_W);
+			writel_relaxed(p[i], chip->IO_ADDR_W);
 	} else {
 		for (i = 0; i < len; i++)
-			writeb(buf[i], chip->IO_ADDR_W);
+			writeb_relaxed(buf[i], chip->IO_ADDR_W);
 	}
 }
 
@@ -658,10 +662,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 		uint32_t *p = (uint32_t *)buf;
 		len = len >> 2;
 		for (i = 0; i < len; i++)
-			p[i] = readl(chip->IO_ADDR_R);
+			p[i] = readl_relaxed(chip->IO_ADDR_R);
 	} else {
 		for (i = 0; i < len; i++)
-			buf[i] = readb(chip->IO_ADDR_R);
+			buf[i] = readb_relaxed(chip->IO_ADDR_R);
 	}
 }
 
@@ -792,7 +796,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
 	uint32_t num_err, i;
 	uint32_t ecc1, ecc2, ecc3, ecc4;
 
-	num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
+	num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF;
 
 	/* no bit flipping */
 	if (likely(num_err == 0))
@@ -835,10 +839,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
 	 * uint64_t array and error offset indexes are populated in err_idx
 	 * array
 	 */
-	ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1));
-	ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2));
-	ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3));
-	ecc4 = readl(FSMC_NAND_REG(regs, bank, STS));
+	ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1));
+	ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2));
+	ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3));
+	ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS));
 
 	err_idx[0] = (ecc1 >> 0) & 0x1FFF;
 	err_idx[1] = (ecc1 >> 13) & 0x1FFF;
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:51 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:51 +0530
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>

change_bit routine accepts only ulong pointers as buffer, so an unaligned char
pointer passed to change_bit may lead to a crash.

Fix this bug by accessing the buffer as char pointer.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 drivers/mtd/nand/fsmc_nand.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index f48ee60..762cf83 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -859,7 +859,9 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
 		change_bit(1, (unsigned long *)&err_idx[i]);
 
 		if (err_idx[i] < chip->ecc.size * 8) {
-			change_bit(err_idx[i], (unsigned long *)dat);
+			uint8_t *p = dat + err_idx[i] / 8;
+			*p = *p ^ (1 << (err_idx[i] % 8));
+
 			i++;
 		}
 	}
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:52 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:52 +0530
Subject: [PATCH 10/11] fsmc/nand: Add sw bch support for ecc
 calculation/correction
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <3968b65e9aa0a81eca16ce0f20e45504da7ad7fe.1349778821.git.vipin.kumar@st.com>

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 .../devicetree/bindings/mtd/fsmc-nand.txt          |   2 +
 drivers/mtd/nand/fsmc_nand.c                       | 156 +++++++++++++--------
 include/linux/mtd/fsmc.h                           |   3 +
 3 files changed, 106 insertions(+), 55 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
index 598bca2..dcf513b 100644
--- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
@@ -30,6 +30,8 @@ Optional properties:
 - st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
   pin number is defined in this property
 
+- nand-sw-ecc: boolean indicating whether s/w ecc is supported
+
 Example:
 
 	fsmc: flash at d1800000 {
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 762cf83..ff84468 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -946,6 +946,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
 	} else
 		pdata->rbpin.use_pin = FSMC_RB_WAIT;
 
+	if (of_property_read_bool(np, "nand-sw-ecc"))
+		pdata->sw_ecc = true;
+
 	return 0;
 }
 #else
@@ -972,6 +975,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	dma_cap_mask_t mask;
 	int ret = 0;
 	u32 pid, bank;
+	uint oobeccsize, m;
 	int i;
 
 	if (np) {
@@ -1104,9 +1108,24 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 	nand->cmd_ctrl = fsmc_cmd_ctrl;
 	nand->chip_delay = 30;
 
-	nand->ecc.mode = NAND_ECC_HW;
-	nand->ecc.hwctl = fsmc_enable_hwecc;
-	nand->ecc.size = 512;
+	if (pdata->sw_ecc) {
+		nand->ecc.mode = NAND_ECC_SOFT_BCH;
+		/*
+		 * The recent devices require n-bit correctibility in x bytes.
+		 * The values of n and x varies as below
+		 * n - 1 to 100
+		 * x - 512 to 1K
+		 * TODO: For now, take x = 1K for all sw bch mathematics. Think
+		 * of a better way to handle other device dependent
+		 * requirements. May be it should come from board dts files
+		 */
+		nand->ecc.size = 1024;
+	} else {
+		nand->ecc.mode = NAND_ECC_HW;
+		nand->ecc.hwctl = fsmc_enable_hwecc;
+		nand->ecc.size = 512;
+	}
+
 	nand->options = pdata->options;
 	nand->select_chip = fsmc_select_chip;
 	nand->badblockbits = 7;
@@ -1165,17 +1184,19 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 				nand->options & NAND_BUSWIDTH_16,
 				host->dev_timings, host->rbpin);
 
-	if (AMBA_REV_BITS(host->pid) >= 8) {
-		nand->ecc.read_page = fsmc_read_page_hwecc;
-		nand->ecc.calculate = fsmc_read_hwecc_ecc4;
-		nand->ecc.correct = fsmc_bch8_correct_data;
-		nand->ecc.bytes = 13;
-		nand->ecc.strength = 8;
-	} else {
-		nand->ecc.calculate = fsmc_read_hwecc_ecc1;
-		nand->ecc.correct = nand_correct_data;
-		nand->ecc.bytes = 3;
-		nand->ecc.strength = 1;
+	if (nand->ecc.mode != NAND_ECC_SOFT_BCH) {
+		if (AMBA_REV_BITS(host->pid) >= 8) {
+			nand->ecc.read_page = fsmc_read_page_hwecc;
+			nand->ecc.calculate = fsmc_read_hwecc_ecc4;
+			nand->ecc.correct = fsmc_bch8_correct_data;
+			nand->ecc.bytes = 13;
+			nand->ecc.strength = 8;
+		} else {
+			nand->ecc.calculate = fsmc_read_hwecc_ecc1;
+			nand->ecc.correct = nand_correct_data;
+			nand->ecc.bytes = 3;
+			nand->ecc.strength = 1;
+		}
 	}
 
 	/*
@@ -1187,48 +1208,73 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
 		goto err_scan_ident;
 	}
 
-	if (AMBA_REV_BITS(host->pid) >= 8) {
-		switch (host->mtd.oobsize) {
-		case 16:
-			nand->ecc.layout = &fsmc_ecc4_16_layout;
-			host->ecc_place = &fsmc_ecc4_sp_place;
-			break;
-		case 64:
-			nand->ecc.layout = &fsmc_ecc4_64_layout;
-			host->ecc_place = &fsmc_ecc4_lp_place;
-			break;
-		case 128:
-			nand->ecc.layout = &fsmc_ecc4_128_layout;
-			host->ecc_place = &fsmc_ecc4_lp_place;
-			break;
-		case 224:
-			nand->ecc.layout = &fsmc_ecc4_224_layout;
-			host->ecc_place = &fsmc_ecc4_lp_place;
-			break;
-		case 256:
-			nand->ecc.layout = &fsmc_ecc4_256_layout;
-			host->ecc_place = &fsmc_ecc4_lp_place;
-			break;
-		default:
-			printk(KERN_WARNING "No oob scheme defined for "
-			       "oobsize %d\n", mtd->oobsize);
-			BUG();
-		}
+	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
+		/*
+		 * Initialize the ecc bytes and strength dynamically based on eccsize
+		 * and writesize.
+		 *
+		 * Parameters @eccsize and @eccbytes are used to compute BCH parameters
+		 * m (Galois field order) and t (error correction capability). @eccbytes
+		 * should be equal to the number of bytes required to store m*t bits,
+		 * where m is such that 2^m-1 > @eccsize*8.
+		 *
+		 * Example: to configure 4 bit correction per 512 bytes, you should pass
+		 * @eccsize = 512  (thus, m=13 is the smallest integer such that 2^m-1 >
+		 * 512*8) @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52
+		 * bits)
+		 *
+		 * Note: 2 bytes of oob are considered reserved for bad block marking
+		 */
+		m = fls(1 + 8 * nand->ecc.size);
+		oobeccsize = ((host->mtd.oobsize - 2) * \
+				nand->ecc.size) / host->mtd.writesize;
+		nand->ecc.bytes = (oobeccsize / m) * m;
+		nand->ecc.strength = (nand->ecc.bytes * 8) / m;
+		nand->ecc.layout = NULL;
 	} else {
-		switch (host->mtd.oobsize) {
-		case 16:
-			nand->ecc.layout = &fsmc_ecc1_16_layout;
-			break;
-		case 64:
-			nand->ecc.layout = &fsmc_ecc1_64_layout;
-			break;
-		case 128:
-			nand->ecc.layout = &fsmc_ecc1_128_layout;
-			break;
-		default:
-			printk(KERN_WARNING "No oob scheme defined for "
-			       "oobsize %d\n", mtd->oobsize);
-			BUG();
+		if (AMBA_REV_BITS(host->pid) >= 8) {
+			switch (host->mtd.oobsize) {
+			case 16:
+				nand->ecc.layout = &fsmc_ecc4_16_layout;
+				host->ecc_place = &fsmc_ecc4_sp_place;
+				break;
+			case 64:
+				nand->ecc.layout = &fsmc_ecc4_64_layout;
+				host->ecc_place = &fsmc_ecc4_lp_place;
+				break;
+			case 128:
+				nand->ecc.layout = &fsmc_ecc4_128_layout;
+				host->ecc_place = &fsmc_ecc4_lp_place;
+				break;
+			case 224:
+				nand->ecc.layout = &fsmc_ecc4_224_layout;
+				host->ecc_place = &fsmc_ecc4_lp_place;
+				break;
+			case 256:
+				nand->ecc.layout = &fsmc_ecc4_256_layout;
+				host->ecc_place = &fsmc_ecc4_lp_place;
+				break;
+			default:
+				printk(KERN_WARNING "No oob scheme defined for "
+						"oobsize %d\n", mtd->oobsize);
+				BUG();
+			}
+		} else {
+			switch (host->mtd.oobsize) {
+			case 16:
+				nand->ecc.layout = &fsmc_ecc1_16_layout;
+				break;
+			case 64:
+				nand->ecc.layout = &fsmc_ecc1_64_layout;
+				break;
+			case 128:
+				nand->ecc.layout = &fsmc_ecc1_128_layout;
+				break;
+			default:
+				printk(KERN_WARNING "No oob scheme defined for "
+						"oobsize %d\n", mtd->oobsize);
+				BUG();
+			}
 		}
 	}
 
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
index eed22a1..07eee6e 100644
--- a/include/linux/mtd/fsmc.h
+++ b/include/linux/mtd/fsmc.h
@@ -176,6 +176,9 @@ struct fsmc_nand_platform_data {
 	/* priv structures for dma accesses */
 	void			*read_dma_priv;
 	void			*write_dma_priv;
+
+	/* whether s/w ecc is supported */
+	bool			sw_ecc;
 };
 
 extern int __init fsmc_nor_init(struct platform_device *pdev,
-- 
1.7.11.4



From vipin.kumar at st.com  Tue Oct  9 06:44:53 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Tue, 9 Oct 2012 16:14:53 +0530
Subject: [PATCH 11/11] nand: Increase the ecc placement locations to 640
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <67e0aae3b23f37feb30789f5c6cb342b5684911a.1349778821.git.vipin.kumar@st.com>

Few devices like H27UBG8T2CTR have a writesize/oobsize of 8KB/640B.
This means that the maximum oobsize has gone up to 640 bytes and consequently
the maximum ecc placement locations have also gone up to 640.

Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
 include/linux/mtd/mtd.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 81d61e7..f9ac289 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -98,7 +98,7 @@ struct mtd_oob_ops {
 };
 
 #define MTD_MAX_OOBFREE_ENTRIES_LARGE	32
-#define MTD_MAX_ECCPOS_ENTRIES_LARGE	448
+#define MTD_MAX_ECCPOS_ENTRIES_LARGE	640
 /*
  * Internal ECC layout control structure. For historical reasons, there is a
  * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
-- 
1.7.11.4



From gerg at snapgear.com  Tue Oct  9 06:37:09 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Tue, 9 Oct 2012 20:37:09 +1000
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <20121009084418.GH18531@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
Message-ID: <5073FE55.2000402@snapgear.com>

Hi Uwe,

On 10/09/2012 06:44 PM, Uwe Kleine-K?nig wrote:
> On Tue, Oct 09, 2012 at 01:29:46PM +1000, Greg Ungerer wrote:
>> On 09/10/12 01:25, Uwe Kleine-K??nig wrote:
>>> This allows to put the filesystem at a defined address in ROM allowing
>>> to save more precious RAM.
>>>
>>> I think it's save to default to ROM because the intention of using the
>>> uclinux map is to use a romfs and so mtd-ram doesn't give you anything
>>> that mtd-rom doesn't.
>>>
>>> Signed-off-by: Uwe Kleine-K?????nig <u.kleine-koenig at pengutronix.de>
>>
>> Looks good to me, so:
>>
>> Acked-by: Greg Ungerer <gerg at uclinux.org>
>>
>> Couple of things to be aware of. Artem currently has a couple of
>> patches against this file (looks like at least 1 of them is currently
>> in linux-next). It will probably conflict with your changes, should
>> be easy enough to fix up.
> If you tell me a branch to test, I can do so.

Sure. All three patches I sent to the linux-mtd list are here:

The following changes since commit 979570e02981d4a8fc20b3cc8fd651856c98ee9d:
   Linus Torvalds (1):
         Linux 3.6-rc7

are available in the git repository at:

   git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git cfmmu

Greg Ungerer (3):
       mtd: fix wrong usage of ioremap_nocache() in uclinux.c map driver
       mtd: allow uclinux map driver to be used on any ColdFire CPU platform
       mtd: clean up uclinux.c map driver

  drivers/mtd/maps/Kconfig   |    2 +-
  drivers/mtd/maps/uclinux.c |   42 
+++++++++++++++++++-----------------------
  2 files changed, 20 insertions(+), 24 deletions(-)


As far as I can see Artem has pushed the first 2 into for linux-next,
but not the third. I am hoping he hops in here and lets us know what
his intentions are with the third...

Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From plagnioj at jcrosoft.com  Tue Oct  9 07:50:23 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 9 Oct 2012 13:50:23 +0200
Subject: [PATCH 10/11] fsmc/nand: Add sw bch support for ecc
 calculation/correction
In-Reply-To: <3968b65e9aa0a81eca16ce0f20e45504da7ad7fe.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <3968b65e9aa0a81eca16ce0f20e45504da7ad7fe.1349778821.git.vipin.kumar@st.com>
Message-ID: <20121009115023.GK12801@game.jcrosoft.org>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |   2 +
>  drivers/mtd/nand/fsmc_nand.c                       | 156 +++++++++++++--------
>  include/linux/mtd/fsmc.h                           |   3 +
>  3 files changed, 106 insertions(+), 55 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 598bca2..dcf513b 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -30,6 +30,8 @@ Optional properties:
>  - st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
>    pin number is defined in this property
>  
> +- nand-sw-ecc: boolean indicating whether s/w ecc is supported
> +
please use the generic binding
 - nand-ecc-mode = xx
>  Example:
>  
>  	fsmc: flash at d1800000 {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index 762cf83..ff84468 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -946,6 +946,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  	} else
>  		pdata->rbpin.use_pin = FSMC_RB_WAIT;
>  
> +	if (of_property_read_bool(np, "nand-sw-ecc"))
> +		pdata->sw_ecc = true;
> +
of_get_nand_ecc_mode

>  	return 0;
>  }
>  #else
> @@ -972,6 +975,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	dma_cap_mask_t mask;
>  	int ret = 0;
>  	u32 pid, bank;
> +	uint oobeccsize, m;
>  	int i;
>  
>  	if (np) {
> @@ -1104,9 +1108,24 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	nand->cmd_ctrl = fsmc_cmd_ctrl;
>  	nand->chip_delay = 30;
>  
> -	nand->ecc.mode = NAND_ECC_HW;
> -	nand->ecc.hwctl = fsmc_enable_hwecc;
> -	nand->ecc.size = 512;
> +	if (pdata->sw_ecc) {
> +		nand->ecc.mode = NAND_ECC_SOFT_BCH;
> +		/*
> +		 * The recent devices require n-bit correctibility in x bytes.
> +		 * The values of n and x varies as below
> +		 * n - 1 to 100
> +		 * x - 512 to 1K
> +		 * TODO: For now, take x = 1K for all sw bch mathematics. Think
> +		 * of a better way to handle other device dependent
> +		 * requirements. May be it should come from board dts files
> +		 */
> +		nand->ecc.size = 1024;
> +	} else {
> +		nand->ecc.mode = NAND_ECC_HW;
> +		nand->ecc.hwctl = fsmc_enable_hwecc;
> +		nand->ecc.size = 512;
> +	}
> +
>  	nand->options = pdata->options;
>  	nand->select_chip = fsmc_select_chip;
>  	nand->badblockbits = 7;
> @@ -1165,17 +1184,19 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  				nand->options & NAND_BUSWIDTH_16,
>  				host->dev_timings, host->rbpin);
>  
> -	if (AMBA_REV_BITS(host->pid) >= 8) {
> -		nand->ecc.read_page = fsmc_read_page_hwecc;
> -		nand->ecc.calculate = fsmc_read_hwecc_ecc4;
> -		nand->ecc.correct = fsmc_bch8_correct_data;
> -		nand->ecc.bytes = 13;
> -		nand->ecc.strength = 8;
> -	} else {
> -		nand->ecc.calculate = fsmc_read_hwecc_ecc1;
> -		nand->ecc.correct = nand_correct_data;
> -		nand->ecc.bytes = 3;
> -		nand->ecc.strength = 1;
> +	if (nand->ecc.mode != NAND_ECC_SOFT_BCH) {
> +		if (AMBA_REV_BITS(host->pid) >= 8) {
> +			nand->ecc.read_page = fsmc_read_page_hwecc;
> +			nand->ecc.calculate = fsmc_read_hwecc_ecc4;
> +			nand->ecc.correct = fsmc_bch8_correct_data;
> +			nand->ecc.bytes = 13;
> +			nand->ecc.strength = 8;
> +		} else {
> +			nand->ecc.calculate = fsmc_read_hwecc_ecc1;
> +			nand->ecc.correct = nand_correct_data;
> +			nand->ecc.bytes = 3;
> +			nand->ecc.strength = 1;
> +		}
>  	}
>  
>  	/*
> @@ -1187,48 +1208,73 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		goto err_scan_ident;
>  	}
>  
> -	if (AMBA_REV_BITS(host->pid) >= 8) {
> -		switch (host->mtd.oobsize) {
> -		case 16:
> -			nand->ecc.layout = &fsmc_ecc4_16_layout;
> -			host->ecc_place = &fsmc_ecc4_sp_place;
> -			break;
> -		case 64:
> -			nand->ecc.layout = &fsmc_ecc4_64_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 128:
> -			nand->ecc.layout = &fsmc_ecc4_128_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 224:
> -			nand->ecc.layout = &fsmc_ecc4_224_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		case 256:
> -			nand->ecc.layout = &fsmc_ecc4_256_layout;
> -			host->ecc_place = &fsmc_ecc4_lp_place;
> -			break;
> -		default:
> -			printk(KERN_WARNING "No oob scheme defined for "
> -			       "oobsize %d\n", mtd->oobsize);
> -			BUG();
> -		}
> +	if (nand->ecc.mode == NAND_ECC_SOFT_BCH) {
> +		/*
> +		 * Initialize the ecc bytes and strength dynamically based on eccsize
> +		 * and writesize.
> +		 *
> +		 * Parameters @eccsize and @eccbytes are used to compute BCH parameters
> +		 * m (Galois field order) and t (error correction capability). @eccbytes
> +		 * should be equal to the number of bytes required to store m*t bits,
> +		 * where m is such that 2^m-1 > @eccsize*8.
> +		 *
> +		 * Example: to configure 4 bit correction per 512 bytes, you should pass
> +		 * @eccsize = 512  (thus, m=13 is the smallest integer such that 2^m-1 >
> +		 * 512*8) @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52
> +		 * bits)
> +		 *
> +		 * Note: 2 bytes of oob are considered reserved for bad block marking
> +		 */
> +		m = fls(1 + 8 * nand->ecc.size);
> +		oobeccsize = ((host->mtd.oobsize - 2) * \
> +				nand->ecc.size) / host->mtd.writesize;
> +		nand->ecc.bytes = (oobeccsize / m) * m;
> +		nand->ecc.strength = (nand->ecc.bytes * 8) / m;
> +		nand->ecc.layout = NULL;
>  	} else {
> -		switch (host->mtd.oobsize) {
> -		case 16:
> -			nand->ecc.layout = &fsmc_ecc1_16_layout;
> -			break;
> -		case 64:
> -			nand->ecc.layout = &fsmc_ecc1_64_layout;
> -			break;
> -		case 128:
> -			nand->ecc.layout = &fsmc_ecc1_128_layout;
> -			break;
> -		default:
> -			printk(KERN_WARNING "No oob scheme defined for "
> -			       "oobsize %d\n", mtd->oobsize);
> -			BUG();
> +		if (AMBA_REV_BITS(host->pid) >= 8) {
> +			switch (host->mtd.oobsize) {
> +			case 16:
> +				nand->ecc.layout = &fsmc_ecc4_16_layout;
> +				host->ecc_place = &fsmc_ecc4_sp_place;
> +				break;
> +			case 64:
> +				nand->ecc.layout = &fsmc_ecc4_64_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 128:
> +				nand->ecc.layout = &fsmc_ecc4_128_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 224:
> +				nand->ecc.layout = &fsmc_ecc4_224_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			case 256:
> +				nand->ecc.layout = &fsmc_ecc4_256_layout;
> +				host->ecc_place = &fsmc_ecc4_lp_place;
> +				break;
> +			default:
> +				printk(KERN_WARNING "No oob scheme defined for "
> +						"oobsize %d\n", mtd->oobsize);
> +				BUG();
> +			}
> +		} else {
> +			switch (host->mtd.oobsize) {
> +			case 16:
> +				nand->ecc.layout = &fsmc_ecc1_16_layout;
> +				break;
> +			case 64:
> +				nand->ecc.layout = &fsmc_ecc1_64_layout;
> +				break;
> +			case 128:
> +				nand->ecc.layout = &fsmc_ecc1_128_layout;
> +				break;
> +			default:
> +				printk(KERN_WARNING "No oob scheme defined for "
> +						"oobsize %d\n", mtd->oobsize);
> +				BUG();
> +			}
>  		}
>  	}
>  
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index eed22a1..07eee6e 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -176,6 +176,9 @@ struct fsmc_nand_platform_data {
>  	/* priv structures for dma accesses */
>  	void			*read_dma_priv;
>  	void			*write_dma_priv;
> +
> +	/* whether s/w ecc is supported */
> +	bool			sw_ecc;
>  };
>  
>  extern int __init fsmc_nor_init(struct platform_device *pdev,
> -- 
> 1.7.11.4
> 


From plagnioj at jcrosoft.com  Tue Oct  9 07:52:45 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 9 Oct 2012 13:52:45 +0200
Subject: [PATCH 02/11] fsmc/nand: Rearrange the fsmc_nand_data
 structure and update comments
In-Reply-To: <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>
Message-ID: <20121009115245.GL12801@game.jcrosoft.org>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  drivers/mtd/nand/fsmc_nand.c | 51 ++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index e96d7d1..bd89580 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -278,52 +278,61 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   * struct fsmc_nand_data - structure for FSMC NAND device state
>   *
>   * @pid:		Part ID on the AMBA PrimeCell format
> - * @mtd:		MTD info for a NAND flash.
> - * @nand:		Chip related info for a NAND flash.
> - * @partitions:		Partition info for a NAND Flash.
> - * @nr_partitions:	Total number of partition of a NAND flash.
> - *
> - * @ecc_place:		ECC placing locations in oobfree type format.
> - * @bank:		Bank number for probed device.
> - * @clk:		Clock structure for FSMC.
> + * @mtd:		MTD info for a NAND flash
> + * @nand:		Chip related info for a NAND flash
> + * @dev:		Device structure pointer
> + * @clk:		Clock structure for FSMC
> + * @ecc_place:		ECC placing locations in oobfree type format
> + * @bank:		Bank number for probed device
>   *
>   * @read_dma_chan:	DMA channel for read access
>   * @write_dma_chan:	DMA channel for write access to NAND
>   * @dma_access_complete: Completion structure
>   *
> - * @data_pa:		NAND Physical port for Data.
> - * @data_va:		NAND port for Data.
> - * @cmd_va:		NAND port for Command.
> - * @addr_va:		NAND port for Address.
> - * @regs_va:		FSMC regs base address.
> + * @dev_timings:	Timings to be programmed in controller
> + * @partitions:		Partition info for a NAND Flash
> + * @nr_partitions:	Total number of partition of a NAND flash
> + * @mode:		Defines the NAND device access mode
> + *			Can be one of:
> + *			- DMA access
> + *			- Word access (CPU)
> + *			- None (Use driver default ie bus width specific
> + *			  CPU access)
> + * @select_chip:	Select a particular bank
> + *
> + * @data_pa:		NAND Physical port for Data
> + * @data_va:		NAND port for Data
> + * @cmd_va:		NAND port for Command
> + * @addr_va:		NAND port for Address
> + * @regs_va:		FSMC regs base address
>   */
>  struct fsmc_nand_data {
>  	u32			pid;
>  	struct mtd_info		mtd;
>  	struct nand_chip	nand;
> -	struct mtd_partition	*partitions;
> -	unsigned int		nr_partitions;
> -
> -	struct fsmc_eccplace	*ecc_place;
> -	unsigned int		bank;
>  	struct device		*dev;
> -	enum access_mode	mode;
>  	struct clk		*clk;
> +	struct fsmc_eccplace	*ecc_place;
> +	unsigned int		bank;
>  
>  	/* DMA related objects */
>  	struct dma_chan		*read_dma_chan;
>  	struct dma_chan		*write_dma_chan;
>  	struct completion	dma_access_complete;
>  
> +	/* Recieved from plat data */
>  	struct fsmc_nand_timings *dev_timings;
> +	struct mtd_partition	*partitions;
> +	unsigned int		nr_partitions;
where do you use those execpt at probe time
> +	enum access_mode	mode;
> +	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  
> +	/* Virtual/Physical addresses for CPU/DMA access */
>  	dma_addr_t		data_pa;
>  	void __iomem		*data_va;
>  	void __iomem		*cmd_va;
>  	void __iomem		*addr_va;
>  	void __iomem		*regs_va;
> -
> -	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  };
>  
>  /* Assert CS signal based on chipnr */
> -- 
> 1.7.11.4
> 


From plagnioj at jcrosoft.com  Tue Oct  9 07:55:23 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 9 Oct 2012 13:55:23 +0200
Subject: [PATCH 03/11] fsmc/nand: Support multiple banks connected to
 controller
In-Reply-To: <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>
Message-ID: <20121009115523.GM12801@game.jcrosoft.org>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Support up to max_banks number of banks in fsmc driver.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
please rebase this over my patch that drop -off to resource
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |  2 ++
>  arch/arm/boot/dts/spear300.dtsi                    |  1 +
>  arch/arm/boot/dts/spear310.dtsi                    |  1 +
>  arch/arm/boot/dts/spear320.dtsi                    |  1 +
>  arch/arm/boot/dts/spear600.dtsi                    |  1 +
>  arch/arm/mach-u300/core.c                          |  1 +
>  drivers/mtd/nand/fsmc_nand.c                       | 26 +++++++++++++++-------
>  include/linux/mtd/fsmc.h                           |  2 +-
>  8 files changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index e2c663b..29d1a2f 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -6,6 +6,7 @@ Required properties:
>  - reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
>  - st,ale-off : Chip specific offset to ALE
>  - st,cle-off : Chip specific offset to CLE
> +- maxbanks: Number of banks supported by SoC
make it optionnal will simplify the binding with 1 by default and will allow
to avoid issue

>  
>  Optional properties:
>  - bank-width : Width (in bytes) of the device.  If not present, the width
> @@ -23,6 +24,7 @@ Example:
>  		reg-names = "fsmc_regs", "nand_data";
>  		st,ale-off = <0x20000>;
>  		st,cle-off = <0x10000>;
> +		maxbanks = <1>;
>  
>  		bank-width = <1>;
>  		nand-skip-bbtscan;
> diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
> index ed3627c..19e2328 100644
> --- a/arch/arm/boot/dts/spear300.dtsi
> +++ b/arch/arm/boot/dts/spear300.dtsi
> @@ -42,6 +42,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
> index 62fc4fb..0272afb3 100644
> --- a/arch/arm/boot/dts/spear310.dtsi
> +++ b/arch/arm/boot/dts/spear310.dtsi
> @@ -36,6 +36,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x10000>;
>  			st,cle-off = <0x20000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
> index 1f49d69..69fe50d 100644
> --- a/arch/arm/boot/dts/spear320.dtsi
> +++ b/arch/arm/boot/dts/spear320.dtsi
> @@ -42,6 +42,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
> index a3c36e4..6ed57c8 100644
> --- a/arch/arm/boot/dts/spear600.dtsi
> +++ b/arch/arm/boot/dts/spear600.dtsi
> @@ -71,6 +71,7 @@
>  			reg-names = "fsmc_regs", "nand_data";
>  			st,ale-off = <0x20000>;
>  			st,cle-off = <0x10000>;
> +			maxbanks = <1>;
>  			status = "disabled";
>  		};
>  
> diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
> index 03acf18..5ea9f71 100644
> --- a/arch/arm/mach-u300/core.c
> +++ b/arch/arm/mach-u300/core.c
> @@ -1546,6 +1546,7 @@ static struct fsmc_nand_platform_data nand_platform_data = {
>  	.width = FSMC_NAND_BW8,
>  	.ale_off = PLAT_NAND_ALE,
>  	.cle_off = PLAT_NAND_CLE,
> +	.max_banks = 1,
>  };
>  
>  static struct platform_device nand_device = {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index bd89580..fc6a044 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -298,6 +298,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   *			- Word access (CPU)
>   *			- None (Use driver default ie bus width specific
>   *			  CPU access)
> + * @max_banks:		Maximum number of banks supported
>   * @select_chip:	Select a particular bank
>   *
>   * @data_pa:		NAND Physical port for Data
> @@ -325,6 +326,7 @@ struct fsmc_nand_data {
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
>  	enum access_mode	mode;
> +	uint32_t		max_banks;
>  	void			(*select_chip)(uint32_t bank, uint32_t busw);
>  
>  	/* Virtual/Physical addresses for CPU/DMA access */
> @@ -343,6 +345,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
>  
>  	host = container_of(mtd, struct fsmc_nand_data, mtd);
>  
> +	host->bank = chipnr;
>  	switch (chipnr) {
>  	case -1:
>  		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
> @@ -889,6 +892,7 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  	of_property_read_u32(np, "st,cle-off", &pdata->cle_off);
>  	if (of_get_property(np, "nand-skip-bbtscan", NULL))
>  		pdata->options = NAND_SKIP_BBTSCAN;
> +	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
>  
>  	return 0;
>  }
> @@ -915,7 +919,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	dma_cap_mask_t mask;
>  	int ret = 0;
> -	u32 pid;
> +	u32 pid, bank;
>  	int i;
>  
>  	if (np) {
> @@ -1023,13 +1027,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
>  		 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
>  
> -	host->bank = pdata->bank;
>  	host->select_chip = pdata->select_bank;
>  	host->partitions = pdata->partitions;
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
>  	host->dev_timings = pdata->nand_timings;
>  	host->mode = pdata->mode;
> +	host->max_banks = pdata->max_banks;
>  
>  	if (host->mode == USE_DMA_ACCESS)
>  		init_completion(&host->dma_access_complete);
> @@ -1083,9 +1087,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  		break;
>  	}
>  
> -	fsmc_nand_setup(host->regs_va, host->bank,
> -			nand->options & NAND_BUSWIDTH_16,
> -			host->dev_timings);
> +	for (bank = 0; bank < host->max_banks; bank++)
> +		fsmc_nand_setup(host->regs_va, bank,
> +				nand->options & NAND_BUSWIDTH_16,
> +				host->dev_timings);
>  
>  	if (AMBA_REV_BITS(host->pid) >= 8) {
>  		nand->ecc.read_page = fsmc_read_page_hwecc;
> @@ -1230,11 +1235,16 @@ static int fsmc_nand_suspend(struct device *dev)
>  static int fsmc_nand_resume(struct device *dev)
>  {
>  	struct fsmc_nand_data *host = dev_get_drvdata(dev);
> +	uint32_t bank;
> +
>  	if (host) {
>  		clk_prepare_enable(host->clk);
> -		fsmc_nand_setup(host->regs_va, host->bank,
> -				host->nand.options & NAND_BUSWIDTH_16,
> -				host->dev_timings);
> +
> +		for (bank = 0; bank < host->max_banks; bank++)
> +			fsmc_nand_setup(host->regs_va, bank,
> +					host->nand.options & NAND_BUSWIDTH_16,
> +					host->dev_timings);
> +
>  	}
>  	return 0;
>  }
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index b200292..f0ab734 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -153,7 +153,7 @@ struct fsmc_nand_platform_data {
>  	unsigned int		nr_partitions;
>  	unsigned int		options;
>  	unsigned int		width;
> -	unsigned int		bank;
> +	unsigned int		max_banks;
>  
>  	/* CLE, ALE offsets */
>  	unsigned int		cle_off;
> -- 
> 1.7.11.4
> 


From plagnioj at jcrosoft.com  Tue Oct  9 07:57:05 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 9 Oct 2012 13:57:05 +0200
Subject: [PATCH 04/11] fsmc/nand: Accept nand timing parameters via DT
In-Reply-To: <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>
Message-ID: <20121009115705.GN12801@game.jcrosoft.org>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> Add support to accept nand timing parameters via device tree
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          | 20 ++++++++
>  drivers/mtd/nand/fsmc_nand.c                       | 59 ++++++++++++++--------
>  include/linux/mtd/fsmc.h                           |  2 +-
>  3 files changed, 59 insertions(+), 22 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 29d1a2f..6a7fc43 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -13,6 +13,18 @@ Optional properties:
>    defaults to 1 byte
>  - nand-skip-bbtscan: Indicates the the BBT scanning should be skipped
>  
> +- nand-timings-enabled: Indicates if the timing parameters are passed
> +  via DT
> +- nand-timings,tclr:
> +- nand-timings,tar:
> +- nand-timings,thiz:
> +- nand-timings,thold:
> +- nand-timings,twait:
> +- nand-timings,tset: All these timing parameters come from the actual
> +  nand device specification. Each of this represents a number of time
> +  period of hclk ie a number 4 in thold with hclk = 166MHz means that
> +  thold = (1000 / 166) * 4 ns = 24.09ns
> +
>  Example:
>  
>  	fsmc: flash at d1800000 {
> @@ -26,6 +38,14 @@ Example:
>  		st,cle-off = <0x10000>;
>  		maxbanks = <1>;
>  
> +		nand-timings-enabled;
> +		nand-timings,tclr = <1>;
> +		nand-timings,tar = <1>;
> +		nand-timings,thiz = <1>;
> +		nand-timings,thold = <4>;
> +		nand-timings,twait = <6>;
> +		nand-timings,tset = <0>;
> +
>  		bank-width = <1>;
>  		nand-skip-bbtscan;
>  
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index fc6a044..f3d69b3 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -415,27 +415,13 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
>  {
>  	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
>  	uint32_t tclr, tar, thiz, thold, twait, tset;
> -	struct fsmc_nand_timings *tims;
> -	struct fsmc_nand_timings default_timings = {
> -		.tclr	= FSMC_TCLR_1,
> -		.tar	= FSMC_TAR_1,
> -		.thiz	= FSMC_THIZ_1,
> -		.thold	= FSMC_THOLD_4,
> -		.twait	= FSMC_TWAIT_6,
> -		.tset	= FSMC_TSET_0,
> -	};
> -
> -	if (timings)
> -		tims = timings;
> -	else
> -		tims = &default_timings;
>  
> -	tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
> -	tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
> -	thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> -	thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
> -	twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
> -	tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
> +	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
> +	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
> +	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> +	thold = (timings->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
> +	twait = (timings->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
> +	tset = (timings->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
>  
>  	if (busw)
>  		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
> @@ -876,6 +862,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  					       struct device_node *np)
>  {
>  	struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	struct fsmc_nand_timings default_timings = {
> +		.tclr	= FSMC_TCLR_1,
> +		.tar	= FSMC_TAR_1,
> +		.thiz	= FSMC_THIZ_1,
> +		.thold	= FSMC_THOLD_4,
> +		.twait	= FSMC_TWAIT_6,
> +		.tset	= FSMC_TSET_0,
> +	};
>  	u32 val;
>  
>  	/* Set default NAND width to 8 bits */
> @@ -894,6 +888,29 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  		pdata->options = NAND_SKIP_BBTSCAN;
>  	of_property_read_u32(np, "maxbanks", &pdata->max_banks);
>  
> +	if (of_property_read_bool(np, "nand-timings-enabled")) {
> +		of_property_read_u32(np, "nand-timings,tclr", &val);
> +		pdata->nand_timings.tclr = (uint8_t)val;
use a mask will be better
> +
> +		of_property_read_u32(np, "nand-timings,tar", &val);
> +		pdata->nand_timings.tar = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,thiz", &val);
> +		pdata->nand_timings.thiz = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,thold", &val);
> +		pdata->nand_timings.thold = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,twait", &val);
> +		pdata->nand_timings.twait = (uint8_t)val;
> +
> +		of_property_read_u32(np, "nand-timings,tset", &val);
> +		pdata->nand_timings.tset = (uint8_t)val;
> +	} else {
> +		memcpy(&pdata->nand_timings, &default_timings,
> +				sizeof(default_timings));
> +	}
> +
>  	return 0;
>  }
>  #else
> @@ -1031,7 +1048,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	host->partitions = pdata->partitions;
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
> -	host->dev_timings = pdata->nand_timings;
> +	host->dev_timings = &pdata->nand_timings;
>  	host->mode = pdata->mode;
>  	host->max_banks = pdata->max_banks;
>  
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index f0ab734..4fbdce4 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -148,7 +148,7 @@ enum access_mode {
>   * this may be set to NULL
>   */
>  struct fsmc_nand_platform_data {
> -	struct fsmc_nand_timings *nand_timings;
> +	struct fsmc_nand_timings nand_timings;
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
>  	unsigned int		options;
> -- 
> 1.7.11.4
> 


From dedekind1 at gmail.com  Tue Oct  9 08:00:06 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 09 Oct 2012 15:00:06 +0300
Subject: UBIFS Recovery Issue: 'grab_empty_leb: could not find an empty
 LEB'
In-Reply-To: <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
References: <CAP+RiCC1afVbKAZESMcZGd1G3+7aKuLTQGggOEFGZxQM6o+QQA@mail.gmail.com>
 <1346413469.9709.44.camel@sauron.fi.intel.com>
 <CAP+RiCBRopbShAGf_fWCvK2R=uPPR1j4Pz12JfJxdEMUjwofNw@mail.gmail.com>
 <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
Message-ID: <1349784006.1992.114.camel@sauron.fi.intel.com>

On Mon, 2012-09-17 at 08:34 -0500, Brent Taylor wrote:
> Artem,
>    I was finally able to capture the issue again with linux version
> 3.5.1, and I now have a 64MB mtd image for you to look at.  The issue
> occurred in the root filesystem this time.  Let me know what's the
> best way to get this image to you.  The image was retrieved from a NOR
> flash chip instead of a NAND flash chip, but I've seen the error on
> both which leads me to believe it's not a flash driver issue and it's
> something in the UBIFS subsystem.  If there is more data you need from
> me to help track this down, just let me know.

I've took a look. So far I do not understand what is going on. There
seems to be some bug in UBIFS. I'll try to dig deeper.

But what I've noticed that if you do this:

echo 1 > /sys/kernel/debug/ubifs/chk_lprops

before mounting UBIFS, then it mounts fine. If this issue is a blocker
for you, you may use this as a workaround.

Note, this enables lprops checks in UBIFS which slow it down. So you can
use this trick only to mount, and then you can write 0 to that file to
disable the checks.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121009/b00dcece/attachment.sig>

From plagnioj at jcrosoft.com  Tue Oct  9 07:59:24 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 9 Oct 2012 13:59:24 +0200
Subject: [PATCH 05/11] fsmc: Implement ready/busy through gpio pin
In-Reply-To: <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>
Message-ID: <20121009115924.GO12801@game.jcrosoft.org>

On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
> The NAND devices have a ready/busy (active low) output which is connected to the
> FSMC controller FSMC_RnB pin
> 
> The CPU can work in following two ways
> * CPU keeps waiting for a ready response and it halts until it receives a ready
>   response from NAND device. This halts the ldr instruction in between and in
>   effect holds the CPU down for a number of cycles. During this period, CPU
>   can't even service interrupts. This behavior is enabled via WAIT_ON bit of
>   FSMC controller
> * CPU merely issues the command and does not wait for response. The NAND device
>   is later probed for being ready by reading the NAND_RnB signal
> 
> Until now, WAIT_ON was enabled by default. This patch implements reading the
> device ready state through a gpio. The gpio number is passed via DT and this
> patch also adds a corresponding binding for fsmc
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  .../devicetree/bindings/mtd/fsmc-nand.txt          |  5 ++
>  drivers/mtd/nand/fsmc_nand.c                       | 54 +++++++++++++++++++---
>  include/linux/mtd/fsmc.h                           | 11 +++++
>  3 files changed, 64 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> index 6a7fc43..598bca2 100644
> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> @@ -25,6 +25,11 @@ Optional properties:
>    period of hclk ie a number 4 in thold with hclk = 166MHz means that
>    thold = (1000 / 166) * 4 ns = 24.09ns
>  
> +- st,ready-busy: Should contain either of "rb-gpio" or "rb-wait". When
> +  this property is not defined, the default is to use rb-wait.
> +- st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
> +  pin number is defined in this property
> +
>  Example:
>  
>  	fsmc: flash at d1800000 {
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index f3d69b3..eaffd3b 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -22,6 +22,7 @@
>  #include <linux/dma-direction.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/err.h>
> +#include <linux/gpio.h>
>  #include <linux/init.h>
>  #include <linux/module.h>
>  #include <linux/resource.h>
> @@ -32,6 +33,7 @@
>  #include <linux/mtd/nand_ecc.h>
>  #include <linux/platform_device.h>
>  #include <linux/of.h>
> +#include <linux/of_gpio.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> @@ -289,6 +291,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>   * @write_dma_chan:	DMA channel for write access to NAND
>   * @dma_access_complete: Completion structure
>   *
> + * @rb_pin:		Ready/Busy data
>   * @dev_timings:	Timings to be programmed in controller
>   * @partitions:		Partition info for a NAND Flash
>   * @nr_partitions:	Total number of partition of a NAND flash
> @@ -322,6 +325,7 @@ struct fsmc_nand_data {
>  	struct completion	dma_access_complete;
>  
>  	/* Recieved from plat data */
> +	struct fsmc_rbpin	*rbpin;
>  	struct fsmc_nand_timings *dev_timings;
>  	struct mtd_partition	*partitions;
>  	unsigned int		nr_partitions;
> @@ -410,12 +414,16 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
>   * This routine initializes timing parameters related to NAND memory access in
>   * FSMC registers
>   */
> -static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
> -			   uint32_t busw, struct fsmc_nand_timings *timings)
> +static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, uint32_t busw,
> +			   struct fsmc_nand_timings *timings,
> +			   struct fsmc_rbpin *rbpin)
>  {
> -	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
> +	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE;
>  	uint32_t tclr, tar, thiz, thold, twait, tset;
>  
> +	if (!rbpin || (rbpin->use_pin == FSMC_RB_WAIT))
> +		value |= FSMC_WAITON;
> +
>  	tclr = (timings->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
>  	tar = (timings->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
>  	thiz = (timings->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
> @@ -857,6 +865,14 @@ static bool filter(struct dma_chan *chan, void *slave)
>  	return true;
>  }
>  
> +static int fsmc_dev_ready(struct mtd_info *mtd)
> +{
> +	struct fsmc_nand_data *host = container_of(mtd,
> +					struct fsmc_nand_data, mtd);
> +
> +	return !!gpio_get_value(host->rbpin->gpio_pin);
> +}
> +
>  #ifdef CONFIG_OF
>  static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  					       struct device_node *np)
> @@ -870,7 +886,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  		.twait	= FSMC_TWAIT_6,
>  		.tset	= FSMC_TSET_0,
>  	};
> +	const char *rb;
>  	u32 val;
> +	enum of_gpio_flags flags;
>  
>  	/* Set default NAND width to 8 bits */
>  	pdata->width = 8;
> @@ -911,6 +929,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>  				sizeof(default_timings));
>  	}
>  
> +	if (!of_property_read_string(np, "st,ready-busy", &rb) &&
> +			!strcmp(rb, "rb-gpio")) {
> +		pdata->rbpin.use_pin = FSMC_RB_GPIO;
> +		pdata->rbpin.gpio_pin =
> +			of_get_named_gpio_flags(np, "st,rb-gpios", 0, &flags);
> +	} else
> +		pdata->rbpin.use_pin = FSMC_RB_WAIT;
> +
>  	return 0;
>  }
>  #else
> @@ -1049,6 +1075,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	host->nr_partitions = pdata->nr_partitions;
>  	host->dev = &pdev->dev;
>  	host->dev_timings = &pdata->nand_timings;
> +	host->rbpin = &pdata->rbpin;
> +
>  	host->mode = pdata->mode;
>  	host->max_banks = pdata->max_banks;
>  
> @@ -1074,6 +1102,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	nand->select_chip = fsmc_select_chip;
>  	nand->badblockbits = 7;
>  
> +	if (host->rbpin->use_pin != FSMC_RB_WAIT)
> +		nand->dev_ready = fsmc_dev_ready;
> +
> +	if (host->rbpin->use_pin == FSMC_RB_GPIO) {
> +		ret = gpio_request(host->rbpin->gpio_pin, "fsmc-rb");
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "gpio request fail: %d\n",
> +					host->rbpin->gpio_pin);
> +			goto err_gpio_req;
> +		}
> +	}
> +
>  	if (pdata->width == FSMC_NAND_BW16)
>  		nand->options |= NAND_BUSWIDTH_16;
>  
> @@ -1107,7 +1147,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>  	for (bank = 0; bank < host->max_banks; bank++)
>  		fsmc_nand_setup(host->regs_va, bank,
>  				nand->options & NAND_BUSWIDTH_16,
> -				host->dev_timings);
> +				host->dev_timings, host->rbpin);
>  
>  	if (AMBA_REV_BITS(host->pid) >= 8) {
>  		nand->ecc.read_page = fsmc_read_page_hwecc;
> @@ -1211,6 +1251,9 @@ err_req_write_chnl:
>  	if (host->mode == USE_DMA_ACCESS)
>  		dma_release_channel(host->read_dma_chan);
>  err_req_read_chnl:
> +	if (host->rbpin->use_pin == FSMC_RB_GPIO)
> +		gpio_free(host->rbpin->gpio_pin);
> +err_gpio_req:
>  	clk_disable_unprepare(host->clk);
>  err_clk_prepare_enable:
>  	clk_put(host->clk);
> @@ -1260,8 +1303,7 @@ static int fsmc_nand_resume(struct device *dev)
>  		for (bank = 0; bank < host->max_banks; bank++)
>  			fsmc_nand_setup(host->regs_va, bank,
>  					host->nand.options & NAND_BUSWIDTH_16,
> -					host->dev_timings);
> -
> +					host->dev_timings, host->rbpin);
>  	}
>  	return 0;
>  }
> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
> index 4fbdce4..eed22a1 100644
> --- a/include/linux/mtd/fsmc.h
> +++ b/include/linux/mtd/fsmc.h
> @@ -130,6 +130,16 @@ struct fsmc_nand_timings {
>  	uint8_t tset;
>  };
>  
> +enum rbpin {
> +	FSMC_RB_WAIT = 0,
> +	FSMC_RB_GPIO,
> +};
> +
> +struct fsmc_rbpin {
> +	enum rbpin	use_pin;
> +	uint32_t	gpio_pin;
> +};
> +
>  enum access_mode {
>  	USE_DMA_ACCESS = 1,
>  	USE_WORD_ACCESS,
> @@ -149,6 +159,7 @@ enum access_mode {
>   */
>  struct fsmc_nand_platform_data {
>  	struct fsmc_nand_timings nand_timings;
> +	struct fsmc_rbpin	rbpin;
do more simple
	int 			rbpin;

	and set it as -EINVAL to use RB_WAIT

so in the binding if you do not specifcy a gpio or a valid one we switch to
wait

Best Regards,
J.


From avinashphilip at ti.com  Tue Oct  9 08:36:50 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Tue, 9 Oct 2012 12:36:50 +0000
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <20121005142338.GA7199@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
Message-ID: <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>

On Fri, Oct 05, 2012 at 19:53:38, Ivan Djelic wrote:
> On Fri, Oct 05, 2012 at 09:51:50AM +0100, Philip, Avinash wrote:
> > On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
> > > On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
> > > > On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
> > > > > ELM module can be used for error correction of BCH 4 & 8 bit. Also
> > > > > support read & write page in one shot by adding custom read_page &
> > > > > write_page methods. This helps in optimizing code.
> > > > > 
> > > > > New structure member "is_elm_used" is added to know the status of
> > > > > whether the ELM module is used for error correction or not.
> > > > > 
> > > > > Note:
> > > > > ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
> > > > > with RBL ECC layout, even though the requirement was only 13 byte. This
> > > > > results a common ecc layout across RBL, U-boot & Linux.
> > > > > 
> > > > 
> > > > See a few comments below,
> > > > 
> > > > (...)
> > > > > +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
> > > > > +                               u_char *read_ecc, u_char *calc_ecc)
> > > > > +{
> > > > > +       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> > > > > +                       mtd);
> > > > > +       int eccsteps = info->nand.ecc.steps;
> > > > > +       int i , j, stat = 0;
> > > > > +       int eccsize, eccflag, size;
> > > > > +       struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
> > > > > +       u_char *ecc_vec = calc_ecc;
> > > > > +       enum bch_ecc type;
> > > > > +       bool is_error_reported = false;
> > > > > +
> > > > > +       /* initialize elm error vector to zero */
> > > > > +       memset(err_vec, 0, sizeof(err_vec));
> > > > > +       if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
> > > > > +               size = BCH8_SIZE;
> > > > > +               eccsize = BCH8_ECC_OOB_BYTES;
> > > > > +               type = BCH8_ECC;
> > > > > +       } else {
> > > > > +               size = BCH4_SIZE;
> > > > > +               eccsize = BCH4_SIZE;
> > > > > +               type = BCH4_ECC;
> > > > > +       }
> > > > > +
> > > > > +       for (i = 0; i < eccsteps ; i++) {
> > > > > +               eccflag = 0;    /* initialize eccflag */
> > > > > +
> > > > > +               for (j = 0; (j < eccsize); j++) {
> > > > > +                       if (read_ecc[j] != 0xFF) {
> > > > > +                               eccflag = 1;    /* data area is flashed */
> > > > 
> > > > Just a reminder: this way of checking if a page has been programmed is not robust to bitflips,
> > > > so you may get into trouble with UBIFS on a fairly recent device.
> > 
> > Sorry I missed this point.
> > 
> > Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) is 0xFF. If all data
> > in spare area is 0xFF, conclude that the page is erased & no need of error correction. In case
> > of bit flip present in spare area, page will be reported as uncorrectable.
> > But I am not understand understand " trouble with UBIFS on a fairly recent device".
> > Can you little elaborativ
> 
> There are at least 2 potential problems when reading an erased page with bitflips:
> 
> 1. bitflip in data area and no bitflip in spare area (all 0xff)
> Your code will not perform any ECC correction.
> UBIFS does not like finding bitflips in empty pages, see for instance
> http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.

In case of error correction using ELM, syndrome vector calculated after reading
Data area & OOB area. So handling of erased page requires a software workaround.
I am planning something as follows.

I will first check calculated ecc, which would be zero for non error pages.
Then I would check 0xFF in OOB area (for erased page) by checking number of
bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
set entire page as 0xFF if number of bit zeros is less than max bit flips
(8 or 4) by counting the number of bit zero's in data area.

This logic is implemented in fsmc_nand.c

See commit
mtd: fsmc: Newly erased page read algorithm implemented

> 
> 2. bitflip in ECC bytes in spare area
> Your code will report an uncorrectable error upon reading; if this happens while reading a partially programmed UBI block,
> I guess you will lose data.

In case of uncorrectable errors due to bit flips in spare area,
I can go on checking number of bit zero's in data area + OOB area
are less than max bit flips (8 or 4), I can go on setting the entire
page as 0xFF.

Thanks
Avinash

> 
> BR,
> --
> Ivan
> 



From balado0318 at hotmail.com  Tue Oct  9 08:52:16 2012
From: balado0318 at hotmail.com (=?big5?B?rGanoSC4rQ==?=)
Date: Tue, 9 Oct 2012 12:52:16 +0000
Subject: [help] JFFS2 CRC failed in kernel 2.6.35
Message-ID: <BLU170-W1123245400E4A0187A42D83C08F0@phx.gbl>


Hi all,
 
Sorry for my poor English first.
 
I develop the NAND controller driver on kernel 2.6.35 and use 
it to format NAND flash(512B page, Hynix H27US08561A) as JFFS2.

Under overnight test by the storage test item of BurnInTest tool,
it appeared the following info:
 
JFFS2 notice: (119) jffs2_get_inode_nodes: Node header CRC failed 
              at 0x98aff0. {5e78,f3f2,0a0c080f,0b0d090e}
JFFS2 notice: (119) read_dnode: node CRC failed on dnode 
              at 0xfd35d0: read 0x11281639, calculated 0xc4fcdd58
JFFS2 notice: (119) read_dnode: node CRC failed on dnode
              at 0xfc0dd0: read 0x3631417d, calculated 0xe3e58a1c
JFFS2 notice: (119) read_dnode: node CRC failed on dnode 
              at 0xfbaff0: read 0x4252f682, calculated 0x7fe31a5e
JFFS2 notice: (119) read_dnode: node CRC failed on dnode 
              at 0xfb75d0: read 0x21b1d7a5, calculated 0x19b26d31
JFFS2 notice: (119) read_dnode: node CRC failed on dnode 
              at 0xfaf5d0: read 0x4375dd2d, calculated 0xd826e6f7
...
Data CRC failed on REF_PRISTINE data node 
            at 0x00fd2330: Read 0xf43e5add, calculated 0x99772ea8
Node CRC failed on REF_PRISTINE data node 
            at 0x00df05b0: Read 0xfb1aa12a, calculated 0xfa63c826
Data CRC failed on REF_PRISTINE data node 
            at 0x00ea1770: Read 0xed8ec085, calculated 0x593d2074
Data CRC failed on REF_PRISTINE data node 
            at 0x00ce8410: Read 0xf43e5add, calculated 0xb4a5853f
Data CRC failed on REF_PRISTINE data node 
            at 0x00e26330: Read 0x9db49f5b, calculated 0xe41b6991
Data CRC failed on REF_PRISTINE data node 
            at 0x00d4dc10: Read 0x7ce2b87f, calculated 0x712748df
Data CRC failed on REF_PRISTINE data node 
            at 0x00c20c70: Read 0x4c64f44a, calculated 0x45cccbc8
...
 
It's so weird~ 
Although the crc failed appears from jffs2 layer, the written file 
seems not to be corrupted.(The comparison is accuracy)
Is it the issue of driver-level? 
 
However, this driver has passed the test-modules under 
<linux source>/driver/mtd/tests and the storage 
test item(Sequential data pattern, random seeking,...etc) of 
BurnInTest tool for 69 hours when the flash is formatted as 
the UBIFS filesystem.
 
Refer to the posts before, the CRC failed usually occurred in the case 
of power off when the gc didn't complete. 
But, I don't cut the power when I run the BurnInTest tool for 
overnight test.
 
Any suggestion or question is welcome!!
I will appreciate for your reply.
 
 		 	   		   		 	   		  


From nsekhar at ti.com  Tue Oct  9 09:03:32 2012
From: nsekhar at ti.com (Sekhar Nori)
Date: Tue, 9 Oct 2012 18:33:32 +0530
Subject: [PATCH 1/1] mtd:nand:clk: preparation for switch to common clock
 framework
In-Reply-To: <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
References: <1347899860-24358-1-git-send-email-m-karicheri2@ti.com>
 <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
Message-ID: <507420A4.8090905@ti.com>

On 9/17/2012 10:07 PM, Murali Karicheri wrote:
> As a first step towards migrating davinci platforms to use common clock
> framework, replace all instances of clk_enable() with clk_prepare_enable()
> and clk_disable() with clk_disable_unprepare(). Until the platform is
> switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just
> adds a might_sleep() call and would work without any issues.
> 
> This will make it easy later to switch to common clk based implementation
> of clk driver from DaVinci specific driver.
> 
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> Reviewed-by: Mike Turquette <mturquette at linaro.org>

Tested this using NAND flash on DA850 EVM.

Acked-by: Sekhar Nori <nsekhar at ti.com>

Any chance this can make into the v3.7 kernel?

Thanks,
Sekhar


From nsekhar at ti.com  Tue Oct  9 09:09:19 2012
From: nsekhar at ti.com (Sekhar Nori)
Date: Tue, 9 Oct 2012 18:39:19 +0530
Subject: [PATCH 1/1] mtd:nand:clk: preparation for switch to common clock
 framework
In-Reply-To: <507420A4.8090905@ti.com>
References: <1347899860-24358-1-git-send-email-m-karicheri2@ti.com>
 <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
 <507420A4.8090905@ti.com>
Message-ID: <507421FF.2090309@ti.com>

On 10/9/2012 6:33 PM, Sekhar Nori wrote:
> On 9/17/2012 10:07 PM, Murali Karicheri wrote:
>> As a first step towards migrating davinci platforms to use common clock
>> framework, replace all instances of clk_enable() with clk_prepare_enable()
>> and clk_disable() with clk_disable_unprepare(). Until the platform is
>> switched to use the CONFIG_HAVE_CLK_PREPARE Kconfig variable, this just
>> adds a might_sleep() call and would work without any issues.
>>
>> This will make it easy later to switch to common clk based implementation
>> of clk driver from DaVinci specific driver.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> Reviewed-by: Mike Turquette <mturquette at linaro.org>
> 
> Tested this using NAND flash on DA850 EVM.
> 
> Acked-by: Sekhar Nori <nsekhar at ti.com>
> 
> Any chance this can make into the v3.7 kernel?

Just noticed another thread where Artem replied saying this patch is
pushed. Sorry about the noise.

Thanks,
Sekhar


From dedekind1 at gmail.com  Tue Oct  9 09:30:37 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 09 Oct 2012 16:30:37 +0300
Subject: UBIFS Recovery Issue: 'grab_empty_leb: could not find an empty
 LEB'
In-Reply-To: <CAP+RiCDHZYMZPFYmE6YfkLoA1gH=z8cTSRZ+9iQqQ=ei1xXFYg@mail.gmail.com>
References: <CAP+RiCC1afVbKAZESMcZGd1G3+7aKuLTQGggOEFGZxQM6o+QQA@mail.gmail.com>
 <1346413469.9709.44.camel@sauron.fi.intel.com>
 <CAP+RiCBRopbShAGf_fWCvK2R=uPPR1j4Pz12JfJxdEMUjwofNw@mail.gmail.com>
 <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
 <CAP+RiCDHZYMZPFYmE6YfkLoA1gH=z8cTSRZ+9iQqQ=ei1xXFYg@mail.gmail.com>
Message-ID: <1349789437.1992.116.camel@sauron.fi.intel.com>

On Sun, 2012-09-23 at 10:48 -0500, Brent Taylor wrote:
> Ping,  I just didn't want to get lost in the e-mail shuffle.

OK, Brent, here is the fix. I am sorry for so long delay. I simply
do not have enough time for my UBIFS hobby. And thank you for sending
me the image. The fix is attached.

From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Date: Tue, 9 Oct 2012 16:20:15 +0300
Subject: [PATCH] UBIFS: fix mounting problems after power cuts

This is a bugfix for a problem with the following symptoms:

1. A power cut happens
2. After reboot, we try to mount UBIFS
3. Mount fails with "No space left on device" error message

UBIFS complains like this:

UBIFS error (pid 28225): grab_empty_leb: could not find an empty LEB

The root cause of this problem is that when we mount, not all LEBs are
categorized. Only those which were read are. However, the
'ubifs_find_free_leb_for_idx()' function assumes that all LEBs were
categorized and 'c->freeable_cnt' is valid, which is a false assumption.

This patch fixes the problem by teaching 'ubifs_find_free_leb_for_idx()'
to always fall back to LPT scanning if no freeable LEBs were found.

This problem was reported by several people in the past, but Brent Taylor
was able to reproduce it and send me a flash image which cannot be mounted,
which made it easy to hunt the bug. Kudos to Brent.

Reported-by: Brent Taylor <motobud at gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: stable at vger.kernel.org
---
 fs/ubifs/find.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 28ec13a..959386b 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -682,12 +682,10 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
 		lprops = ubifs_fast_find_freeable(c);
 		if (!lprops) {
 			ubifs_assert(c->freeable_cnt == 0);
-			if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
-				lprops = scan_for_leb_for_idx(c);
-				if (IS_ERR(lprops)) {
-					err = PTR_ERR(lprops);
-					goto out;
-				}
+			lprops = scan_for_leb_for_idx(c);
+			if (IS_ERR(lprops)) {
+				err = PTR_ERR(lprops);
+				goto out;
 			}
 		}
 	}
-- 
1.7.7.6



-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-UBIFS-fix-mounting-problems-after-power-cuts.patch
Type: text/x-patch
Size: 2024 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121009/cf077fd9/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121009/cf077fd9/attachment.sig>

From dhowells at redhat.com  Tue Oct  9 09:30:31 2012
From: dhowells at redhat.com (David Howells)
Date: Tue, 09 Oct 2012 14:30:31 +0100
Subject: [GIT PULL] Disintegrate UAPI for mtd
Message-ID: <30720.1349789431@warthog.procyon.org.uk>

Can you merge the following branch into the mtd tree please.

This is to complete part of the Userspace API (UAPI) disintegration for which
the preparatory patches were pulled recently.  After these patches, userspace
headers will be segregated into:

	include/uapi/linux/.../foo.h

for the userspace interface stuff, and:

	include/linux/.../foo.h

for the strictly kernel internal stuff.

---
The following changes since commit 9e2d8656f5e8aa214e66b462680cf86b210b74a8:

  Merge branch 'akpm' (Andrew's patch-bomb) (2012-10-09 16:23:15 +0900)

are available in the git repository at:


  git://git.infradead.org/users/dhowells/linux-headers.git tags/disintegrate-mtd-20121009

for you to fetch changes up to 4a8e43feeac7996b8de2d5b2823e316917493df4:

  UAPI: (Scripted) Disintegrate include/mtd (2012-10-09 09:49:09 +0100)

----------------------------------------------------------------
UAPI Disintegration 2012-10-09

----------------------------------------------------------------
David Howells (1):
      UAPI: (Scripted) Disintegrate include/mtd

 include/mtd/Kbuild                  | 5 -----
 include/uapi/mtd/Kbuild             | 5 +++++
 include/{ => uapi}/mtd/inftl-user.h | 0
 include/{ => uapi}/mtd/mtd-abi.h    | 0
 include/{ => uapi}/mtd/mtd-user.h   | 0
 include/{ => uapi}/mtd/nftl-user.h  | 0
 include/{ => uapi}/mtd/ubi-user.h   | 0
 7 files changed, 5 insertions(+), 5 deletions(-)
 rename include/{ => uapi}/mtd/inftl-user.h (100%)
 rename include/{ => uapi}/mtd/mtd-abi.h (100%)
 rename include/{ => uapi}/mtd/mtd-user.h (100%)
 rename include/{ => uapi}/mtd/nftl-user.h (100%)
 rename include/{ => uapi}/mtd/ubi-user.h (100%)
.


From david.woodhouse at intel.com  Tue Oct  9 11:02:46 2012
From: david.woodhouse at intel.com (Woodhouse, David)
Date: Tue, 9 Oct 2012 15:02:46 +0000
Subject: MTD pull for 3.7
Message-ID: <1349794964.6072.24.camel@shinybook.infradead.org>

Linus, please pull from
	git://git.infradead.org/mtd-2.6 for-linus-20121009

This is bigger than normal since I missed the large merge window, but
it's the normal set of additional hardware support and cleanups:

 - Disable broken mtdchar mmap() on MMU systems
 - Additional ECC tests for NAND flash, and some test cleanups
 - New NAND and SPI chip support
 - Fixes/cleanup for SH FLCTL NAND controller driver
 - Improved hardware support for GPMI NAND controller
 - Conversions to device-tree support for various drivers
 - Removal of obsolete drivers (sbc8xxx, bcmring, etc.)
 - New LPC32xx drivers for MLC and SLC NAND
 - Further cleanup of NAND OOB/ECC handling
 - UAPI cleanup merge from David Howells (just moving files, since MTD
   headers were sorted out long ago to separate user-visible from kernel
   bits)

Akinobu Mita (11):
      mtd: mtd_nandecctest: remove unnecessary srandom32() call
      mtd: mtd_nandecctest: make module_init() return an error code if test fails
      mtd: mtd_nandecctest: remove unnecessary include
      mtd: mtd_nandecctest: make module_init() return appropriate errno
      mtd: mtd_nandecctest: improve message output
      mtd: mtd_nandecctest: ensure alignment requirement for bitops
      mtd: mtd_nandecctest: support injecting bit error for ecc code
      mtd: mtd_nandecctest: rewrite the test routine
      mtd: mtd_nandecctest: add no corruption test
      mtd: mtd_nandecctest: add single bit error correction test
      mtd: mtd_nandecctest: add double bit error detection tests

Alexander Shiyan (2):
      mtd: autcpu12-nvram: Fix compile breakage
      mtd: autcpu12-nvram: Convert driver to platform_device

Alexandre Pereira da Silva (3):
      mtd: m25p80: Add support for m25pe20
      mtd: m25p80: Add support for n25q064
      mtd: lpc32xx_slc: Make wp gpio optional

Andreas Bie?mann (2):
      mtd: omap2: fix omap_nand_remove segfault
      mtd: omap2: fix module loading

Andy Shevchenko (1):
      mtd: use %*ph[CN] to dump small buffers

Artem Bityutskiy (6):
      mtd: tests: use random32 instead of home-brewed generator
      mtd: spear_smi: fix compilation warning
      JFFS2: fix unmount regression
      mtd: cmdlinepart: remove unneeded initialization
      mtd: cmdlinepart: revise error handling
      mtd: cmdlinepart: minor cleanups

Bastian Hecht (10):
      mtd: sh_flctl: Add missing iounmap()
      mtd: sh_flctl: Add support for error IRQ
      mtd: sh_flctl: Use different OOB layout
      mtd: sh_flctl: Fix hardware ECC behaviour
      mtd: sh_flctl: Simplify the hardware ecc page read/write
      mtd: sh_flctl: Group sector accesses into a single transfer
      mtd: sh_flctl: Restructure the hardware ECC handling
      mtd: sh_flctl: Use user oob data in hardware ECC mode
      mtd: sh_flctl: Use memcpy() instead of using a loop
      mtd: sh_flctl: Only copy OOB data if it is required

Brian Norris (26):
      mtd: move mtd_read_oob() definition out of mtd.h
      mtd: mtdoops: refactor loop
      mtd: cafe_nand: spelling mistake
      mtd: nand: gpmi: need to use {read,write}_oob_raw
      mtd: nand: add Eon Silicon Solutions manufacturer ID
      mtd: nand: remove NAND_BBT_SEARCH option
      mtd: nand: kill NAND_NO_READRDY
      mtd: nand: change "AMD" manuf. ID to "AMD/Spansion"
      mtd: nand: rename "no_bbt" descriptors to "no_oob"
      mtd: nand_bbt: refactor check_pattern_no_oob()
      mtd: check for max_bitflips in mtd_read_oob()
      mtd: nand: remove unused 'int' return codes
      mtd: nand_bbt: use string library
      mtd: nand: use ECC, if present, when scanning OOB
      mtd: nand: rename '_raw' BBT scan functions
      mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver
      JFFS2: don't fail on bitflips in OOB
      mtd: nand: remove unnecessary variable
      mtd: nand: remove redundant ID read
      mtd: nand: split BB marker options decoding into its own function
      mtd: nand: split extended ID decoding into its own function
      mtd: nand: split simple ID decode into its own function
      mtd: nand: add generic READ ID length calculation functions
      mtd: nand: increase max OOB size to 640
      mtd: nand: decode Hynix MLC, 6-byte ID length
      mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID

Christian Daudt (1):
      mtd: remove bcmring NAND driver

Chunhe Lan (1):
      mtd: m25p80: Add support for Atmel at45db081d

David Howells (1):
      UAPI: (Scripted) Disintegrate include/mtd

David Woodhouse (4):
      Merge tag 'v3.6-rc2' of git://git.kernel.org/.../torvalds/linux
      Merge commit '371a00448f95adaa612cf1a0b31a11e7093bc706' of 'git://git.kernel.org/.../davem/net-next.git'
      Merge tag 'disintegrate-mtd-20121009' of git://git.infradead.org/users/dhowells/linux-headers
      mtd: Disable mtdchar mmap on MMU systems

Fabio Estevam (9):
      nand: mxc_nand: Use clk_prepare_enable/clk_disable_unprepare
      mtd: mxc_nand: Select the driver via ARCH_MXC
      mtd: nand: Include IMX6 in the list of supported SoCs
      mtd: nand: nand_bbt: export nand_update_bbt
      mtd: allow MTD_NAND_GPMI_NAND to be built as module
      mtd: gpmi-nand: Improve logging style
      mtd: gpmi-nand: Convert to module_platform_driver()
      mtd: mxc_nand: Convert to module_platform_driver()
      mtd: mxc_nand: Adapt the clock name to the new clock framework

Gabor Juhos (1):
      mtd: m25p80: add support for the EON EN25Q64 chip

Gerlando Falauto (1):
      mtd: cfi_cmdset_0002: Micron M29EW bugfixes as per TN-13-07

Greg Ungerer (2):
      mtd: fix wrong usage of ioremap_nocache() in uclinux.c map driver
      mtd: allow uclinux map driver to be used on any ColdFire CPU platform

Heiko Schocher (1):
      mtd: nand: davinci: add OF support for davinci nand controller

Huang Shijie (18):
      mtd: use MTD_OPS_PLACE_OOB macro consistently
      mtd: fix typo in comment
      mtd: gpmi: add on-flash BBT support for gpmi nand
      mtd: gpmi: update the bitflip_threshold
      mtd: gpmi: change the code for clocks
      mtd: gpmi: fix the compiler warnings
      mtd: kill MTD_NAND_VERIFY_WRITE
      defconfigs: remove CONFIG_MTD_NAND_VERIFY_WRITE
      mtd: mtdpart: break it as soon as we parse out the partitions
      mtd: add helpers to set/get features for ONFI nand
      mtd: add helpers to get the supportted ONFI timing mode
      mtd: gpmi: add a new field for HW_GPMI_TIMING1
      mtd: gpmi: do not get the clock frequency in gpmi_begin()
      mtd: gpmi: add a new field for HW_GPMI_CTRL1
      mtd: gpmi: simplify the DLL setting code
      mtd: gpmi: do not set the default values for the extra clocks
      mtd: gpmi: add EDO feature for imx6q
      mtd: gpmi: initialize the timing registers only one time

Iwo Mergler (1):
      mtd: tests: test for multi-bit error correction

Jan Luebbe (1):
      mtd: m25p80: add support for Micron N25Q128

Jean-Christophe PLAGNIOL-VILLARD (1):
      mtd: atmel nand: fix gpio missing request

Jeff Westfahl (1):
      mtd: nand: Added a device flag for subpage read support

John Crispin (2):
      mtd: check for valid pdata inside plat_nand
      mtd: lantiq: Add NAND support on Lantiq XWAY SoC.

Josh Wu (4):
      mtd: at91: extract hw ecc initialization to one function
      mtd: nand: teach write_page and write_page_raw return an error code
      mtd: at91: add dt parameters for Atmel PMECC
      mtd: at91: atmel_nand: add Programmable Multibit ECC controller support

Julia Lawall (4):
      mtd: spear_smi: failure test for null rather than negative integer
      mtd: spear_smi: use devm_ functions consistently
      mtd: maps: rbtx4939-flash: delete unneeded test
      mtd: autcpu12-nvram: drop frees of devm_ alloc'd data

Kim Phillips (1):
      mtd: fsl_ifc_nand: fix sparse warnings

Knut Wohlrab (1):
      mtd: m25p80: Add support for serial flash STM/Micron N25Q032

Marek Vasut (4):
      mtd: fix bogus inequation
      mtd: m25p80: add support for Spansion s25sl064p chip
      mtd: m25p80: Fix the Spansion chip detection
      mtd: m25p80: Disable 4KiB erase for s25sl032p, s25sl064p

Mike Dunn (3):
      mtd: docg4: fix oob reads
      mtd: nand: expand description of read_page method in comment header
      mtd: docg4: ecc.read_page() returns 0 on uncorrectable errors

Paul Bolle (1):
      mtd: chips: reorganize Kconfig help on swapping

Paul Gortmaker (1):
      mtd: delete SBC82xx/SBC8560 MTD mapping support

Peter Huewe (1):
      mtd: docg4: add missing HAS_IOMEM dependency

Peter Meerwald (1):
      mtd: omap2: fix some typos in comments

Rafa? Mi?ecki (2):
      mtd: bcm47part driver for BCM47XX chipsets
      mtd: basic (read only) driver for BCMA serial flash

Randy Dunlap (1):
      mtd: fix kernel-doc warning in include/linux/mtd/nand.h

Richard Genoud (3):
      mtd: nand: remove stale config options
      mtd: nand: use NAND_BBT_SCAN_MAXBLOCKS
      mtd: nandsim: bugfix: fail if overridesize is too big

Roland Stigge (10):
      mtd: add LPC32xx SLC NAND driver
      mtd: lpc32xx_slc: Use of_get_named_gpio()
      mtd: lpc32xx_slc: Make probe() return -EPROBE_DEFER if necessary
      mtd: add LPC32xx MLC NAND driver
      mtd: lpc32xx_slc: Adjust to pl08x DMA interface changes
      mtd: lpc32xx_mlc: Adjust to pl08x DMA interface changes
      mtd: lpc32xx_slc: Make driver independent of AMBA DMA engine driver
      mtd: lpc32xx_mlc: Make driver independent of AMBA DMA engine driver
      mtd: lpc32xx_slc: Cleanup after DT-only conversion
      mtd: lpc32xx_mlc: Cleanup after DT-only conversion

Sachin Kamat (9):
      mtd: s3c2410: Use module_platform_driver()
      mtd: s3c2410: Use pr_* instead of printk
      mtd: s3c2410: Use <linux/io.h> instead of <asm/io.h>
      mtd: s3c2410: Do not initialise statics to 0 or NULL
      mtd: s3c2410: Fix checkpatch warnings and errors related to whitespaces
      mtd: s3c2410: Fix line over 80 characters warning
      mtd: s3c2410: Use devm_* functions
      mtd: s3c2410: Fix compiler warnings
      mtd: nand/gpio: Convert to module_platform_driver()

Sascha Hauer (4):
      mtd: mxc_nand: Use managed resources
      mtd: mxc_nand: swap iomem resource order
      mtd: mxc_nand: add i.MX53 support
      ARM: i.MX5: Add nand oftree support

Scott Wood (1):
      mtd: elbc nand: use drvdata to only remove the relevant chip

Shiraz Hashim (1):
      mtd: spear_smi: clear status register on init

Shmulik Ladkani (4):
      mtd: nand: Use the mirror BBT descriptor when reading its version
      mtd: Better comment NAND_BBT_NO_OOB
      mtd: nand: rename create_bbt()'s 'len' variable to 'numpages'
      mtd: cmdlinepart: make the partitions rule more strict

Stefan Roese (2):
      mtd: physmap_of: Add "no-unaligned-direct-access" DT property
      mtd: cfi_cmdset_0001: Fix problem with unlocking timeout

Thomas Petazzoni (1):
      mtd: orion_nand: remove <mach/hardware.h> include

Vipin Kumar (1):
      mtd: spear_smi: handle return value of timeouts properly

Viresh Kumar (1):
      mtd: spear_smi: Move suspend/resume to follow dev_pm_ops

Vivien Didelot (1):
      mtd: m25p80: add support for Micron N25Q256A

Wolfram Sang (1):
      mtd: maps: pci: remove dead code

ing. Federico Fuga (1):
      mtd: add JEDEC ID for w25q32dw to chip table

m-karicheri2 at ti.com (1):
      mtd: nand: clk: preparation for switch to common clock framework

 Documentation/DocBook/mtdnand.tmpl                 |    2 -
 .../devicetree/bindings/arm/davinci/nand.txt       |   51 +
 .../devicetree/bindings/mtd/atmel-nand.txt         |   40 +-
 .../devicetree/bindings/mtd/gpmi-nand.txt          |    4 +
 .../devicetree/bindings/mtd/lpc32xx-mlc.txt        |   50 +
 .../devicetree/bindings/mtd/lpc32xx-slc.txt        |   52 +
 .../devicetree/bindings/mtd/mtd-physmap.txt        |    7 +
 arch/arm/boot/dts/imx51.dtsi                       |    7 +
 arch/arm/boot/dts/imx53.dtsi                       |    7 +
 arch/arm/configs/cam60_defconfig                   |    1 -
 arch/arm/configs/corgi_defconfig                   |    1 -
 arch/arm/configs/ep93xx_defconfig                  |    1 -
 arch/arm/configs/mini2440_defconfig                |    1 -
 arch/arm/configs/mv78xx0_defconfig                 |    1 -
 arch/arm/configs/nhk8815_defconfig                 |    1 -
 arch/arm/configs/orion5x_defconfig                 |    1 -
 arch/arm/configs/pxa3xx_defconfig                  |    1 -
 arch/arm/configs/spitz_defconfig                   |    1 -
 arch/arm/mach-clps711x/autcpu12.c                  |   19 +
 arch/arm/mach-imx/clk-imx51-imx53.c                |    2 +
 arch/arm/plat-mxc/devices/platform-mxc_nand.c      |   11 +-
 arch/blackfin/configs/BF561-ACVILON_defconfig      |    1 -
 arch/mips/configs/rb532_defconfig                  |    1 -
[dwmw2 at shinybook mtd-2.6]$ git diff linus.. --stat | cat
 Documentation/DocBook/mtdnand.tmpl                 |    2 -
 .../devicetree/bindings/arm/davinci/nand.txt       |   51 +
 .../devicetree/bindings/mtd/atmel-nand.txt         |   40 +-
 .../devicetree/bindings/mtd/gpmi-nand.txt          |    4 +
 .../devicetree/bindings/mtd/lpc32xx-mlc.txt        |   50 +
 .../devicetree/bindings/mtd/lpc32xx-slc.txt        |   52 +
 .../devicetree/bindings/mtd/mtd-physmap.txt        |    7 +
 arch/arm/boot/dts/imx51.dtsi                       |    7 +
 arch/arm/boot/dts/imx53.dtsi                       |    7 +
 arch/arm/configs/cam60_defconfig                   |    1 -
 arch/arm/configs/corgi_defconfig                   |    1 -
 arch/arm/configs/ep93xx_defconfig                  |    1 -
 arch/arm/configs/mini2440_defconfig                |    1 -
 arch/arm/configs/mv78xx0_defconfig                 |    1 -
 arch/arm/configs/nhk8815_defconfig                 |    1 -
 arch/arm/configs/orion5x_defconfig                 |    1 -
 arch/arm/configs/pxa3xx_defconfig                  |    1 -
 arch/arm/configs/spitz_defconfig                   |    1 -
 arch/arm/mach-clps711x/autcpu12.c                  |   19 +
 arch/arm/mach-imx/clk-imx51-imx53.c                |    2 +
 arch/arm/plat-mxc/devices/platform-mxc_nand.c      |   11 +-
 arch/blackfin/configs/BF561-ACVILON_defconfig      |    1 -
 arch/mips/configs/rb532_defconfig                  |    1 -
 arch/powerpc/configs/83xx/mpc8313_rdb_defconfig    |    1 -
 arch/powerpc/configs/83xx/mpc8315_rdb_defconfig    |    1 -
 arch/powerpc/configs/mpc83xx_defconfig             |    1 -
 drivers/mtd/Kconfig                                |    7 +
 drivers/mtd/Makefile                               |    1 +
 drivers/mtd/bcm47xxpart.c                          |  202 ++++
 drivers/mtd/chips/Kconfig                          |   11 +-
 drivers/mtd/chips/cfi_cmdset_0001.c                |   14 +-
 drivers/mtd/chips/cfi_cmdset_0002.c                |   67 ++
 drivers/mtd/cmdlinepart.c                          |  183 ++--
 drivers/mtd/devices/Kconfig                        |   10 +-
 drivers/mtd/devices/Makefile                       |    1 +
 drivers/mtd/devices/bcm47xxsflash.c                |  105 ++
 drivers/mtd/devices/doc2001plus.c                  |   14 +-
 drivers/mtd/devices/docg3.c                        |   12 +-
 drivers/mtd/devices/m25p80.c                       |   24 +-
 drivers/mtd/devices/spear_smi.c                    |  141 +--
 drivers/mtd/maps/Kconfig                           |   16 +-
 drivers/mtd/maps/Makefile                          |    1 -
 drivers/mtd/maps/autcpu12-nvram.c                  |  153 +--
 drivers/mtd/maps/pci.c                             |   23 -
 drivers/mtd/maps/physmap_of.c                      |   14 +
 drivers/mtd/maps/rbtx4939-flash.c                  |    2 -
 drivers/mtd/maps/uclinux.c                         |   15 +-
 drivers/mtd/maps/wr_sbc82xx_flash.c                |  174 ----
 drivers/mtd/mtdchar.c                              |    6 +-
 drivers/mtd/mtdcore.c                              |   21 +
 drivers/mtd/mtdoops.c                              |   14 +-
 drivers/mtd/mtdpart.c                              |    5 +-
 drivers/mtd/nand/Kconfig                           |   63 +-
 drivers/mtd/nand/Makefile                          |    4 +-
 drivers/mtd/nand/ams-delta.c                       |   13 -
 drivers/mtd/nand/atmel_nand.c                      |  987 +++++++++++++++++--
 drivers/mtd/nand/atmel_nand_ecc.h                  |  114 ++-
 drivers/mtd/nand/au1550nd.c                        |   46 -
 drivers/mtd/nand/bcm_umi_bch.c                     |  217 ----
 drivers/mtd/nand/bcm_umi_nand.c                    |  555 -----------
 drivers/mtd/nand/bf5xx_nand.c                      |    6 +-
 drivers/mtd/nand/cafe_nand.c                       |   20 +-
 drivers/mtd/nand/cmx270_nand.c                     |   13 -
 drivers/mtd/nand/davinci_nand.c                    |   78 +-
 drivers/mtd/nand/denali.c                          |   12 +-
 drivers/mtd/nand/diskonchip.c                      |   63 --
 drivers/mtd/nand/docg4.c                           |   43 +-
 drivers/mtd/nand/fsl_elbc_nand.c                   |   51 +-
 drivers/mtd/nand/fsl_ifc_nand.c                    |   52 +-
 drivers/mtd/nand/gpio.c                            |   54 +-
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c              |  322 +++++-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |  152 ++-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h             |   26 +-
 drivers/mtd/nand/gpmi-nand/gpmi-regs.h             |   12 +
 drivers/mtd/nand/lpc32xx_mlc.c                     |  924 +++++++++++++++++
 drivers/mtd/nand/lpc32xx_slc.c                     | 1039 ++++++++++++++++++++
 drivers/mtd/nand/mpc5121_nfc.c                     |   22 -
 drivers/mtd/nand/mxc_nand.c                        |  168 ++--
 drivers/mtd/nand/nand_base.c                       |  529 ++++++----
 drivers/mtd/nand/nand_bbt.c                        |  148 +--
 drivers/mtd/nand/nand_bcm_umi.c                    |  149 ---
 drivers/mtd/nand/nand_bcm_umi.h                    |  336 -------
 drivers/mtd/nand/nand_ids.c                        |    7 +-
 drivers/mtd/nand/nandsim.c                         |   17 +-
 drivers/mtd/nand/ndfc.c                            |   13 -
 drivers/mtd/nand/nuc900_nand.c                     |   17 -
 drivers/mtd/nand/omap2.c                           |   36 +-
 drivers/mtd/nand/orion_nand.c                      |    1 -
 drivers/mtd/nand/plat_nand.c                       |    5 +
 drivers/mtd/nand/pxa3xx_nand.c                     |   12 +-
 drivers/mtd/nand/r852.c                            |   22 -
 drivers/mtd/nand/s3c2410.c                         |  191 ++--
 drivers/mtd/nand/sh_flctl.c                        |  327 +++---
 drivers/mtd/nand/socrates_nand.c                   |   19 -
 drivers/mtd/nand/tmio_nand.c                       |   13 -
 drivers/mtd/nand/txx9ndfmc.c                       |   13 -
 drivers/mtd/nand/xway_nand.c                       |  201 ++++
 drivers/mtd/sm_ftl.c                               |    1 -
 drivers/mtd/tests/Makefile                         |    1 +
 drivers/mtd/tests/mtd_nandbiterrs.c                |  460 +++++++++
 drivers/mtd/tests/mtd_nandecctest.c                |  294 +++++-
 drivers/mtd/tests/mtd_speedtest.c                  |   16 +-
 drivers/mtd/tests/mtd_stresstest.c                 |   39 +-
 fs/jffs2/super.c                                   |    4 +
 fs/jffs2/wbuf.c                                    |    8 +-
 include/linux/bcma/bcma_driver_chipcommon.h        |    2 +
 include/linux/mtd/bbm.h                            |    7 +-
 include/linux/mtd/lpc32xx_mlc.h                    |   20 +
 include/linux/mtd/lpc32xx_slc.h                    |   20 +
 include/linux/mtd/mtd.h                            |    9 +-
 include/linux/mtd/nand.h                           |   72 +-
 include/linux/mtd/sh_flctl.h                       |   23 +-
 include/mtd/Kbuild                                 |    5 -
 include/mtd/inftl-user.h                           |   91 --
 include/mtd/mtd-abi.h                              |  278 ------
 include/mtd/mtd-user.h                             |   34 -
 include/mtd/nftl-user.h                            |   90 --
 include/mtd/ubi-user.h                             |  420 --------
 include/uapi/mtd/Kbuild                            |    5 +
 include/uapi/mtd/inftl-user.h                      |   91 ++
 include/uapi/mtd/mtd-abi.h                         |  278 ++++++
 include/uapi/mtd/mtd-user.h                        |   34 +
 include/uapi/mtd/nftl-user.h                       |   90 ++
 include/uapi/mtd/ubi-user.h                        |  420 ++++++++
 124 files changed, 7274 insertions(+), 4152 deletions(-)

-- 
                   Sent with MeeGo's ActiveSync support.

David Woodhouse                            Open Source Technology Centre
David.Woodhouse at intel.com                              Intel Corporation


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 4370 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121009/82ca505f/attachment-0001.bin>

From richard at nod.at  Tue Oct  9 10:18:47 2012
From: richard at nod.at (Richard Weinberger)
Date: Tue, 9 Oct 2012 16:18:47 +0200
Subject: [PATCH] ubi: use list_move_tail instead of list_del/list_add_tail
In-Reply-To: <CAPgLHd_AHHe7=H18K54LvbiS0M7_w1vTMOxwwxgVdRaiXNN-OA@mail.gmail.com>
References: <CAPgLHd_AHHe7=H18K54LvbiS0M7_w1vTMOxwwxgVdRaiXNN-OA@mail.gmail.com>
Message-ID: <20121009161847.79031abb@spider.haslach.nod.at>

Am Tue, 9 Oct 2012 14:14:21 +0800
schrieb Wei Yongjun <weiyj.lk at gmail.com>:

> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> 
> Using list_move_tail() instead of list_del() + list_add_tail().
> 
> dpatch engine is used to auto generate this patch.
> (https://github.com/weiyj/dpatch)
> 
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Acked-by: Richard Weinberger <richard at nod.at>

Thanks,
//richard


From richard at nod.at  Tue Oct  9 12:23:01 2012
From: richard at nod.at (Richard Weinberger)
Date: Tue,  9 Oct 2012 18:23:01 +0200
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <CAN8TOE_BC6JGbrMcTYf5oMWnaAAx=LSh3V08vMnaGQVhkT-Yrw@mail.gmail.com>
References: <CAN8TOE_BC6JGbrMcTYf5oMWnaAAx=LSh3V08vMnaGQVhkT-Yrw@mail.gmail.com>
Message-ID: <1349799781-5132-1-git-send-email-richard@nod.at>

Add documentation on fastmap to mtd-www.

Signed-off-by: Richard Weinberger <richard at nod.at>
---
 doc/ubi.xml | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 115 insertions(+), 3 deletions(-)

diff --git a/doc/ubi.xml b/doc/ubi.xml
index 6bea323..13b8174 100644
--- a/doc/ubi.xml
+++ b/doc/ubi.xml
@@ -46,6 +46,7 @@
 		</li>
 		</ol>
 	</li>
+	<li><a href="ubi.html#L_fastmap">Fastmap</a></li>
 	<li><a href="ubi.html#L_ubidoc">More documentation</a></li>
 </ol>
 
@@ -758,8 +759,12 @@ for detailed information.</p>
 <p>Unfortunately, UBI scales linearly in terms of flash size. UBI
 initialization time linearly depends on the number of physical eraseblocks on
 the flash. This means that the larger is the flash, the more time it takes for
-UBI to initialize (i.e., to attach the MTD device). The initialization time
-depends on the flash I/O speed and (slightly) on the CPU speed, because:</p>
+UBI to initialize (i.e., to attach the MTD device).
+Note: Starting with Linux v3.7 UBI offers an optional and experimental feature,
+called "fastmap", which allows attaching in nearly constant time,
+see <a href="ubi.html#L_fastmap">Fastmap</a>.
+The initialization time depends on the flash I/O speed and (slightly) on the
+CPU speed, because:</p>
 
 <ul>
 	<li>UBI scans the MTD device when attaching - it reads the erase EC and
@@ -1170,7 +1175,114 @@ means that all data has been written to the flash media), otherwise it selects
 the PEB with lower sequence number(<i>P<sub>1</sub></i>). Of course, UBI has to
 read the LEB contents in order to check the <code>CRC-32</code> checksum.</p>
 
-
+<h2><a name="L_fastmap">Fastmap</a></h2>
+<p>
+Fastmap is an experimental and optional UBI feature, which can be enabled
+by setting CONFIG_MTD_UBI_FASTMAP to 'y'.
+Once enabled UBI evaluates the module parameter
+"fm_autoconvert". If it is set to 1 (default is 0) UBI automatically enables
+fastmap for any attached image. This means UBI creates a new internal
+volume with the fastmap data such that next time the fast attach mode can be
+used.
+In the default configuration UBI will use the information stored in this
+fastmap volume to accelerate the attach procedure.
+If you want to test fastmap, set fm_autoconvert to 1 and attach a volume.
+</p>
+
+The following settings are possible:
+<table>
+<thead>
+<th>CONFIG_MTD_UBI_FASTMAP</th>
+<th>fm_autoconvert</th>
+<th>Result</th>
+</thead>
+
+<tdata>
+<tr>
+<td>n</td>
+<td>0</td>
+<td>fastmap is completely disabled</td>
+</tr>
+
+<tr>
+<td>y</td>
+<td>0</td>
+<td>UBI will attach by fastmap if one exists on an image,
+but no fastmap will be installed on images without a fastmap</td>
+</tr>
+
+<tr>
+<td>y</td>
+<td>1</td>
+<td>UBI will attach by fastmap if one exists on an image, a fastmap
+is automatically installed on all attached images</td>
+</tr>
+</tdata>
+</table>
+
+<h4><a name="L_fastmap_compat">Backwards compatibility</a></h4>
+<p>The fastmap on-disk data structure makes use of delete compatible volumes,
+therefore fastmap enabled images are fully backwards compatible with UBI
+implementations which do not support fastmap. The kernel will remove the fastmap
+volumes and continue with scanning.
+This includes not only v3.6- but also v3.7+ with this option disabled.
+</p>
+
+<h4><a name="L_fastmap_tech">Technical design</a></h4>
+
+<p>A on-disk fastmap contains all information needed to attach the whole image,
+namely all erase counter values, a list of all PEBs and their state, a list of
+all volumes and their current EBA, ...
+To avoid too many writes of the fastmap, it also contains a list of PEBs which
+may have changed and need a full scan while attaching.
+This list is called "fastmap pool" and has a fixed sized, 5% of the total
+amount of PEBs. Using this technique UBI needs to write the fastmap only if the
+pool contains no free PEBs. Otherwise it would have to write the fastmap each
+time the EBA of a volume has changed.</p>
+
+<p>A fastmap consists of a super block (also known as anchor PEB) and payload
+data which can live on any PEB.
+The anchor PEB has to be located within the first 64 PEBs on the MTD device.
+It contains pointers to the remaining PEBs which carry the actual fastmap
+data. On modern NAND chips the whole fastmap fits into a single PEB.
+Hence, the anchor PEB points to itself.
+After loading the fastmap data, UBI attach information structure is created
+from it.
+
+The attach process works as follows:
+<ol>
+	<li>UBI tries to find the fastmap anchor PEB,
+	if no anchor PEB was found UBI performs  traditional full scan</li>
+	<li>It follows the pointers stored in the anchor PEB and reads
+	the fastmap payload data</li>
+	<li>Then it performs a traditional scan only on PEBs in the pool
+	instead of all PEBs</li>
+</ol>
+If UBI detects that the used fastmap is invalid or corrupted it automatically
+falls back to scanning mode and performs a full scan.
+Using a CRC32 checksum and consistency checks of the internal UBI structures
+UBI is able to detect whether a fastmap is invalid or not.
+</p>
+
+<p>
+A fastmap is written to the devices each time the fastmap pool becomes full
+(no free PEBs are available), the volume layout changes or the image is
+detached. One may wonder why writing at detach time is needed.
+If UBI would not write a new fastmap at detach time all erase counter
+modifications since the last fastmap write are lost.
+</p>
+
+<h4><a name="L_fastmap_overhead">Overhead</a></h4>
+<p>If fastmap enabled UBI will reserve enough PEBs to carry two complete
+fastmaps. In practice on modern NAND chips two PEBs are reserved for fastmap.
+</p>
+<p>
+There is also some runtime overhead, to guarantee that the new fastmap is valid
+and conistent UBI has to take care that all IO which would cause EBA changes
+are blocked while attaching. Depending on flash chips this can take up to one
+second. Therefore, fastmap makes only sense on fast and large flash devices
+where a full scan takes too long. E.g. On 4GiB NAND chips a full scan takes
+several seconds whereas a fast attach needs less than one second.</p>
 
 <h2><a name="L_ubidoc">More documentation</a></h2>
 
-- 
1.7.11.5



From viresh.kumar at linaro.org  Tue Oct  9 13:14:40 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 22:44:40 +0530
Subject: [PATCH 01/11] fsmc/nand:FIX: Change the type for regs to void
 __iomem *
In-Reply-To: <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
Message-ID: <CAOh2x=neFZcdK16_3wHRPHURWDVgfyv2UvX44bSb0hLmvMjHqA@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  drivers/mtd/nand/fsmc_nand.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> index 38d2624..e96d7d1 100644
> --- a/drivers/mtd/nand/fsmc_nand.c
> +++ b/drivers/mtd/nand/fsmc_nand.c
> @@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
>         struct nand_chip *this = mtd->priv;
>         struct fsmc_nand_data *host = container_of(mtd,
>                                         struct fsmc_nand_data, mtd);
> -       void *__iomem *regs = host->regs_va;
> +       void __iomem *regs = host->regs_va;

Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>


From viresh.kumar at linaro.org  Tue Oct  9 13:15:33 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 22:45:33 +0530
Subject: [PATCH 02/11] fsmc/nand: Rearrange the fsmc_nand_data structure
 and update comments
In-Reply-To: <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>
Message-ID: <CAOh2x=m0U4LdDcPxcWRQF-Z7dS1qskgXXKpPnc3m2JP0PSvBcQ@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
>  drivers/mtd/nand/fsmc_nand.c | 51 ++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 21 deletions(-)

Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>


From viresh.kumar at linaro.org  Tue Oct  9 13:20:47 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 22:50:47 +0530
Subject: [PATCH 04/11] fsmc/nand: Accept nand timing parameters via DT
In-Reply-To: <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>
Message-ID: <CAOh2x==1UA-9yDX=S6zGtJ-NwGkQuxStE5WTh6qpWAK7Dw68nw@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt

> +- nand-timings-enabled: Indicates if the timing parameters are passed
> +  via DT
> +- nand-timings,tclr:
> +- nand-timings,tar:
> +- nand-timings,thiz:
> +- nand-timings,thold:
> +- nand-timings,twait:
> +- nand-timings,tset: All these timing parameters come from the actual
> +  nand device specification. Each of this represents a number of time
> +  period of hclk ie a number 4 in thold with hclk = 166MHz means that
> +  thold = (1000 / 166) * 4 ns = 24.09ns

Are they specific to fsmc controller or nand memory type? If to fsmc then
please add my

Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>

else
I would suggest to add these to mtd bindings instead, so that same fields
can be used by multiple drivers....

Similar approach is used for mmc controllers too.


From dedekind1 at gmail.com  Tue Oct  9 13:25:35 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 09 Oct 2012 20:25:35 +0300
Subject: UBIFS Recovery Issue: 'grab_empty_leb: could not find an empty
 LEB'
In-Reply-To: <CAP+RiCBCe-KUu+dd5NTizMoJU4gd+r5o=VmBa4CauP704uSmbQ@mail.gmail.com>
References: <CAP+RiCC1afVbKAZESMcZGd1G3+7aKuLTQGggOEFGZxQM6o+QQA@mail.gmail.com>
 <1346413469.9709.44.camel@sauron.fi.intel.com>
 <CAP+RiCBRopbShAGf_fWCvK2R=uPPR1j4Pz12JfJxdEMUjwofNw@mail.gmail.com>
 <CAP+RiCAzOKvV00F8zppPxrL1CHKqR6eU2g08F+s_wm2R6jJ7Cg@mail.gmail.com>
 <CAP+RiCDHZYMZPFYmE6YfkLoA1gH=z8cTSRZ+9iQqQ=ei1xXFYg@mail.gmail.com>
 <1349789437.1992.116.camel@sauron.fi.intel.com>
 <CAP+RiCBCe-KUu+dd5NTizMoJU4gd+r5o=VmBa4CauP704uSmbQ@mail.gmail.com>
Message-ID: <1349803535.1827.0.camel@kyv>

On Tue, 2012-10-09 at 12:11 -0500, Brent Taylor wrote:
> Artem,
>    Thanks so much for your time to track down this bug.  I've tested
> your patch and it does mount the filesystem that it would fail on
> before.  I'm glad I could help.  I want to thank you for all your work
> in the UBI and UBIFS subsystems and all your contributions to the
> Linux kernel.

Thanks!

I will send a better version of the patch later, and give it some more
test. I will keep you in CC.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121009/d8b4d9ba/attachment.sig>

From viresh.kumar at linaro.org  Tue Oct  9 13:34:48 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 23:04:48 +0530
Subject: [PATCH 05/11] fsmc: Implement ready/busy through gpio pin
In-Reply-To: <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <e455d98df0fba37e8b7ecd7e72d510a05f23d2ba.1349778821.git.vipin.kumar@st.com>
Message-ID: <CAOh2x=kAgD+0c4mgZsx+Gc+mxAEO9QPEj8_LdDxMaoqFi5g6_g@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
> +- st,ready-busy: Should contain either of "rb-gpio" or "rb-wait". When
> +  this property is not defined, the default is to use rb-wait.
> +- st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
> +  pin number is defined in this property

Why st,*** maybe fsmc,***?

Would be better if you update the example too in this file.

> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c

> + * @rb_pin:            Ready/Busy data

> +       struct fsmc_rbpin       *rbpin;

comment variable mismatch :(

> -static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
> -                          uint32_t busw, struct fsmc_nand_timings *timings)
> +static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, uint32_t busw,
> +                          struct fsmc_nand_timings *timings,
> +                          struct fsmc_rbpin *rbpin)

Can function prototype come in two lines instead of three?

> @@ -1049,6 +1075,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)

> +       if (host->rbpin->use_pin == FSMC_RB_GPIO) {
> +               ret = gpio_request(host->rbpin->gpio_pin, "fsmc-rb");
> +               if (ret < 0) {
> +                       dev_err(&pdev->dev, "gpio request fail: %d\n",
> +                                       host->rbpin->gpio_pin);
> +                       goto err_gpio_req;
> +               }
> +       }

Don't you want to set its direction to input?


From viresh.kumar at linaro.org  Tue Oct  9 13:41:25 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 23:11:25 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
Message-ID: <CAOh2x=mwWPyPDQG1NZ-XKXCjxFuPdypUNcn8b-prmrv3f2QxsQ@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
> @@ -675,7 +676,8 @@ static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len)
>         struct fsmc_nand_data *host;
>
>         host = container_of(mtd, struct fsmc_nand_data, mtd);
> -       dma_xfer(host, buf, len, DMA_FROM_DEVICE);
> +       dma_xfer(host, host->dma_buf, len, DMA_FROM_DEVICE);
> +       memcpy(buf, (const void *)host->dma_buf, len);

Ahh.. Too much overhead. Can't you do something better here?
- DMA can be done to user buffers too, Pratyush has done some work in
past on this.
- There must be some other way of sharing kernel buffer to user space.

--
viresh


From viresh.kumar at linaro.org  Tue Oct  9 13:42:45 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Tue, 9 Oct 2012 23:12:45 +0530
Subject: [PATCH 08/11] fsmc/nand: Use relaxed variants of io accessors
In-Reply-To: <88484dbae96f7db42ce615552a4c758844a5e6cc.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <88484dbae96f7db42ce615552a4c758844a5e6cc.1349778821.git.vipin.kumar@st.com>
Message-ID: <CAOh2x=nbiYCvwpiuVikcKB6=M2m0Z031XromT3jcFWOurupZZw@mail.gmail.com>

On Tue, Oct 9, 2012 at 4:14 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> Use relaxed variants of readl/writel accessors. readl/writel io accessors use
> explicit dsb instruction which causes stalls in the processor core resulting
> several cycles of delay for each access
>
> Use relaxed variants where ever possible. This also results in an improved
> read/write performance.

Good change.

Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>


From stigge at antcom.de  Tue Oct  9 14:30:29 2012
From: stigge at antcom.de (Roland Stigge)
Date: Tue, 09 Oct 2012 20:30:29 +0200
Subject: Pull request for mainline
In-Reply-To: <506EA8B4.6050309@antcom.de>
References: <506EA8B4.6050309@antcom.de>
Message-ID: <50746D45.9080308@antcom.de>

Hi David and Artem!

On 05/10/12 11:30, Roland Stigge wrote:
> just small reminder, just in case: Now would be a good opportunity for a
> pull request for mtd to mainline, if not already done. ;-)

I found two others asking on the mtd list for the same, but also without
a reply.

So I hope you are well and can prepare a pull request in time for this
merge window (closing at the end of this week).

Please tell me if I can do anything to help here. I would volunteer.

Thanks in advance,

Roland


From thomas.betker at freenet.de  Tue Oct  9 15:11:35 2012
From: thomas.betker at freenet.de (Thomas Betker)
Date: Tue, 09 Oct 2012 21:11:35 +0200
Subject: [PATCH RESEND] jffs2: Fix lock acquisition order bug in
 jffs2_write_begin
In-Reply-To: <507321E6.1050609@freenet.de>
References: <507321E6.1050609@freenet.de>
Message-ID: <507476E7.8030705@freenet.de>

jffs2_write_begin() first acquires the page lock, then f->sem. This causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first acquires f->sem, then the page lock:

jffs2_garbage_collect_live
     mutex_lock(&f->sem)                         (A)
     jffs2_garbage_collect_dnode
         jffs2_gc_fetch_page
             read_cache_page_async
                 do_read_cache_page
                     lock_page(page)             (B)

jffs2_write_begin
     grab_cache_page_write_begin
         find_lock_page
             lock_page(page)                     (B)
     mutex_lock(&f->sem)                         (A)

We fix this by restructuring jffs2_write_begin() to take f->sem before the page lock. However, we make sure that f->sem is not held when calling jffs2_reserve_space(), as this is not permitted by the locking rules.

The deadlock above was observed multiple times on an SoC with a dual ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred when using scp to copy files from a host system to the ARM target system. The fix was heavily tested on the same target system.

If the patch is accepted, please get it also pushed to 3.4; it applies cleanly both to linux-mtd.git and the current linux-3.4 tree.

Cc: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
Signed-off-by: Thomas Betker <thomas.betker at rohde-schwarz.com>

diff -Naur linux-3.4.11-orig/fs/jffs2/file.c linux-3.4.11/fs/jffs2/file.c
--- linux-3.4.11-orig/fs/jffs2/file.c	2012-09-14 22:18:55.000000000 +0000
+++ linux-3.4.11/fs/jffs2/file.c	2012-10-05 09:01:10.000000000 +0000
@@ -138,33 +138,39 @@
  	struct page *pg;
  	struct inode *inode = mapping->host;
  	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_raw_inode ri;
+	uint32_t alloc_len = 0;
  	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
  	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
  	int ret = 0;
  
+	jffs2_dbg(1, "%s()\n", __func__);
+
+	if (pageofs > inode->i_size) {
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			return ret;
+	}
+
+	mutex_lock(&f->sem);
  	pg = grab_cache_page_write_begin(mapping, index, flags);
-	if (!pg)
+	if (!pg) {
+		if (alloc_len)
+			jffs2_complete_reservation(c);
+		mutex_unlock(&f->sem);
  		return -ENOMEM;
+	}
  	*pagep = pg;
  
-	jffs2_dbg(1, "%s()\n", __func__);
-
-	if (pageofs > inode->i_size) {
+	if (alloc_len) {
  		/* Make new hole frag from old EOF to new page */
-		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-		struct jffs2_raw_inode ri;
  		struct jffs2_full_dnode *fn;
-		uint32_t alloc_len;
  
  		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
  			  (unsigned int)inode->i_size, pageofs);
  
-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			goto out_page;
-
-		mutex_lock(&f->sem);
  		memset(&ri, 0, sizeof(ri));
  
  		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +197,6 @@
  		if (IS_ERR(fn)) {
  			ret = PTR_ERR(fn);
  			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
  			goto out_page;
  		}
  		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +211,10 @@
  			jffs2_mark_node_obsolete(c, fn->raw);
  			jffs2_free_full_dnode(fn);
  			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
  			goto out_page;
  		}
  		jffs2_complete_reservation(c);
  		inode->i_size = pageofs;
-		mutex_unlock(&f->sem);
  	}
  
  	/*
@@ -220,18 +223,18 @@
  	 * case of a short-copy.
  	 */
  	if (!PageUptodate(pg)) {
-		mutex_lock(&f->sem);
  		ret = jffs2_do_readpage_nolock(inode, pg);
-		mutex_unlock(&f->sem);
  		if (ret)
  			goto out_page;
  	}
+	mutex_unlock(&f->sem);
  	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
  	return ret;
  
  out_page:
  	unlock_page(pg);
  	page_cache_release(pg);
+	mutex_unlock(&f->sem);
  	return ret;
  }
  


From b32955 at freescale.com  Tue Oct  9 22:44:14 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 10 Oct 2012 10:44:14 +0800
Subject: [PATCH] nand: gpmi-nand: Fix clock registration
In-Reply-To: <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
References: <1348425062-17427-1-git-send-email-festevam@gmail.com>	<50723E5C.3020403@freescale.com>
 <CAOMZO5AE22Kscv8JAxiazzR5NSvEH+qs4QxBC6aEQqi3ZCpCpg@mail.gmail.com>
Message-ID: <5074E0FE.2050602@freescale.com>

? 2012?10?08? 11:22, Fabio Estevam ??:
> On Sun, Oct 7, 2012 at 11:45 PM, Huang Shijie<b32955 at freescale.com>  wrote:
>> ? 2012?09?24? 02:31, Fabio Estevam ??:
>>> From: Fabio Estevam<fabio.estevam at freescale.com>
>>>
>>> On a mx28 board the following error happens since commit 638064e56c
>>> (mtd: gpmi: change the code for clocks):
>>>
>>> gpmi-nand: probe of 8000c000.gpmi-nand failed with error -12
>>>
>>> Acquire the clock using "NULL" as it was done previously, so that the driver
>>> can register on mx23/mx28 as well.
>>>
>>> Signed-off-by: Fabio Estevam<fabio.estevam at freescale.com>
>>> ---
>>>   drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> index c46be6c..1f23cb4 100644
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> @@ -492,7 +492,7 @@ static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
>>>        int i;
>>>
>>>        /* The main clock is stored in the first. */
>>> -     r->clock[0] = clk_get(this->dev, "gpmi_io");
>>> +     r->clock[0] = clk_get(this->dev, NULL);
>> Please do not change this line.
>>
>> The gpmi_io is for mx6q.
>> If you replace it with `NULL`. The mx6q can not find the proper clock.
> What about this?
>
> index 42978f1b..7b1aded 100644
> --- a/drivers/clk/mxs/clk-imx28.c
> +++ b/drivers/clk/mxs/clk-imx28.c
> @@ -139,7 +139,7 @@ enum imx28_clk {
>          ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
>          emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
>          clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
> -       ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
> +       ssp1, ssp2, ssp3, gpmi_io, spdif, emi, saif0, saif1, lcdif, etm,
>          fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
>          clk_max
>   };
> @@ -208,7 +208,7 @@ int __init mx28_clocks_init(void)
>          clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
>          clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
>          clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
> -       clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
> +       clks[gpmi_io] = mxs_clk_gate("gpmi_io", "gpmi_div", GPMI, 31);
>          clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
>          clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
>          clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
>
> Can you please test it on mx28?
I tested it in the linux-next with mx28-evk board. It did not works.

thanks a lot.

Huang Shijie
> Regards,
>
> Fabio Estevam
>




From b32955 at freescale.com  Tue Oct  9 22:44:46 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 10 Oct 2012 10:44:46 +0800
Subject: [PATCH] ARM: dts: imx28: add the `clock-names` for gpmi-nand
Message-ID: <1349837086-21844-1-git-send-email-b32955@freescale.com>

The current DT node misses the `clocks-names` item for gpmi-nand.
So the gpmi-nand driver could not find the proper clock.

This patch fixes this issue.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 arch/arm/boot/dts/imx28.dtsi |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e16d631..55c57ea 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -85,6 +85,7 @@
 				interrupts = <88>, <41>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 50>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
-- 
1.7.0.4




From festevam at gmail.com  Wed Oct 10 00:54:56 2012
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 10 Oct 2012 01:54:56 -0300
Subject: [PATCH] ARM: dts: imx28: add the `clock-names` for gpmi-nand
In-Reply-To: <1349837086-21844-1-git-send-email-b32955@freescale.com>
References: <1349837086-21844-1-git-send-email-b32955@freescale.com>
Message-ID: <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>

Hi Huang,

On Tue, Oct 9, 2012 at 11:44 PM, Huang Shijie <b32955 at freescale.com> wrote:
> The current DT node misses the `clocks-names` item for gpmi-nand.
> So the gpmi-nand driver could not find the proper clock.
>
> This patch fixes this issue.
>
> Signed-off-by: Huang Shijie <b32955 at freescale.com>

Thanks for the fix.

Could you please also fix mx23 in the same patch?

Regards,

Fabio Estevam


From b32955 at freescale.com  Wed Oct 10 01:01:24 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 10 Oct 2012 13:01:24 +0800
Subject: [PATCH] ARM: dts: imx28: add the `clock-names` for gpmi-nand
In-Reply-To: <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>
References: <1349837086-21844-1-git-send-email-b32955@freescale.com>
 <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>
Message-ID: <50750124.5060208@freescale.com>

? 2012?10?10? 12:54, Fabio Estevam ??:
> Hi Huang,
>
> On Tue, Oct 9, 2012 at 11:44 PM, Huang Shijie<b32955 at freescale.com>  wrote:
>> The current DT node misses the `clocks-names` item for gpmi-nand.
>> So the gpmi-nand driver could not find the proper clock.
>>
>> This patch fixes this issue.
>>
>> Signed-off-by: Huang Shijie<b32955 at freescale.com>
> Thanks for the fix.
>
> Could you please also fix mx23 in the same patch?
I am just fixing it now. :)

Huang Shijie
> Regards,
>
> Fabio Estevam
>




From computersforpeace at gmail.com  Wed Oct 10 02:26:06 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue,  9 Oct 2012 23:26:06 -0700
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
Message-ID: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>

A combination of the following two commits caused a regression in 3.7-rc1
when identifying some Samsung NAND, so that some previously working NAND
were no longer detected properly:

    commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a
    mtd: nand: add generic READ ID length calculation functions

    commit e2d3a35ee427aaba99b6c68a56609ce276c51270
    mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID

Particularly, a regression was seen on Samsung K9F2G08U0B, with the
following full 8-byte READ ID string:

    ec da 10 95 44 00 ec da

The basic problem is that Samsung manufactures both SLC and MLC NAND
that use a non-standard decoding table for deriving information from
their IDs. I have heuristically determined that all the chips that use
the new table have ID strings which wrap around after the 6th byte.
Unfortunately, I overlooked the fact that some older Samsung SLC (which
use a different decoding table) have "5 byte ID strings" which also wrap
around after the 6th byte.

This patch re-introduces a distinction between these old and new Samsung
NAND by checking that the 6th byte is non-zero, allowing both old and
new Samsung NAND to be detected properly.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Tested-by: Brian Norris <computersforpeace at gmail.com>
Reported-by: Marek Vasut <marex at denx.de>
Tested-by: Marek Vasut <marex at denx.de>
---
David,

Marek and I just discovered this issue during the merge window. Please merge
this fix in the 3.7-rc cycle. Thanks.

 drivers/mtd/nand/nand_base.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec6841d..d5ece6e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2983,13 +2983,14 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 	/*
 	 * Field definitions are in the following datasheets:
 	 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
-	 * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
+	 * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
 	 * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
 	 *
-	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
-	 * to do.
+	 * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
+	 * ID to decide what to do.
 	 */
-	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+			id_data[5] != 0x00) {
 		/* Calc pagesize */
 		mtd->writesize = 2048 << (extid & 0x03);
 		extid >>= 2;
-- 
1.7.11.3



From dwmw2 at infradead.org  Wed Oct 10 02:31:22 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Wed, 10 Oct 2012 07:31:22 +0100
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1349850682.6072.70.camel@shinybook.infradead.org>

On Tue, 2012-10-09 at 23:26 -0700, Brian Norris wrote:
> I have heuristically determined that all the chips that use
> the new table have ID strings which wrap around after the 6th byte.

I'd be happier if we had confirmation of that from Samsung...

-- 
dwmw2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/425367e0/attachment.bin>

From computersforpeace at gmail.com  Wed Oct 10 02:39:43 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 9 Oct 2012 23:39:43 -0700
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <1349850682.6072.70.camel@shinybook.infradead.org>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
 <1349850682.6072.70.camel@shinybook.infradead.org>
Message-ID: <CAN8TOE-ZLyCanBx8pqsbzY6jMQq+ysiVvdLmWvO8QdnyZg1QRg@mail.gmail.com>

On Tue, Oct 9, 2012 at 11:31 PM, David Woodhouse <dwmw2 at infradead.org> wrote:
> On Tue, 2012-10-09 at 23:26 -0700, Brian Norris wrote:
>> I have heuristically determined that all the chips that use
>> the new table have ID strings which wrap around after the 6th byte.
>
> I'd be happier if we had confirmation of that from Samsung...

I can see if that's possible, but I think it's unlikely. They don't
even bother following standards (ONFI). Is this an obstacle to
merging?

Brian


From b32955 at freescale.com  Wed Oct 10 02:15:40 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 10 Oct 2012 14:15:40 +0800
Subject: [PATCH] ARM: dts: mxs: add the `clock-names` for gpmi-nand
In-Reply-To: <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>
References: <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>
Message-ID: <1349849740-14090-1-git-send-email-b32955@freescale.com>

The current DT nodes for mx23/mx28 miss the `clocks-names` item for gpmi-nand.
So the gpmi-nand driver could not find the proper clock.

This patch fixes this issue.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 arch/arm/boot/dts/imx23.dtsi |    1 +
 arch/arm/boot/dts/imx28.dtsi |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 9ca4ca7..6d31aa3 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -69,6 +69,7 @@
 				interrupts = <13>, <56>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 34>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e16d631..55c57ea 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -85,6 +85,7 @@
 				interrupts = <88>, <41>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 50>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
-- 
1.7.0.4




From dedekind1 at gmail.com  Wed Oct 10 02:47:41 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 09:47:41 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
Message-ID: <1349851661.20594.6.camel@sauron.fi.intel.com>

Yeah, I am probably confused.

On Mon, 2012-10-08 at 17:04 +0200, Marcus Prebble wrote:
> We have remounted a static UBI volume which happens to be the rootfs (/)
> onto another location, /tmp/newrootfs

So, you have your UBI volume, it contains your root file-sytem, right?
Then you "remount your" root to /tmp/newrootfs? If yes, I would like to
understand how exactly you do this? Give some more details.

> We are trying to make an image of /tmp/newrootfs with mkfs.ubifs and
> where the output file is /tmp/newrootfs.img.


If the inode number of / is the same as /tmp/newroofs, and the device
number is the same, this is the same inode, no?

This means that /tmp/newrootfs.img will also be visible
in /tmp/newrootfs/tmp/newrootfs.img, no?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/a6c590f6/attachment-0001.sig>

From joakim.tjernlund at transmode.se  Wed Oct 10 02:58:06 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Wed, 10 Oct 2012 08:58:06 +0200
Subject: [PATCH RESEND] jffs2: Fix lock acquisition order bug in
 jffs2_write_begin
In-Reply-To: <507476E7.8030705@freenet.de>
References: <507321E6.1050609@freenet.de> <507476E7.8030705@freenet.de>
Message-ID: <OFA7EB3EBC.A800CC26-ONC1257A93.00262334-C1257A93.00264752@transmode.se>

>
> jffs2_write_begin() first acquires the page lock, then f->sem. This causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first acquires f->sem, then the page lock:
>
> jffs2_garbage_collect_live
>      mutex_lock(&f->sem)                         (A)
>      jffs2_garbage_collect_dnode
>          jffs2_gc_fetch_page
>              read_cache_page_async
>                  do_read_cache_page
>                      lock_page(page)             (B)
>
> jffs2_write_begin
>      grab_cache_page_write_begin
>          find_lock_page
>              lock_page(page)                     (B)
>      mutex_lock(&f->sem)                         (A)
>
> We fix this by restructuring jffs2_write_begin() to take f->sem before the page lock. However, we make sure that f->sem is not held when calling jffs2_reserve_space(), as this is not permitted by the locking rules.
>
> The deadlock above was observed multiple times on an SoC with a dual ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred when using scp to copy files from a host system to the ARM target system. The fix was heavily tested on the same target system.
>
> If the patch is accepted, please get it also pushed to 3.4; it applies cleanly both to linux-mtd.git and the current linux-3.4 tree.
>
> Cc: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
> Signed-off-by: Thomas Betker <thomas.betker at rohde-schwarz.com>

Acked-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>

David, are you happy with this?

 Jocke



From dwmw2 at infradead.org  Wed Oct 10 03:48:49 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Wed, 10 Oct 2012 08:48:49 +0100
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <CAN8TOE-ZLyCanBx8pqsbzY6jMQq+ysiVvdLmWvO8QdnyZg1QRg@mail.gmail.com>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
 <1349850682.6072.70.camel@shinybook.infradead.org>
 <CAN8TOE-ZLyCanBx8pqsbzY6jMQq+ysiVvdLmWvO8QdnyZg1QRg@mail.gmail.com>
Message-ID: <1349855329.6072.72.camel@shinybook.infradead.org>

On Tue, 2012-10-09 at 23:39 -0700, Brian Norris wrote:
> I can see if that's possible, but I think it's unlikely. They don't
> even bother following standards (ONFI). Is this an obstacle to
> merging?

No. I already pushed it.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/c333486d/attachment.bin>

From sachin.kamat at linaro.org  Wed Oct 10 03:51:55 2012
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Wed, 10 Oct 2012 13:21:55 +0530
Subject: [PATCH] mtd: ofpart: Fix incorrect NULL check in
 parse_ofoldpart_partitions()
In-Reply-To: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
References: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <CAK9yfHx7ee-r_xDp+=32nnox_RVGv2-rtiHAeRcPju1gHTtK8w@mail.gmail.com>

ping

On 25 September 2012 15:27, Sachin Kamat <sachin.kamat at linaro.org> wrote:
> The pointer returned by kzalloc should be tested for NULL
> to avoid potential NULL pointer dereference later. Incorrect
> pointer was being tested for NULL. Bug introduced by commit fbcf62a3
> (mtd: physmap_of: move parse_obsolete_partitions to become separate
> parser).
> This patch fixes this bug.
>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
> Cc: Artem Bityutskiy <artem.bityutskiy at intel.com>
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
> ---
>  drivers/mtd/ofpart.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
> index 64be8f0..d9127e2 100644
> --- a/drivers/mtd/ofpart.c
> +++ b/drivers/mtd/ofpart.c
> @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
>         nr_parts = plen / sizeof(part[0]);
>
>         *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
> -       if (!pparts)
> +       if (!*pparts)
>                 return -ENOMEM;
>
>         names = of_get_property(dp, "partition-names", &plen);
> --
> 1.7.4.1
>



-- 
With warm regards,
Sachin


From u.kleine-koenig at pengutronix.de  Wed Oct 10 03:58:41 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 10 Oct 2012 09:58:41 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <5073FE55.2000402@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com>
 <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
Message-ID: <20121010075841.GD10151@pengutronix.de>

Hello,

On Tue, Oct 09, 2012 at 08:37:09PM +1000, Greg Ungerer wrote:
> On 10/09/2012 06:44 PM, Uwe Kleine-K?nig wrote:
> >On Tue, Oct 09, 2012 at 01:29:46PM +1000, Greg Ungerer wrote:
> >>On 09/10/12 01:25, Uwe Kleine-K??nig wrote:
> >>>This allows to put the filesystem at a defined address in ROM allowing
> >>>to save more precious RAM.
> >>>
> >>>I think it's save to default to ROM because the intention of using the
> >>>uclinux map is to use a romfs and so mtd-ram doesn't give you anything
> >>>that mtd-rom doesn't.
> >>>
> >>>Signed-off-by: Uwe Kleine-K?????nig <u.kleine-koenig at pengutronix.de>
> >>
> >>Looks good to me, so:
> >>
> >>Acked-by: Greg Ungerer <gerg at uclinux.org>
> >>
> >>Couple of things to be aware of. Artem currently has a couple of
> >>patches against this file (looks like at least 1 of them is currently
> >>in linux-next). It will probably conflict with your changes, should
> >>be easy enough to fix up.
> >If you tell me a branch to test, I can do so.
> 
> Sure. All three patches I sent to the linux-mtd list are here:
> 
> The following changes since commit 979570e02981d4a8fc20b3cc8fd651856c98ee9d:
>   Linus Torvalds (1):
>         Linux 3.6-rc7
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git cfmmu
> 
> Greg Ungerer (3):
>       mtd: fix wrong usage of ioremap_nocache() in uclinux.c map driver
>       mtd: allow uclinux map driver to be used on any ColdFire CPU platform
>       mtd: clean up uclinux.c map driver
> 
>  drivers/mtd/maps/Kconfig   |    2 +-
>  drivers/mtd/maps/uclinux.c |   42
> +++++++++++++++++++-----------------------
>  2 files changed, 20 insertions(+), 24 deletions(-)
> 
> 
> As far as I can see Artem has pushed the first 2 into for linux-next,
> but not the third. I am hoping he hops in here and lets us know what
> his intentions are with the third...
This branch merged into my tree still works fine.

Something I noticed is that the printk cleanups could look a bit nicer
if you used

	#define pr_fmt(fmt)	"uclinux[mtd]: " fmt

and then pr_notice et al. But maybe this is only subjective.

Also I'm not sure if all the comments are still correct with my change.

(And btw, your mailer is broken regarding line breaking and non-ascii
characters.)

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From dedekind1 at gmail.com  Wed Oct 10 04:13:34 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 11:13:34 +0300
Subject: [PATCH 1/2] UBIFS: introduce categorized lprops counter
Message-ID: <1349856815-22893-1-git-send-email-dedekind1@gmail.com>

From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>

This commit is a preparation for a subsequent bugfix. We introduce a
counter for categorized lprops.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: stable at vger.kernel.org
---
 fs/ubifs/lprops.c |    6 ++++++
 fs/ubifs/ubifs.h  |    3 +++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 86eb8e5..b33ec7a 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
 	default:
 		ubifs_assert(0);
 	}
+
 	lprops->flags &= ~LPROPS_CAT_MASK;
 	lprops->flags |= cat;
+	c->in_a_category_cnt += 1;
+	ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
 }
 
 /**
@@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
 	default:
 		ubifs_assert(0);
 	}
+
+	c->in_a_category_cnt -= 1;
+	ubifs_assert(c->in_a_category_cnt >= 0);
 }
 
 /**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 1e5a086..51ac3e6 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1184,6 +1184,8 @@ struct ubifs_debug_info;
  * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
  * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
  * @freeable_cnt: number of freeable LEBs in @freeable_list
+ * @in_a_category_cnt: count of lprops which are in a certain category, which
+ *                     basically meants that they were loaded from the flash
  *
  * @ltab_lnum: LEB number of LPT's own lprops table
  * @ltab_offs: offset of LPT's own lprops table
@@ -1413,6 +1415,7 @@ struct ubifs_info {
 	struct list_head freeable_list;
 	struct list_head frdi_idx_list;
 	int freeable_cnt;
+	int in_a_category_cnt;
 
 	int ltab_lnum;
 	int ltab_offs;
-- 
1.7.7.6



From dedekind1 at gmail.com  Wed Oct 10 04:13:35 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 11:13:35 +0300
Subject: [PATCH 2/2] UBIFS: fix mounting problems after power cuts
In-Reply-To: <1349856815-22893-1-git-send-email-dedekind1@gmail.com>
References: <1349856815-22893-1-git-send-email-dedekind1@gmail.com>
Message-ID: <1349856815-22893-2-git-send-email-dedekind1@gmail.com>

From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>

This is a bugfix for a problem with the following symptoms:

1. A power cut happens
2. After reboot, we try to mount UBIFS
3. Mount fails with "No space left on device" error message

UBIFS complains like this:

UBIFS error (pid 28225): grab_empty_leb: could not find an empty LEB

The root cause of this problem is that when we mount, not all LEBs are
categorized. Only those which were read are. However, the
'ubifs_find_free_leb_for_idx()' function assumes that all LEBs were
categorized and 'c->freeable_cnt' is valid, which is a false assumption.

This patch fixes the problem by teaching 'ubifs_find_free_leb_for_idx()'
to always fall back to LPT scanning if no freeable LEBs were found.

This problem was reported by few people in the past, but Brent Taylor
was able to reproduce it and send me a flash image which cannot be mounted,
which made it easy to hunt the bug. Kudos to Brent.

Reported-by: Brent Taylor <motobud at gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: stable at vger.kernel.org
---
 fs/ubifs/find.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 28ec13a..4b0b8b4 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -681,8 +681,9 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
 	if (!lprops) {
 		lprops = ubifs_fast_find_freeable(c);
 		if (!lprops) {
-			ubifs_assert(c->freeable_cnt == 0);
-			if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+			if (c->in_a_category_cnt != c->main_lebs ||
+			    c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+				ubifs_assert(c->freeable_cnt == 0);
 				lprops = scan_for_leb_for_idx(c);
 				if (IS_ERR(lprops)) {
 					err = PTR_ERR(lprops);
-- 
1.7.7.6



From marcus.prebble at axis.com  Wed Oct 10 05:04:16 2012
From: marcus.prebble at axis.com (Marcus Prebble)
Date: Wed, 10 Oct 2012 11:04:16 +0200
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349851661.20594.6.camel@sauron.fi.intel.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
Message-ID: <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>

On Wed, 2012-10-10 at 08:47 +0200, Artem Bityutskiy wrote:
> Yeah, I am probably confused.

Or, I have explained it in a not-so-clear way ;)

> 
> On Mon, 2012-10-08 at 17:04 +0200, Marcus Prebble wrote:
> > We have remounted a static UBI volume which happens to be the rootfs (/)
> > onto another location, /tmp/newrootfs
> 
> So, you have your UBI volume, it contains your root file-sytem, right?

Exactly.

> Then you "remount your" root to /tmp/newrootfs? If yes, I would like to
> understand how exactly you do this? Give some more details.

The mount command is: 

mount -t ubifs -o ro ubi0:rootfs /tmp/newrootfs

which results in the following mount table:

[root at axis-00408c93d266 /tmp]4517# mount
ubi0:rootfs-11 on / type ubifs (ro,relatime)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
udev on /dev type tmpfs (rw,relatime)
/dev/ubi0_23 on /mnt/flash type ubifs (rw,relatime)
/dev/part/persistent on /lib/persistent type ubifs (rw,relatime)
/dev/part/iv on /usr/local type ubifs (rw,relatime)
tmpfs on /var type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
tmpfs on /dev/shm type tmpfs (rw,relatime)
tmpfs on /var/cache/recorder type tmpfs
(rw,relatime,size=111320k,nr_inodes=0)
ubi0:rootfs-11 on /var/tmp/newrootfs type ubifs (ro,relatime)

> 
> > We are trying to make an image of /tmp/newrootfs with mkfs.ubifs and
> > where the output file is /tmp/newrootfs.img.

> If the inode number of / is the same as /tmp/newroofs, and the device
> number is the same, this is the same inode, no?

I wrote a small program to test this seeing we don't have stat on target

[root at axis-00408c93d266 /tmp]4530# ./a.out / 
Stat() info for '/':
st_mode=0x41ed
st_ino=1
st_dev=10
st_rdev=0
st_size=0

[root at axis-00408c93d266 /tmp]4530# ./a.out /tmp/newrootfs/
Stat() info for '/tmp/newrootfs/':
st_mode=0x41ed
st_ino=1
st_dev=10
st_rdev=0
st_size=0

So according to stat() it is the same inode.

> 
> This means that /tmp/newrootfs.img will also be visible
> in /tmp/newrootfs/tmp/newrootfs.img, no?

No, as /tmp is a tmpfs mounted on  /var/tmp

[root at axis-00408c93d266 /]4530# touch /tmp/foo.txt   
[root at axis-00408c93d266 /]4530# ls /tmp/newrootfs/tmp/       
ls: /tmp/newrootfs/tmp/: No such file or directory
[root at axis-00408c93d266 /]4530# 

.. and is thus not reachable from /tmp/newrootfs/ 

[root at axis-00408c93d266 /]4530# ls /tmp/newrootfs/var/
[root at axis-00408c93d266 /]4530# 

Apologies for the long-winded explanation - but the output file really
isn't in the the root directory, even though apparently the inodes are
the same. 

Thanks and kind regards,

/Marcus Prebble



From dedekind1 at gmail.com  Wed Oct 10 05:30:52 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 12:30:52 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
Message-ID: <1349861452.20594.12.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 11:04 +0200, Marcus Prebble wrote:
> Apologies for the long-winded explanation - but the output file really
> isn't in the the root directory, even though apparently the inodes are
> the same. 

Well, ok, this is a bug. But I think the solution for this should _not_
be a separate "--band-aid" type of option. We should kill 'in_path()'
and implement a 'is_contained(file, dir)' function, which would return
true if 'dir' contains 'file' and false otherwise.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/05e92308/attachment.sig>

From vipin.kumar at st.com  Wed Oct 10 06:28:54 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Wed, 10 Oct 2012 15:58:54 +0530
Subject: [PATCH 03/11] fsmc/nand: Support multiple banks connected to
 controller
In-Reply-To: <20121009115523.GM12801@game.jcrosoft.org>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>
 <20121009115523.GM12801@game.jcrosoft.org>
Message-ID: <50754DE6.3080409@st.com>

On 10/9/2012 5:25 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
>> Support up to max_banks number of banks in fsmc driver.
>>
>> Signed-off-by: Vipin Kumar<vipin.kumar at st.com>
> please rebase this over my patch that drop -off to resource

Sure, I will do that. I actually planned to do it but forgot while 
sending it

>> ---
>>   .../devicetree/bindings/mtd/fsmc-nand.txt          |  2 ++
>>   arch/arm/boot/dts/spear300.dtsi                    |  1 +
>>   arch/arm/boot/dts/spear310.dtsi                    |  1 +
>>   arch/arm/boot/dts/spear320.dtsi                    |  1 +
>>   arch/arm/boot/dts/spear600.dtsi                    |  1 +
>>   arch/arm/mach-u300/core.c                          |  1 +
>>   drivers/mtd/nand/fsmc_nand.c                       | 26 +++++++++++++++-------
>>   include/linux/mtd/fsmc.h                           |  2 +-
>>   8 files changed, 26 insertions(+), 9 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> index e2c663b..29d1a2f 100644
>> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> @@ -6,6 +6,7 @@ Required properties:
>>   - reg-names: Should contain the reg names "fsmc_regs" and "nand_data"
>>   - st,ale-off : Chip specific offset to ALE
>>   - st,cle-off : Chip specific offset to CLE
>> +- maxbanks: Number of banks supported by SoC
> make it optionnal will simplify the binding with 1 by default and will allow
> to avoid issue
>

hmmm....OK
I think you are right. May be optional with a default of 1 is a better 
option

>>
>>   Optional properties:
>>   - bank-width : Width (in bytes) of the device.  If not present, the width
>> @@ -23,6 +24,7 @@ Example:
>>   		reg-names = "fsmc_regs", "nand_data";
>>   		st,ale-off =<0x20000>;
>>   		st,cle-off =<0x10000>;
>> +		maxbanks =<1>;
>>
>>   		bank-width =<1>;
>>   		nand-skip-bbtscan;
>> diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
>> index ed3627c..19e2328 100644
>> --- a/arch/arm/boot/dts/spear300.dtsi
>> +++ b/arch/arm/boot/dts/spear300.dtsi
>> @@ -42,6 +42,7 @@
>>   			reg-names = "fsmc_regs", "nand_data";
>>   			st,ale-off =<0x20000>;
>>   			st,cle-off =<0x10000>;
>> +			maxbanks =<1>;
>>   			status = "disabled";
>>   		};
>>
>> diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
>> index 62fc4fb..0272afb3 100644
>> --- a/arch/arm/boot/dts/spear310.dtsi
>> +++ b/arch/arm/boot/dts/spear310.dtsi
>> @@ -36,6 +36,7 @@
>>   			reg-names = "fsmc_regs", "nand_data";
>>   			st,ale-off =<0x10000>;
>>   			st,cle-off =<0x20000>;
>> +			maxbanks =<1>;
>>   			status = "disabled";
>>   		};
>>
>> diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
>> index 1f49d69..69fe50d 100644
>> --- a/arch/arm/boot/dts/spear320.dtsi
>> +++ b/arch/arm/boot/dts/spear320.dtsi
>> @@ -42,6 +42,7 @@
>>   			reg-names = "fsmc_regs", "nand_data";
>>   			st,ale-off =<0x20000>;
>>   			st,cle-off =<0x10000>;
>> +			maxbanks =<1>;
>>   			status = "disabled";
>>   		};
>>
>> diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
>> index a3c36e4..6ed57c8 100644
>> --- a/arch/arm/boot/dts/spear600.dtsi
>> +++ b/arch/arm/boot/dts/spear600.dtsi
>> @@ -71,6 +71,7 @@
>>   			reg-names = "fsmc_regs", "nand_data";
>>   			st,ale-off =<0x20000>;
>>   			st,cle-off =<0x10000>;
>> +			maxbanks =<1>;
>>   			status = "disabled";
>>   		};
>>
>> diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
>> index 03acf18..5ea9f71 100644
>> --- a/arch/arm/mach-u300/core.c
>> +++ b/arch/arm/mach-u300/core.c
>> @@ -1546,6 +1546,7 @@ static struct fsmc_nand_platform_data nand_platform_data = {
>>   	.width = FSMC_NAND_BW8,
>>   	.ale_off = PLAT_NAND_ALE,
>>   	.cle_off = PLAT_NAND_CLE,
>> +	.max_banks = 1,
>>   };
>>
>>   static struct platform_device nand_device = {
>> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
>> index bd89580..fc6a044 100644
>> --- a/drivers/mtd/nand/fsmc_nand.c
>> +++ b/drivers/mtd/nand/fsmc_nand.c
>> @@ -298,6 +298,7 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>>    *			- Word access (CPU)
>>    *			- None (Use driver default ie bus width specific
>>    *			  CPU access)
>> + * @max_banks:		Maximum number of banks supported
>>    * @select_chip:	Select a particular bank
>>    *
>>    * @data_pa:		NAND Physical port for Data
>> @@ -325,6 +326,7 @@ struct fsmc_nand_data {
>>   	struct mtd_partition	*partitions;
>>   	unsigned int		nr_partitions;
>>   	enum access_mode	mode;
>> +	uint32_t		max_banks;
>>   	void			(*select_chip)(uint32_t bank, uint32_t busw);
>>
>>   	/* Virtual/Physical addresses for CPU/DMA access */
>> @@ -343,6 +345,7 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
>>
>>   	host = container_of(mtd, struct fsmc_nand_data, mtd);
>>
>> +	host->bank = chipnr;
>>   	switch (chipnr) {
>>   	case -1:
>>   		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
>> @@ -889,6 +892,7 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>>   	of_property_read_u32(np, "st,cle-off",&pdata->cle_off);
>>   	if (of_get_property(np, "nand-skip-bbtscan", NULL))
>>   		pdata->options = NAND_SKIP_BBTSCAN;
>> +	of_property_read_u32(np, "maxbanks",&pdata->max_banks);
>>
>>   	return 0;
>>   }
>> @@ -915,7 +919,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>>   	struct resource *res;
>>   	dma_cap_mask_t mask;
>>   	int ret = 0;
>> -	u32 pid;
>> +	u32 pid, bank;
>>   	int i;
>>
>>   	if (np) {
>> @@ -1023,13 +1027,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>>   		 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
>>   		 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
>>
>> -	host->bank = pdata->bank;
>>   	host->select_chip = pdata->select_bank;
>>   	host->partitions = pdata->partitions;
>>   	host->nr_partitions = pdata->nr_partitions;
>>   	host->dev =&pdev->dev;
>>   	host->dev_timings = pdata->nand_timings;
>>   	host->mode = pdata->mode;
>> +	host->max_banks = pdata->max_banks;
>>
>>   	if (host->mode == USE_DMA_ACCESS)
>>   		init_completion(&host->dma_access_complete);
>> @@ -1083,9 +1087,10 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>>   		break;
>>   	}
>>
>> -	fsmc_nand_setup(host->regs_va, host->bank,
>> -			nand->options&  NAND_BUSWIDTH_16,
>> -			host->dev_timings);
>> +	for (bank = 0; bank<  host->max_banks; bank++)
>> +		fsmc_nand_setup(host->regs_va, bank,
>> +				nand->options&  NAND_BUSWIDTH_16,
>> +				host->dev_timings);
>>
>>   	if (AMBA_REV_BITS(host->pid)>= 8) {
>>   		nand->ecc.read_page = fsmc_read_page_hwecc;
>> @@ -1230,11 +1235,16 @@ static int fsmc_nand_suspend(struct device *dev)
>>   static int fsmc_nand_resume(struct device *dev)
>>   {
>>   	struct fsmc_nand_data *host = dev_get_drvdata(dev);
>> +	uint32_t bank;
>> +
>>   	if (host) {
>>   		clk_prepare_enable(host->clk);
>> -		fsmc_nand_setup(host->regs_va, host->bank,
>> -				host->nand.options&  NAND_BUSWIDTH_16,
>> -				host->dev_timings);
>> +
>> +		for (bank = 0; bank<  host->max_banks; bank++)
>> +			fsmc_nand_setup(host->regs_va, bank,
>> +					host->nand.options&  NAND_BUSWIDTH_16,
>> +					host->dev_timings);
>> +
>>   	}
>>   	return 0;
>>   }
>> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
>> index b200292..f0ab734 100644
>> --- a/include/linux/mtd/fsmc.h
>> +++ b/include/linux/mtd/fsmc.h
>> @@ -153,7 +153,7 @@ struct fsmc_nand_platform_data {
>>   	unsigned int		nr_partitions;
>>   	unsigned int		options;
>>   	unsigned int		width;
>> -	unsigned int		bank;
>> +	unsigned int		max_banks;
>>
>>   	/* CLE, ALE offsets */
>>   	unsigned int		cle_off;
>> --
>> 1.7.11.4
>>
> .
>



From vipin.kumar at st.com  Wed Oct 10 06:33:05 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Wed, 10 Oct 2012 16:03:05 +0530
Subject: [PATCH 10/11] fsmc/nand: Add sw bch support for ecc
 calculation/correction
In-Reply-To: <20121009115023.GK12801@game.jcrosoft.org>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <3968b65e9aa0a81eca16ce0f20e45504da7ad7fe.1349778821.git.vipin.kumar@st.com>
 <20121009115023.GK12801@game.jcrosoft.org>
Message-ID: <50754EE1.7080905@st.com>

On 10/9/2012 5:20 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
>> Signed-off-by: Vipin Kumar<vipin.kumar at st.com>
>> ---
>>   .../devicetree/bindings/mtd/fsmc-nand.txt          |   2 +
>>   drivers/mtd/nand/fsmc_nand.c                       | 156 +++++++++++++--------
>>   include/linux/mtd/fsmc.h                           |   3 +
>>   3 files changed, 106 insertions(+), 55 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> index 598bca2..dcf513b 100644
>> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> @@ -30,6 +30,8 @@ Optional properties:
>>   - st,rb-gpios: When the st,ready-busy is defined as "rb-gpio", a gpio
>>     pin number is defined in this property
>>
>> +- nand-sw-ecc: boolean indicating whether s/w ecc is supported
>> +
> please use the generic binding
>   - nand-ecc-mode = xx

Thanks for pointing. I will do the needful

>>   Example:
>>
>>   	fsmc: flash at d1800000 {
>> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
>> index 762cf83..ff84468 100644
>> --- a/drivers/mtd/nand/fsmc_nand.c
>> +++ b/drivers/mtd/nand/fsmc_nand.c
>> @@ -946,6 +946,9 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>>   	} else
>>   		pdata->rbpin.use_pin = FSMC_RB_WAIT;
>>
>> +	if (of_property_read_bool(np, "nand-sw-ecc"))
>> +		pdata->sw_ecc = true;
>> +
> of_get_nand_ecc_mode
>

Sure

-Vipin



From marcus.prebble at axis.com  Wed Oct 10 06:34:09 2012
From: marcus.prebble at axis.com (Marcus Prebble)
Date: Wed, 10 Oct 2012 12:34:09 +0200
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349861452.20594.12.camel@sauron.fi.intel.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
 <1349861452.20594.12.camel@sauron.fi.intel.com>
Message-ID: <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>

On Wed, 2012-10-10 at 11:30 +0200, Artem Bityutskiy wrote:
> On Wed, 2012-10-10 at 11:04 +0200, Marcus Prebble wrote:
> > Apologies for the long-winded explanation - but the output file really
> > isn't in the the root directory, even though apparently the inodes are
> > the same. 
> 
> Well, ok, this is a bug. But I think the solution for this should _not_
> be a separate "--band-aid" type of option.

Agree entirely. --band-aid was just used as a proof-of-concept.

>  We should kill 'in_path()'
> and implement a 'is_contained(file, dir)' function, which would return
> true if 'dir' contains 'file' and false otherwise.

I will implement and come back with a patch when I have time.

Thanks again for your input,

/Marcus


> 




From marex at denx.de  Wed Oct 10 06:35:55 2012
From: marex at denx.de (Marek Vasut)
Date: Wed, 10 Oct 2012 12:35:55 +0200
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <1349855329.6072.72.camel@shinybook.infradead.org>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
 <CAN8TOE-ZLyCanBx8pqsbzY6jMQq+ysiVvdLmWvO8QdnyZg1QRg@mail.gmail.com>
 <1349855329.6072.72.camel@shinybook.infradead.org>
Message-ID: <201210101235.55741.marex@denx.de>

Dear David Woodhouse,

> On Tue, 2012-10-09 at 23:39 -0700, Brian Norris wrote:
> > I can see if that's possible, but I think it's unlikely. They don't
> > even bother following standards (ONFI). Is this an obstacle to
> > merging?
> 
> No. I already pushed it.

Thanks guys!

Best regards,
Marek Vasut


From marex at denx.de  Wed Oct 10 06:37:13 2012
From: marex at denx.de (Marek Vasut)
Date: Wed, 10 Oct 2012 12:37:13 +0200
Subject: [PATCH] ARM: dts: mxs: add the `clock-names` for gpmi-nand
In-Reply-To: <1349849740-14090-1-git-send-email-b32955@freescale.com>
References: <CAOMZO5A0UX6y3MtHdzZ8V2Z52qsH8Yy-BVtOYEN_OpBezEsvQw@mail.gmail.com>
 <1349849740-14090-1-git-send-email-b32955@freescale.com>
Message-ID: <201210101237.13640.marex@denx.de>

Dear Huang Shijie,

> The current DT nodes for mx23/mx28 miss the `clocks-names` item for
> gpmi-nand. So the gpmi-nand driver could not find the proper clock.
> 
> This patch fixes this issue.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
[...]

One more rant: Can you discard that weird backtick in the patch subject? Maybe 
use '' ?

Best regards,
Marek Vasut


From b32955 at freescale.com  Wed Oct 10 06:27:09 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 10 Oct 2012 18:27:09 +0800
Subject: [PATCH] ARM: dts: mxs: add the "clock-names" for gpmi-nand
In-Reply-To: <201210101237.13640.marex@denx.de>
References: <201210101237.13640.marex@denx.de>
Message-ID: <1349864829-19565-1-git-send-email-b32955@freescale.com>

The current DT nodes for mx23/mx28 miss the `clocks-names` item for gpmi-nand.
So the gpmi-nand driver could not find the proper clock.

This patch fixes this issue.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 arch/arm/boot/dts/imx23.dtsi |    1 +
 arch/arm/boot/dts/imx28.dtsi |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 9ca4ca7..6d31aa3 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -69,6 +69,7 @@
 				interrupts = <13>, <56>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 34>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e16d631..55c57ea 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -85,6 +85,7 @@
 				interrupts = <88>, <41>;
 				interrupt-names = "gpmi-dma", "bch";
 				clocks = <&clks 50>;
+				clock-names = "gpmi_io";
 				fsl,gpmi-dma-channel = <4>;
 				status = "disabled";
 			};
-- 
1.7.0.4




From dedekind1 at gmail.com  Wed Oct 10 07:30:30 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 14:30:30 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
 <1349861452.20594.12.camel@sauron.fi.intel.com>
 <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>
Message-ID: <1349868630.20594.16.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 12:34 +0200, Marcus Prebble wrote:
> I will implement and come back with a patch when I have time.

I actually went ahead and cooked something. Could you please review and
give it a test? Inlined below and also attached. Thanks!


From 7c1b939f2cf0141dfb1969d51b4157a75f55ddac Mon Sep 17 00:00:00 2001
From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Date: Wed, 10 Oct 2012 14:23:18 +0300
Subject: [PATCH] mkfs.ubifs: rewrite path checking

We use the 'in_path()' function to check whether the output image is
withing the mkfs.ubifs root directory or not. However, this function
is not correct and it fails for the following situation, as
Marcus Prebble <marcus.prebble at axis.com> reports:

1. We have our root file-system mounted at / and want to build an image
   out of it.
2. We have tmpfs mounted at /tmp
3. We mount the root file-system under /tmp/newroot
4. We run mkfs.ubifs with -r /tmp/newroot -o /tmp/image

And this fails. It fails because 'in_path()' misses this use-case.

This patch re-implements the check completely. Now we use 'realpath()'
to find canonical paths and just check that the output file is not
under the root mkfs.ubifs directory.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
---
 mkfs.ubifs/mkfs.ubifs.c | 116 +++++++++++++++---------------------------------
 1 file changed, 37 insertions(+), 79 deletions(-)

diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
index 149806b..885c202 100644
--- a/mkfs.ubifs/mkfs.ubifs.c
+++ b/mkfs.ubifs/mkfs.ubifs.c
@@ -20,6 +20,7 @@
  *          Zoltan Sogor
  */
 
+#define _XOPEN_SOURCE 500 /* For realpath() */
 #define PROGRAM_NAME "mkfs.ubifs"
 
 #include "mkfs.ubifs.h"
@@ -235,93 +236,50 @@ static char *make_path(const char *dir, const char *name)
 }
 
 /**
- * same_dir - determine if two file descriptors refer to the same directory.
- * @fd1: file descriptor 1
- * @fd2: file descriptor 2
- */
-static int same_dir(int fd1, int fd2)
-{
-	struct stat stat1, stat2;
-
-	if (fstat(fd1, &stat1) == -1)
-		return -1;
-	if (fstat(fd2, &stat2) == -1)
-		return -1;
-	return stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino;
-}
-
-/**
- * do_openat - open a file in a directory.
- * @fd: file descriptor of open directory
- * @path: path relative to directory
- * @flags: open flags
+ * is_contained - determine if a file is beneath a directory.
+ * @file: file path name
+ * @dir: directory path name
  *
- * This function is provided because the library function openat is sometimes
- * not available.
+ * This function returns %1 if @file is accessible from the @dir directory and
+ * %0 otherwise. In case of error, returns %-1.
  */
-static int do_openat(int fd, const char *path, int flags)
+static int is_contained(const char *file, const char *dir)
 {
-	int ret;
-	char *cwd;
+	char *file_base, *copy, *real_file, *real_dir, *p;
 
-	cwd = getcwd(NULL, 0);
-	if (!cwd)
+	/* Make a copy of the file path because 'dirname()' can modify it */
+	copy = strdup(file);
+	if (!copy)
 		return -1;
-	ret = fchdir(fd);
-	if (ret != -1)
-		ret = open(path, flags);
-	if (chdir(cwd) && !ret)
-		ret = -1;
-	free(cwd);
-	return ret;
-}
+	file_base = dirname(copy);
 
-/**
- * in_path - determine if a file is beneath a directory.
- * @dir_name: directory path name
- * @file_name: file path name
- */
-static int in_path(const char *dir_name, const char *file_name)
-{
-	char *fn = strdup(file_name);
-	char *dn;
-	int fd1, fd2, fd3, ret = -1, top_fd;
+	/* Turn the paths into the canonical form */
+	real_file = malloc(PATH_MAX);
+	if (!real_file) {
+		free(copy);
+		return -1;
+	}
 
-	if (!fn)
+	real_dir = malloc(PATH_MAX);
+	if (!real_dir) {
+		free(real_file);
+		free(copy);
+		return -1;
+	}
+	if (!realpath(file_base, real_file)) {
+		perror("realpath");
 		return -1;
-	top_fd = open("/", O_RDONLY);
-	if (top_fd != -1) {
-		dn = dirname(fn);
-		fd1 = open(dir_name, O_RDONLY);
-		if (fd1 != -1) {
-			fd2 = open(dn, O_RDONLY);
-			if (fd2 != -1) {
-				while (1) {
-					int same;
-
-					same = same_dir(fd1, fd2);
-					if (same) {
-						ret = same;
-						break;
-					}
-					if (same_dir(fd2, top_fd)) {
-						ret = 0;
-						break;
-					}
-					fd3 = do_openat(fd2, "..", O_RDONLY);
-					if (fd3 == -1)
-						break;
-					close(fd2);
-					fd2 = fd3;
-				}
-				close(fd2);
-			}
-			close(fd1);
-		}
-		close(top_fd);
 	}
-	free(fn);
-	return ret;
+	if (!realpath(dir, real_dir)) {
+		perror("realpath");
+		return -1;
+	}
+
+	p = strstr(real_file, real_dir);
+	free(real_dir);
+	free(real_file);
+	free(copy);
+	return !!p;
 }
 
 /**
@@ -376,7 +334,7 @@ static int validate_options(void)
 
 	if (!output)
 		return err_msg("no output file or UBI volume specified");
-	if (root && in_path(root, output))
+	if (root && is_contained(output, root))
 		return err_msg("output file cannot be in the UBIFS root "
 			       "directory");
 	if (!is_power_of_2(c->min_io_size))
-- 
1.7.11.4



-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mkfs.ubifs-rewrite-path-checking.patch
Type: text/x-patch
Size: 4879 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/dd856764/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/dd856764/attachment.sig>

From marex at denx.de  Wed Oct 10 07:34:18 2012
From: marex at denx.de (Marek Vasut)
Date: Wed, 10 Oct 2012 13:34:18 +0200
Subject: [PATCH] ARM: dts: mxs: add the "clock-names" for gpmi-nand
In-Reply-To: <1349864829-19565-1-git-send-email-b32955@freescale.com>
References: <201210101237.13640.marex@denx.de>
 <1349864829-19565-1-git-send-email-b32955@freescale.com>
Message-ID: <201210101334.18605.marex@denx.de>

Dear Huang Shijie,

> The current DT nodes for mx23/mx28 miss the `clocks-names` item for
> gpmi-nand. So the gpmi-nand driver could not find the proper clock.
> 
> This patch fixes this issue.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
[...]

Reviewed-by: Marek Vasut <marex at denx.de>

I will test later today.

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Wed Oct 10 08:48:58 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 15:48:58 +0300
Subject: [PATCH] imx/gpmi: Make debug prints more clear
In-Reply-To: <505EDAF0.2040708@gmail.com>
References: <505EDAF0.2040708@gmail.com>
Message-ID: <1349873338.20594.26.camel@sauron.fi.intel.com>

On Sun, 2012-09-23 at 15:18 +0530, Vikram Narayanan wrote:
> Make the error messages more debugging friendly
> 
> Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
> Cc: Huang Shijie <b32955 at freescale.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/6cac93ac/attachment-0001.sig>

From dedekind1 at gmail.com  Wed Oct 10 08:49:18 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 15:49:18 +0300
Subject: [PATCH v2] mtd: cmdlinepart: Simplify parse_cmdline_partitions
In-Reply-To: <20120923095229.5d0c6806@pixies.home.jungo.com>
References: <20120923095229.5d0c6806@pixies.home.jungo.com>
Message-ID: <1349873358.20594.27.camel@sauron.fi.intel.com>

On Sun, 2012-09-23 at 09:52 +0200, Shmulik Ladkani wrote:
> From: Shmulik Ladkani <shmulik.ladkani at gmail.com>
> 
> Simply 'parse_cmdline_partitions': the outer loop iterating over
> 'partitions' is actually a search loop, it does not execute the inner
> loop for each partition, only for the matched partition.
> 
> Let's break when search is successful, and move all inner code (relevant
> only for the matched partition) outside of the outer loop.
> 
> Resulting code is much more readable, and makes the indent level sane.
> 
> Signed-off-by: Shmulik Ladkani <shmulik.ladkani at gmail.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/eebb92fc/attachment.sig>

From artem.bityutskiy at linux.intel.com  Wed Oct 10 09:42:33 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 16:42:33 +0300
Subject: [PATCH V6] mtd: m25p80: Make fast read configurable via DT
In-Reply-To: <1348450779-22495-1-git-send-email-marex@denx.de>
References: <1348450779-22495-1-git-send-email-marex@denx.de>
Message-ID: <1349876553.20594.29.camel@sauron.fi.intel.com>

On Mon, 2012-09-24 at 03:39 +0200, Marek Vasut wrote:
> Add DT property "m25p,fast-read" that signalises the particular
> chip supports "fast read" opcode.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/a6e810c9/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 10 10:18:21 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 17:18:21 +0300
Subject: Offtopic: ubifs and best practice for supporting browser based
 firmware upgrades
In-Reply-To: <CADqH6VxNTns60J6tc5a6SwdoGcetSK5sYF=a5Sf2HxDR+igCLg@mail.gmail.com>
References: <CADqH6VzVhsGvCCbokjW8TAJSq5Sj33GiHt4gZxOFZaeHtJ4JeQ@mail.gmail.com>
 <1346751620.12610.35.camel@sauron.fi.intel.com>
 <CADqH6Vw0kY=U-jymgpj_JpzLkqLb0JjK7J1C1V6qF_uo-jDFng@mail.gmail.com>
 <1348651795.24309.49.camel@sauron.fi.intel.com>
 <alpine.DEB.2.00.1209261251200.19047@lnxricardw.se.axis.com>
 <1348658003.24309.70.camel@sauron.fi.intel.com>
 <CADqH6VxNTns60J6tc5a6SwdoGcetSK5sYF=a5Sf2HxDR+igCLg@mail.gmail.com>
Message-ID: <1349878701.20594.30.camel@sauron.fi.intel.com>

On Wed, 2012-09-26 at 20:38 +0800, Jaya Kumar wrote:
> I'm guessing I also need to hack the following in rename_volumes:
> desc = ubi_open_volume_nm(ubi->ubi_num, re->new_name, UBI_EXCLUSIVE);

Probably, you can use UBI_READONLY instead of UBI_EXCLUSIVE, I guess,
just to try if the approach works.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/0b4d31bd/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 10 10:35:57 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 17:35:57 +0300
Subject: [PATCH] mtd: m25p80: add support for the windbond w25q256 chip
In-Reply-To: <1348563927-9131-1-git-send-email-matthieu.castet@parrot.com>
References: <1348563927-9131-1-git-send-email-matthieu.castet@parrot.com>
Message-ID: <1349879757.20594.32.camel@sauron.fi.intel.com>

On Tue, 2012-09-25 at 11:05 +0200, Matthieu CASTET wrote:
> Signed-off-by: Matthieu CASTET <matthieu.castet at parrot.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/cce8ad8d/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 10 10:36:18 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 17:36:18 +0300
Subject: [PATCH] mtd: ofpart: Fix incorrect NULL check in
 parse_ofoldpart_partitions()
In-Reply-To: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
References: <1348567033-5418-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1349879778.20594.33.camel@sauron.fi.intel.com>

On Tue, 2012-09-25 at 15:27 +0530, Sachin Kamat wrote:
> The pointer returned by kzalloc should be tested for NULL
> to avoid potential NULL pointer dereference later. Incorrect
> pointer was being tested for NULL. Bug introduced by commit fbcf62a3
> (mtd: physmap_of: move parse_obsolete_partitions to become separate
> parser).
> This patch fixes this bug.
> 
> Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
> Cc: Artem Bityutskiy <artem.bityutskiy at intel.com>
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Added

Cc: stable at vger.kernel.org [3.2+]

and pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/7b4740fc/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 10 10:38:17 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 17:38:17 +0300
Subject: [PATCH] mtd: fsl_elbc_nand: remove unnecessary badblock_pattern
In-Reply-To: <1348701327-12226-1-git-send-email-computersforpeace@gmail.com>
References: <1348701327-12226-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1349879897.20594.34.camel@sauron.fi.intel.com>

On Wed, 2012-09-26 at 16:15 -0700, Brian Norris wrote:
> Since the introduction of nand_create_default_bbt_descr() (now known as
> nand_create_badblock_pattern()) in
> 
>   commit 58373ff0afff4cc8ac40608872995f4d87eb72ec
> 
> nand_chip.badblock_pattern will be dynamically calculated to the same
> 1-byte-length pattern that is required by fsl_elbc_nand. This custom
> badblock_pattern is no longer needed, then, and its removal may help
> facilitate further nand_bbt.c/nand_base.c cleanup in the future (one
> down, many to go?)
> 
> Anyway, with nand_bbt.c fixed, this effectively reverts:
> 
>   commit 452db2724351ff3d9416a183a7955e00ab4e6ab4
>   [MTD] [NAND] fsl_elbc_nand: fix OOB workability for large page NAND chips
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Cc: Scott Wood <scottwood at freescale.com>
> ---
> 
> Not even compile-tested...

Compile-tested and pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/e403e0f6/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 10 10:40:23 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 10 Oct 2012 17:40:23 +0300
Subject: [PATCH] mtd: mtd_oobtest: printk -> pr_{info,err}
In-Reply-To: <1348713422-16626-1-git-send-email-computersforpeace@gmail.com>
References: <1348713422-16626-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1349880023.20594.36.camel@sauron.fi.intel.com>

On Wed, 2012-09-26 at 19:37 -0700, Brian Norris wrote:
> Use pr_info() and pr_err() while defining pr_fmt(). This saves a few
> characters, joins a few lines, and makes the code a little more readable
> (and grep-able).
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>

Not sure about this - there is a patch-set from Vikram Narayanan
<vikram186 at gmail.com> (Subject: [RFC PATCH 0/8] mtd_tests: Remove
duplicate code and cleanups) which does this for all tests. I hoped he
can re-send newer version.

Also, this patch-set should probably merge all the split format strings
at the same time.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/7797ac1d/attachment-0001.sig>

From bas at bmail.ru  Wed Oct 10 10:55:56 2012
From: bas at bmail.ru (kyak)
Date: Wed, 10 Oct 2012 18:55:56 +0400 (MSK)
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.LNX.2.02.1210081900410.1375@bas>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
 <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081833560.1375@bas>
 <alpine.DEB.2.00.1210081650200.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081900410.1375@bas>
Message-ID: <alpine.LNX.2.02.1210101855001.1211@bas>

Thanks Artem, your patch 
(http://lists.infradead.org/pipermail/linux-mtd/2012-October/044477.html) 
has fixed my problem as well.

On Mon, 8 Oct 2012, kyak wrote:

> On Mon, 8 Oct 2012, Ricard Wanderlof wrote:
>
>> Definitely. I see your point now. This must be a definite bug in in_path().
>> 
>> One problem though is that when in_path() traverses the tree upwards, and 
>> encounters a directory which it can't read it can't complete its job. On 
>> the other hand, it shouldn't have to do that, it really only needs to see 
>> that the output file is not below the top level of the input tree. Or am I 
>> missing a case here?
>> 
> Yes, it only needs to check if the output file is above the top level
> of the input tree. But I guess it's not that easy - first things that come 
> into my mind are symbolic links and mount --bind.
>


From marcus.prebble at axis.com  Wed Oct 10 11:26:25 2012
From: marcus.prebble at axis.com (Marcus Prebble)
Date: Wed, 10 Oct 2012 17:26:25 +0200
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349868630.20594.16.camel@sauron.fi.intel.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
 <1349861452.20594.12.camel@sauron.fi.intel.com>
 <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>
 <1349868630.20594.16.camel@sauron.fi.intel.com>
Message-ID: <1349882785.2552.1987.camel@lnxprebble2.se.axis.com>

Hi Artem,

Big thanks for the provided patch. It seems to solve the problem we here
at Axis and other users were having.
When trying to break it (unsuccessfully) I found that if the directory
of the output file was non-existent then the function would return -1
(correct), but the error messages were:

"realpath: no such file or directory"
"Error: output file cannot be in the UBIFS root directory"

which was a tad confusing. Please find attached a new diff (based off
yours) with a few minor suggested changes.

Kind regards,

/Marcus Prebble



On Wed, 2012-10-10 at 13:30 +0200, Artem Bityutskiy wrote:
> On Wed, 2012-10-10 at 12:34 +0200, Marcus Prebble wrote:
> > I will implement and come back with a patch when I have time.
> 
> I actually went ahead and cooked something. Could you please review and
> give it a test? Inlined below and also attached. Thanks!
> 
> 
> From 7c1b939f2cf0141dfb1969d51b4157a75f55ddac Mon Sep 17 00:00:00 2001
> From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
> Date: Wed, 10 Oct 2012 14:23:18 +0300
> Subject: [PATCH] mkfs.ubifs: rewrite path checking
> 
> We use the 'in_path()' function to check whether the output image is
> withing the mkfs.ubifs root directory or not. However, this function
> is not correct and it fails for the following situation, as
> Marcus Prebble <marcus.prebble at axis.com> reports:
> 
> 1. We have our root file-system mounted at / and want to build an image
>    out of it.
> 2. We have tmpfs mounted at /tmp
> 3. We mount the root file-system under /tmp/newroot
> 4. We run mkfs.ubifs with -r /tmp/newroot -o /tmp/image
> 
> And this fails. It fails because 'in_path()' misses this use-case.
> 
> This patch re-implements the check completely. Now we use 'realpath()'
> to find canonical paths and just check that the output file is not
> under the root mkfs.ubifs directory.
> 
> Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
> ---
>  mkfs.ubifs/mkfs.ubifs.c | 116 +++++++++++++++---------------------------------
>  1 file changed, 37 insertions(+), 79 deletions(-)
> 
> diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
> index 149806b..885c202 100644
> --- a/mkfs.ubifs/mkfs.ubifs.c
> +++ b/mkfs.ubifs/mkfs.ubifs.c
> @@ -20,6 +20,7 @@
>   *          Zoltan Sogor
>   */
>  
> +#define _XOPEN_SOURCE 500 /* For realpath() */
>  #define PROGRAM_NAME "mkfs.ubifs"
>  
>  #include "mkfs.ubifs.h"
> @@ -235,93 +236,50 @@ static char *make_path(const char *dir, const char *name)
>  }
>  
>  /**
> - * same_dir - determine if two file descriptors refer to the same directory.
> - * @fd1: file descriptor 1
> - * @fd2: file descriptor 2
> - */
> -static int same_dir(int fd1, int fd2)
> -{
> -	struct stat stat1, stat2;
> -
> -	if (fstat(fd1, &stat1) == -1)
> -		return -1;
> -	if (fstat(fd2, &stat2) == -1)
> -		return -1;
> -	return stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino;
> -}
> -
> -/**
> - * do_openat - open a file in a directory.
> - * @fd: file descriptor of open directory
> - * @path: path relative to directory
> - * @flags: open flags
> + * is_contained - determine if a file is beneath a directory.
> + * @file: file path name
> + * @dir: directory path name
>   *
> - * This function is provided because the library function openat is sometimes
> - * not available.
> + * This function returns %1 if @file is accessible from the @dir directory and
> + * %0 otherwise. In case of error, returns %-1.
>   */
> -static int do_openat(int fd, const char *path, int flags)
> +static int is_contained(const char *file, const char *dir)
>  {
> -	int ret;
> -	char *cwd;
> +	char *file_base, *copy, *real_file, *real_dir, *p;
>  
> -	cwd = getcwd(NULL, 0);
> -	if (!cwd)
> +	/* Make a copy of the file path because 'dirname()' can modify it */
> +	copy = strdup(file);
> +	if (!copy)
>  		return -1;
> -	ret = fchdir(fd);
> -	if (ret != -1)
> -		ret = open(path, flags);
> -	if (chdir(cwd) && !ret)
> -		ret = -1;
> -	free(cwd);
> -	return ret;
> -}
> +	file_base = dirname(copy);
>  
> -/**
> - * in_path - determine if a file is beneath a directory.
> - * @dir_name: directory path name
> - * @file_name: file path name
> - */
> -static int in_path(const char *dir_name, const char *file_name)
> -{
> -	char *fn = strdup(file_name);
> -	char *dn;
> -	int fd1, fd2, fd3, ret = -1, top_fd;
> +	/* Turn the paths into the canonical form */
> +	real_file = malloc(PATH_MAX);
> +	if (!real_file) {
> +		free(copy);
> +		return -1;
> +	}
>  
> -	if (!fn)
> +	real_dir = malloc(PATH_MAX);
> +	if (!real_dir) {
> +		free(real_file);
> +		free(copy);
> +		return -1;
> +	}
> +	if (!realpath(file_base, real_file)) {
> +		perror("realpath");
>  		return -1;
> -	top_fd = open("/", O_RDONLY);
> -	if (top_fd != -1) {
> -		dn = dirname(fn);
> -		fd1 = open(dir_name, O_RDONLY);
> -		if (fd1 != -1) {
> -			fd2 = open(dn, O_RDONLY);
> -			if (fd2 != -1) {
> -				while (1) {
> -					int same;
> -
> -					same = same_dir(fd1, fd2);
> -					if (same) {
> -						ret = same;
> -						break;
> -					}
> -					if (same_dir(fd2, top_fd)) {
> -						ret = 0;
> -						break;
> -					}
> -					fd3 = do_openat(fd2, "..", O_RDONLY);
> -					if (fd3 == -1)
> -						break;
> -					close(fd2);
> -					fd2 = fd3;
> -				}
> -				close(fd2);
> -			}
> -			close(fd1);
> -		}
> -		close(top_fd);
>  	}
> -	free(fn);
> -	return ret;
> +	if (!realpath(dir, real_dir)) {
> +		perror("realpath");
> +		return -1;
> +	}
> +
> +	p = strstr(real_file, real_dir);
> +	free(real_dir);
> +	free(real_file);
> +	free(copy);
> +	return !!p;
>  }
>  
>  /**
> @@ -376,7 +334,7 @@ static int validate_options(void)
>  
>  	if (!output)
>  		return err_msg("no output file or UBI volume specified");
> -	if (root && in_path(root, output))
> +	if (root && is_contained(output, root))
>  		return err_msg("output file cannot be in the UBIFS root "
>  			       "directory");
>  	if (!is_power_of_2(c->min_io_size))
> -- 
> 1.7.11.4
> 
> 
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-mkfs.ubifs-rewrite-path-checking.patch
Type: text/x-patch
Size: 2088 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121010/b1472c7b/attachment.bin>

From vikram186 at gmail.com  Wed Oct 10 11:47:48 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 21:17:48 +0530
Subject: [PATCH] mtd: mtd_oobtest: printk -> pr_{info,err}
In-Reply-To: <1349880023.20594.36.camel@sauron.fi.intel.com>
References: <1348713422-16626-1-git-send-email-computersforpeace@gmail.com>
 <1349880023.20594.36.camel@sauron.fi.intel.com>
Message-ID: <507598A4.8000704@gmail.com>

On 10/10/2012 8:10 PM, Artem Bityutskiy wrote:
> On Wed, 2012-09-26 at 19:37 -0700, Brian Norris wrote:
>> Use pr_info() and pr_err() while defining pr_fmt(). This saves a few
>> characters, joins a few lines, and makes the code a little more readable
>> (and grep-able).
>>
>> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
>
> Not sure about this - there is a patch-set from Vikram Narayanan
> <vikram186 at gmail.com>  (Subject: [RFC PATCH 0/8] mtd_tests: Remove
> duplicate code and cleanups) which does this for all tests. I hoped he
> can re-send newer version.

Yeah. I'll send a newer version which will change the printk to pr_* for 
all the tests. I can take Brian's patch as well and send the whole 
series, if he is ok with it.

Regards,
Vikram


From computersforpeace at gmail.com  Wed Oct 10 12:29:51 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 10 Oct 2012 09:29:51 -0700
Subject: [PATCH] mtd: mtd_oobtest: printk -> pr_{info,err}
In-Reply-To: <507598A4.8000704@gmail.com>
References: <1348713422-16626-1-git-send-email-computersforpeace@gmail.com>
 <1349880023.20594.36.camel@sauron.fi.intel.com>
 <507598A4.8000704@gmail.com>
Message-ID: <CAN8TOE8tjdP-qc_wgw1388xVTvQD2LQm8Ex+iUwfarE+NUVDYg@mail.gmail.com>

On Wed, Oct 10, 2012 at 8:47 AM, Vikram Narayanan <vikram186 at gmail.com> wrote:
> On 10/10/2012 8:10 PM, Artem Bityutskiy wrote:
>>
>> On Wed, 2012-09-26 at 19:37 -0700, Brian Norris wrote:
>>>
>>> Use pr_info() and pr_err() while defining pr_fmt(). This saves a few
>>> characters, joins a few lines, and makes the code a little more readable
>>> (and grep-able).
>>>
>>> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
>>
>>
>> Not sure about this - there is a patch-set from Vikram Narayanan
>> <vikram186 at gmail.com>  (Subject: [RFC PATCH 0/8] mtd_tests: Remove
>> duplicate code and cleanups) which does this for all tests. I hoped he
>> can re-send newer version.

I made the patch a while ago when playing around with the test for the
first time but never bothered to send it out until recently. It was
independent of the fact that Vikram did a (later) patch series for
this.

> Yeah. I'll send a newer version which will change the printk to pr_* for all
> the tests. I can take Brian's patch as well and send the whole series, if he
> is ok with it.

Sure, take it in your series and modify as you want (that's what the
"Signed-off-by" and GPL thing is all about). Or just rewrite it, if
your own search-and-replace is better :)

Regards,
Brian


From ivan.djelic at parrot.com  Wed Oct 10 12:38:41 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Wed, 10 Oct 2012 18:38:41 +0200
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>
References: <cover.1349672877.git.afzal@ti.com>
 <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>
Message-ID: <20121010163840.GA13585@parrot.com>

On Mon, Oct 08, 2012 at 07:08:08AM +0100, Mohammed, Afzal wrote:
> Hi Ivan,
> 
> On Mon, Oct 08, 2012 at 11:05:56, Mohammed, Afzal wrote:
> 
> > This series cleans up omap-gpmc related code so that omap can
> > be a part of common zImage.
> 
> > This series moves gpmc.h from plat-omap/include/plat to mach-omap2
> > so that header file is local.
> 
> > Patches 7 & 8 cleans up the already moved platform data header files
> > to contain only platform data. Also gpmc-nand information is moved
> > to nand platform data header.
> > 
> > Patches 9-13 makes nand driver independent of gpmc header file
> > 
> > And the final patch localizes gpmc header.
> 
> BCH[48] support that you have added on OMAP using gpmc exported
> symbols has been changed such that nand driver now takes care
> of BCH support without relying on gpmc exported symbols.
> 
> This is more or less a cut & paste of your implementation, which was
> necessitated now due to common ARM zImage cleanup w.r.t header files.
> 
> Please verify that BCH[48] works as earlier with this series.

Hi Afzal,

I ran several mtd regression tests on a Beagle Board on your gpmc-czimage-v2 tag.
All BCH error correcting tests passed successfully.

I occasionally had weird read errors though, especially when reading blank pages:
the omap driver returned 512-byte sectors containing something like:



instead of:



I was able to reproduce the problem also on l2-mtd tip, albeit less often.
The problem seems to occur quite randomly, it may be a hardware issue on
my board...

Anyway, the ECC handling part looks OK to me.

Best regards,
--
Ivan


From linus.walleij at linaro.org  Wed Oct 10 12:49:34 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 10 Oct 2012 18:49:34 +0200
Subject: [PATCH 01/11] fsmc/nand:FIX: Change the type for regs to void
 __iomem *
In-Reply-To: <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
Message-ID: <CACRpkdaQuF05Cu_zTVH0PUQv5neG=5B8+8W+7g9tkG57ASn=nA@mail.gmail.com>

On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Oct 10 13:07:23 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 10 Oct 2012 19:07:23 +0200
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
Message-ID: <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>

On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> read_buf/write_buf callbacks should be able to accept a user space memory
> address (virtually contiguous memory) as buffer pointer.
>
> This patch allocates a logically contiguous memory area which is use for dma

You mean PHYSICALLY contigous, don't you?

> xfers during read and write accesses.
>
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

If you really want a physically contigous buffer you need to use
CMA, but I don't think that is the real problem here...

We're already using userspace buffers in e.g. the MMCI driver
(drivers/mmc/host/mmci.c).

The real problem is likely the DMA driver. The stuf that get
fed into dma.device_prep_dma_memcpy() needs to be
converted to a scatterlist and then set up in the LLI list
for the controller.

IIRC SPEAr is using drivers/dma/dw_dmac.c so
check this driver's dwc_prep_dma_memcpy().
It does seem like it is checking whether src or
dest is scattered in this for() loop:

for (offset = 0; offset < len; offset += xfer_count << src_width) {}

dma_sync_single_for_device() is translating the virtual
address to physical for every chunk BTW.

So instead of doing this copying, debug the problem, and
see if there is a bug in that for()-loop or similar, if it needs
to be rewritten or so.

Yours,
Linus Walleij


From ivan.djelic at parrot.com  Wed Oct 10 13:08:06 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Wed, 10 Oct 2012 19:08:06 +0200
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
Message-ID: <20121010170806.GB13585@parrot.com>

On Tue, Oct 09, 2012 at 01:36:50PM +0100, Philip, Avinash wrote:
(...)
> > There are at least 2 potential problems when reading an erased page with bitflips:
> > 
> > 1. bitflip in data area and no bitflip in spare area (all 0xff)
> > Your code will not perform any ECC correction.
> > UBIFS does not like finding bitflips in empty pages, see for instance
> > http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.
> 
> In case of error correction using ELM, syndrome vector calculated after reading
> Data area & OOB area. So handling of erased page requires a software workaround.
> I am planning something as follows.
> 
> I will first check calculated ecc, which would be zero for non error pages.
> Then I would check 0xFF in OOB area (for erased page) by checking number of
> bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
> set entire page as 0xFF if number of bit zeros is less than max bit flips
> (8 or 4) by counting the number of bit zero's in data area.
> 
> This logic is implemented in fsmc_nand.c
> 
> See commit
> mtd: fsmc: Newly erased page read algorithm implemented
> 
> > 
> > 2. bitflip in ECC bytes in spare area
> > Your code will report an uncorrectable error upon reading; if this happens while reading a partially programmed UBI block,
> > I guess you will lose data.
> 
> In case of uncorrectable errors due to bit flips in spare area,
> I can go on checking number of bit zero's in data area + OOB area
> are less than max bit flips (8 or 4), I can go on setting the entire
> page as 0xFF.
> 

OK, sounds reasonable.
Another simple strategy could use the fact that you add a 14th zero byte to
the 13 BCH bytes for RBL compatibility:

Upon reading:
 - if this 14th byte is zero (*) => page was programmed: perform ECC
   correction as usual
 - else, page was not programmed: do not perform ECC, read entire data+spare
   area, and set it to 0xff if less than 8 or 4 (max bitflips) zero bits
   were found

(*) for robustness to bitflip in 14th byte, replace condition
"14th byte is zero" by e.g. "14th byte has less than 4 bits set to 1".

What do you think ?

BR,
--
Ivan


From linus.walleij at linaro.org  Wed Oct 10 13:09:22 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 10 Oct 2012 19:09:22 +0200
Subject: [PATCH 08/11] fsmc/nand: Use relaxed variants of io accessors
In-Reply-To: <88484dbae96f7db42ce615552a4c758844a5e6cc.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <88484dbae96f7db42ce615552a4c758844a5e6cc.1349778821.git.vipin.kumar@st.com>
Message-ID: <CACRpkdZWdJ+uZhkvygXVsbr_3rWt60j4YMiLwed8FUwzvF5KoQ@mail.gmail.com>

On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> Use relaxed variants of readl/writel accessors. readl/writel io accessors use
> explicit dsb instruction which causes stalls in the processor core resulting
> several cycles of delay for each access
>
> Use relaxed variants where ever possible. This also results in an improved
> read/write performance.
>
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Good idea for any performance-critical code! Thanks!
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Oct 10 13:10:33 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 10 Oct 2012 19:10:33 +0200
Subject: [PATCH 06/11] fsmc/nand: Modify the wait to uninterruptible
In-Reply-To: <3dcb002d0ad03dde9a91e8128dbaa320b8a264a9.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <3dcb002d0ad03dde9a91e8128dbaa320b8a264a9.1349778821.git.vipin.kumar@st.com>
Message-ID: <CACRpkdYj2o77fLWM8vwpCSSuQkJAwOx5gNhCQd+yZ8SJ4M328Q@mail.gmail.com>

On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> Interruptible wait caused trouble in fsmc hardware state machine if the
> application was killed abruptly. To make fsmc operation safe turn wait in to
> un-interruptible.
>
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Yes this is wise.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Oct 10 13:22:04 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 10 Oct 2012 19:22:04 +0200
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
Message-ID: <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>

On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> change_bit routine accepts only ulong pointers as buffer, so an unaligned char
> pointer passed to change_bit may lead to a crash.
>
> Fix this bug by accessing the buffer as char pointer.

Why not see if we can fix change_bit() instead?
Since I suspect this is on ARM I bet Russell and Nico
want to hear about this if there is a problem.

Can the ARM change_bit() not be fixed, so that
long arguments are the only option?

>                 if (err_idx[i] < chip->ecc.size * 8) {
> -                       change_bit(err_idx[i], (unsigned long *)dat);
> +                       uint8_t *p = dat + err_idx[i] / 8;
> +                       *p = *p ^ (1 << (err_idx[i] % 8));

I'm one of these people who would write >>3 and
&7 rather than /8 or %8 but I guess we are all
different. Atleast consider it if you stick with this...

Yours,
Linus Walleij


From vikram186 at gmail.com  Wed Oct 10 13:31:49 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:01:49 +0530
Subject: [RESEND PATCH 0/9] mtd_tests cleanup
Message-ID: <5075B105.4080701@gmail.com>

This patch series removes the usage of PRINT_PREF and printk's and
replaces it with pr_{info,err,crit} whichever is applicable.

Cc: Brian Norris <computersforpeace at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>

Brian Norris (1):
  mtd: mtd_oobtest: printk -> pr_{info,err,crit}

Vikram Narayanan (8):
  mtd_tests/mtd_nandbiterrs: Replace msg macro with pr_{info,err}
  mtd_tests/mtd_nandecctest: Use pr_fmt macro
  mtd_tests/mtd_pagetest: Replace printk with pr_{info,crit,err}
  mtd_tests/mtd_readtest: Replace printk with pr_{info,err}
  mtd_tests/mtd_speedtest: Replace printk with pr_{info,crit,err}
  mtd_tests/mtd_stresstest: Replace printk with pr_{info,crit,err}
  mtd_tests/mtd_subpagetest: Replace printk with pr_{info,crit,err}
  mtd_tests/mtd_torturetest: Replace printk with pr_{info,crit}

 drivers/mtd/tests/mtd_nandbiterrs.c |   73 ++++++++--------
 drivers/mtd/tests/mtd_nandecctest.c |    6 +-
 drivers/mtd/tests/mtd_oobtest.c     |  171 +++++++++++++++++------------------
 drivers/mtd/tests/mtd_pagetest.c    |  152 ++++++++++++++++----------------
 drivers/mtd/tests/mtd_readtest.c    |   42 +++++-----
 drivers/mtd/tests/mtd_speedtest.c   |   88 +++++++++---------
 drivers/mtd/tests/mtd_stresstest.c  |   44 +++++-----
 drivers/mtd/tests/mtd_subpagetest.c |  124 +++++++++++++-------------
 drivers/mtd/tests/mtd_torturetest.c |   73 ++++++++--------
 9 files changed, 387 insertions(+), 386 deletions(-)

-- 
1.7.4.1



From vikram186 at gmail.com  Wed Oct 10 13:34:41 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:04:41 +0530
Subject: [PATCH RESEND 1/9] mtd_tests/mtd_nandbiterrs: Replace msg macro with
 pr_{info,err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B1B1.1000005@gmail.com>

Use pr_fmt instead of msg macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_nandbiterrs.c |   73 ++++++++++++++++++-----------------
 1 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c
index cc8d62c..207bf9a 100644
--- a/drivers/mtd/tests/mtd_nandbiterrs.c
+++ b/drivers/mtd/tests/mtd_nandbiterrs.c
@@ -39,6 +39,9 @@
  * this program; see the file COPYING. If not, write to the Free Software
  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -47,8 +50,6 @@
 #include <linux/mtd/nand.h>
 #include <linux/slab.h>
 
-#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
-
 static int dev;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -103,7 +104,7 @@ static int erase_block(void)
 	struct erase_info ei;
 	loff_t addr = eraseblock * mtd->erasesize;
 
-	msg("erase_block\n");
+	pr_info("erase_block\n");
 
 	memset(&ei, 0, sizeof(struct erase_info));
 	ei.mtd  = mtd;
@@ -112,7 +113,7 @@ static int erase_block(void)
 
 	err = mtd_erase(mtd, &ei);
 	if (err || ei.state == MTD_ERASE_FAILED) {
-		msg("error %d while erasing\n", err);
+		pr_err("error %d while erasing\n", err);
 		if (!err)
 			err = -EIO;
 		return err;
@@ -128,11 +129,11 @@ static int write_page(int log)
 	size_t written;
 
 	if (log)
-		msg("write_page\n");
+		pr_info("write_page\n");
 
 	err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);
 	if (err || written != mtd->writesize) {
-		msg("error: write failed at %#llx\n", (long long)offset);
+		pr_err("error: write failed at %#llx\n", (long long)offset);
 		if (!err)
 			err = -EIO;
 	}
@@ -147,7 +148,7 @@ static int rewrite_page(int log)
 	struct mtd_oob_ops ops;
 
 	if (log)
-		msg("rewrite page\n");
+		pr_info("rewrite page\n");
 
 	ops.mode      = MTD_OPS_RAW; /* No ECC */
 	ops.len       = mtd->writesize;
@@ -160,7 +161,7 @@ static int rewrite_page(int log)
 
 	err = mtd_write_oob(mtd, offset, &ops);
 	if (err || ops.retlen != mtd->writesize) {
-		msg("error: write_oob failed (%d)\n", err);
+		pr_err("error: write_oob failed (%d)\n", err);
 		if (!err)
 			err = -EIO;
 	}
@@ -177,7 +178,7 @@ static int read_page(int log)
 	struct mtd_ecc_stats oldstats;
 
 	if (log)
-		msg("read_page\n");
+		pr_info("read_page\n");
 
 	/* Saving last mtd stats */
 	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
@@ -187,7 +188,7 @@ static int read_page(int log)
 		err = mtd->ecc_stats.corrected - oldstats.corrected;
 
 	if (err < 0 || read != mtd->writesize) {
-		msg("error: read failed at %#llx\n", (long long)offset);
+		pr_err("error: read failed at %#llx\n", (long long)offset);
 		if (err >= 0)
 			err = -EIO;
 	}
@@ -201,11 +202,11 @@ static int verify_page(int log)
 	unsigned i, errs = 0;
 
 	if (log)
-		msg("verify_page\n");
+		pr_info("verify_page\n");
 
 	for (i = 0; i < mtd->writesize; i++) {
 		if (rbuffer[i] != hash(i+seed)) {
-			msg("Error: page offset %u, expected %02x, got %02x\n",
+			pr_err("Error: page offset %u, expected %02x, got %02x\n",
 				i, hash(i+seed), rbuffer[i]);
 			errs++;
 		}
@@ -230,13 +231,13 @@ static int insert_biterror(unsigned byte)
 		for (bit = 7; bit >= 0; bit--) {
 			if (CBIT(wbuffer[byte], bit)) {
 				BCLR(wbuffer[byte], bit);
-				msg("Inserted biterror @ %u/%u\n", byte, bit);
+				pr_info("Inserted biterror @ %u/%u\n", byte, bit);
 				return 0;
 			}
 		}
 		byte++;
 	}
-	msg("biterror: Failed to find a '1' bit\n");
+	pr_err("biterror: Failed to find a '1' bit\n");
 	return -EIO;
 }
 
@@ -248,7 +249,7 @@ static int incremental_errors_test(void)
 	unsigned i;
 	unsigned errs_per_subpage = 0;
 
-	msg("incremental biterrors test\n");
+	pr_info("incremental biterrors test\n");
 
 	for (i = 0; i < mtd->writesize; i++)
 		wbuffer[i] = hash(i+seed);
@@ -265,9 +266,9 @@ static int incremental_errors_test(void)
 
 		err = read_page(1);
 		if (err > 0)
-			msg("Read reported %d corrected bit errors\n", err);
+			pr_info("Read reported %d corrected bit errors\n", err);
 		if (err < 0) {
-			msg("After %d biterrors per subpage, read reported error %d\n",
+			pr_err("After %d biterrors per subpage, read reported error %d\n",
 				errs_per_subpage, err);
 			err = 0;
 			goto exit;
@@ -275,11 +276,11 @@ static int incremental_errors_test(void)
 
 		err = verify_page(1);
 		if (err) {
-			msg("ECC failure, read data is incorrect despite read success\n");
+			pr_err("ECC failure, read data is incorrect despite read success\n");
 			goto exit;
 		}
 
-		msg("Successfully corrected %d bit errors per subpage\n",
+		pr_info("Successfully corrected %d bit errors per subpage\n",
 			errs_per_subpage);
 
 		for (i = 0; i < subcount; i++) {
@@ -311,7 +312,7 @@ static int overwrite_test(void)
 
 	memset(bitstats, 0, sizeof(bitstats));
 
-	msg("overwrite biterrors test\n");
+	pr_info("overwrite biterrors test\n");
 
 	for (i = 0; i < mtd->writesize; i++)
 		wbuffer[i] = hash(i+seed);
@@ -329,18 +330,18 @@ static int overwrite_test(void)
 		err = read_page(0);
 		if (err >= 0) {
 			if (err >= MAXBITS) {
-				msg("Implausible number of bit errors corrected\n");
+				pr_info("Implausible number of bit errors corrected\n");
 				err = -EIO;
 				break;
 			}
 			bitstats[err]++;
 			if (err > max_corrected) {
 				max_corrected = err;
-				msg("Read reported %d corrected bit errors\n",
+				pr_info("Read reported %d corrected bit errors\n",
 					err);
 			}
 		} else { /* err < 0 */
-			msg("Read reported error %d\n", err);
+			pr_info("Read reported error %d\n", err);
 			err = 0;
 			break;
 		}
@@ -348,7 +349,7 @@ static int overwrite_test(void)
 		err = verify_page(0);
 		if (err) {
 			bitstats[max_corrected] = opno;
-			msg("ECC failure, read data is incorrect despite read success\n");
+			pr_info("ECC failure, read data is incorrect despite read success\n");
 			break;
 		}
 
@@ -357,9 +358,9 @@ static int overwrite_test(void)
 
 	/* At this point bitstats[0] contains the number of ops with no bit
 	 * errors, bitstats[1] the number of ops with 1 bit error, etc. */
-	msg("Bit error histogram (%d operations total):\n", opno);
+	pr_info("Bit error histogram (%d operations total):\n", opno);
 	for (i = 0; i < max_corrected; i++)
-		msg("Page reads with %3d corrected bit errors: %d\n",
+		pr_info("Page reads with %3d corrected bit errors: %d\n",
 			i, bitstats[i]);
 
 exit:
@@ -370,36 +371,36 @@ static int __init mtd_nandbiterrs_init(void)
 {
 	int err = 0;
 
-	msg("\n");
-	msg("==================================================\n");
-	msg("MTD device: %d\n", dev);
+	printk("\n");
+	printk(KERN_INFO "==================================================\n");
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		msg("error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		goto exit_mtddev;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		msg("this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		err = -ENODEV;
 		goto exit_nand;
 	}
 
-	msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
+	pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
 		(unsigned long long)mtd->size, mtd->erasesize,
 		mtd->writesize, mtd->oobsize);
 
 	subsize  = mtd->writesize >> mtd->subpage_sft;
 	subcount = mtd->writesize / subsize;
 
-	msg("Device uses %d subpages of %d bytes\n", subcount, subsize);
+	pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);
 
 	offset     = page_offset * mtd->writesize;
 	eraseblock = mtd_div_by_eb(offset, mtd);
 
-	msg("Using page=%u, offset=%llu, eraseblock=%u\n",
+	pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",
 		page_offset, offset, eraseblock);
 
 	wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
@@ -432,8 +433,8 @@ static int __init mtd_nandbiterrs_init(void)
 		goto exit_error;
 
 	err = -EIO;
-	msg("finished successfully.\n");
-	msg("==================================================\n");
+	pr_info("finished successfully.\n");
+	printk(KERN_INFO "==================================================\n");
 
 exit_error:
 	kfree(rbuffer);
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:37:19 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:07:19 +0530
Subject: [PATCH RESEND 2/9] mtd_tests/mtd_nandecctest: Use pr_fmt macro
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B24F.4050606@gmail.com>

Use KBUILD_MODNAME instead of hardcoding the filename

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_nandecctest.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index b437fa4..1eee264 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/list.h>
@@ -264,13 +266,13 @@ static int nand_ecc_test_run(const size_t size)
 						correct_data, size);
 
 		if (err) {
-			pr_err("mtd_nandecctest: not ok - %s-%zd\n",
+			pr_err("not ok - %s-%zd\n",
 				nand_ecc_test[i].name, size);
 			dump_data_ecc(error_data, error_ecc,
 				correct_data, correct_ecc, size);
 			break;
 		}
-		pr_info("mtd_nandecctest: ok - %s-%zd\n",
+		pr_info("ok - %s-%zd\n",
 			nand_ecc_test[i].name, size);
 	}
 error:
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:37:40 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:07:40 +0530
Subject: [PATCH RESEND 3/9] mtd_tests/mtd_pagetest: Replace printk with
 pr_{info, crit, err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B264.4000009@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_pagetest.c |  152 +++++++++++++++++++-------------------
 1 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c
index 252ddb0..3ba2a77 100644
--- a/drivers/mtd/tests/mtd_pagetest.c
+++ b/drivers/mtd/tests/mtd_pagetest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -28,8 +30,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_pagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -79,12 +79,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
+		pr_err("some erase error occurred at EB %d\n",
 		       ebnum);
 		return -EIO;
 	}
@@ -102,7 +102,7 @@ static int write_eraseblock(int ebnum)
 	cond_resched();
 	err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
 	if (err || written != mtd->erasesize)
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_err("error: write failed at %#llx\n",
 		       (long long)addr);
 
 	return err;
@@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr0);
 			return err;
 		}
@@ -139,7 +139,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)(addrn - bufsize));
 			return err;
 		}
@@ -148,12 +148,12 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr);
 			break;
 		}
 		if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -166,7 +166,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr0);
 			return err;
 		}
@@ -174,7 +174,7 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)(addrn - bufsize));
 			return err;
 		}
@@ -183,14 +183,14 @@ static int verify_eraseblock(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != bufsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err;
 		}
 		memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);
 		set_random_data(boundary + pgsize, pgsize);
 		if (memcmp(twopages, boundary, bufsize)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -206,10 +206,10 @@ static int crosstest(void)
 	loff_t addr, addr0, addrn;
 	unsigned char *pp1, *pp2, *pp3, *pp4;
 
-	printk(PRINT_PREF "crosstest\n");
+	pr_info("crosstest\n");
 	pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
 	if (!pp1) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 	pp2 = pp1 + pgsize;
@@ -231,7 +231,7 @@ static int crosstest(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -243,7 +243,7 @@ static int crosstest(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -251,12 +251,12 @@ static int crosstest(void)
 
 	/* Read first page to pp2 */
 	addr = addr0;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp2);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -264,12 +264,12 @@ static int crosstest(void)
 
 	/* Read last page to pp3 */
 	addr = addrn - pgsize;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp3);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
@@ -277,25 +277,25 @@ static int crosstest(void)
 
 	/* Read first page again to pp4 */
 	addr = addr0;
-	printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
+	pr_info("reading page at %#llx\n", (long long)addr);
 	err = mtd_read(mtd, addr, pgsize, &read, pp4);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr);
 		kfree(pp1);
 		return err;
 	}
 
 	/* pp2 and pp4 should be the same */
-	printk(PRINT_PREF "verifying pages read at %#llx match\n",
+	pr_info("verifying pages read at %#llx match\n",
 	       (long long)addr0);
 	if (memcmp(pp2, pp4, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_err("verify failed!\n");
 		errcnt += 1;
 	} else if (!err)
-		printk(PRINT_PREF "crosstest ok\n");
+		pr_info("crosstest ok\n");
 	kfree(pp1);
 	return err;
 }
@@ -307,7 +307,7 @@ static int erasecrosstest(void)
 	loff_t addr0;
 	char *readbuf = twopages;
 
-	printk(PRINT_PREF "erasecrosstest\n");
+	pr_info("erasecrosstest\n");
 
 	ebnum = 0;
 	addr0 = 0;
@@ -320,79 +320,79 @@ static int erasecrosstest(void)
 	while (ebnum2 && bbt[ebnum2])
 		ebnum2 -= 1;
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_info("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	memset(readbuf, 0, pgsize);
 	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+	pr_info("verifying 1st page of block %d\n", ebnum);
 	if (memcmp(writebuf, readbuf, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_err("verify failed!\n");
 		errcnt += 1;
 		return -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_err("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum2);
+	pr_info("erasing block %d\n", ebnum2);
 	err = erase_eraseblock(ebnum2);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	memset(readbuf, 0, pgsize);
 	err = mtd_read(mtd, addr0, pgsize, &read, readbuf);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum);
+	pr_info("verifying 1st page of block %d\n", ebnum);
 	if (memcmp(writebuf, readbuf, pgsize)) {
-		printk(PRINT_PREF "verify failed!\n");
+		pr_err("verify failed!\n");
 		errcnt += 1;
 		return -1;
 	}
 
 	if (!err)
-		printk(PRINT_PREF "erasecrosstest ok\n");
+		pr_info("erasecrosstest ok\n");
 	return err;
 }
 
@@ -402,7 +402,7 @@ static int erasetest(void)
 	int err = 0, i, ebnum, ok = 1;
 	loff_t addr0;
 
-	printk(PRINT_PREF "erasetest\n");
+	pr_info("erasetest\n");
 
 	ebnum = 0;
 	addr0 = 0;
@@ -411,40 +411,40 @@ static int erasetest(void)
 		ebnum += 1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
+	pr_info("writing 1st page of block %d\n", ebnum);
 	set_random_data(writebuf, pgsize);
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_err("error: write failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "erasing block %d\n", ebnum);
+	pr_info("erasing block %d\n", ebnum);
 	err = erase_eraseblock(ebnum);
 	if (err)
 		return err;
 
-	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
+	pr_info("reading 1st page of block %d\n", ebnum);
 	err = mtd_read(mtd, addr0, pgsize, &read, twopages);
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != pgsize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n",
+		pr_err("error: read failed at %#llx\n",
 		       (long long)addr0);
 		return err ? err : -1;
 	}
 
-	printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n",
+	pr_info("verifying 1st page of block %d is all 0xff\n",
 	       ebnum);
 	for (i = 0; i < pgsize; ++i)
 		if (twopages[i] != 0xff) {
-			printk(PRINT_PREF "verifying all 0xff failed at %d\n",
+			pr_err("verifying all 0xff failed at %d\n",
 			       i);
 			errcnt += 1;
 			ok = 0;
@@ -452,7 +452,7 @@ static int erasetest(void)
 		}
 
 	if (ok && !err)
-		printk(PRINT_PREF "erasetest ok\n");
+		pr_info("erasetest ok\n");
 
 	return err;
 }
@@ -464,7 +464,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -474,18 +474,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -499,22 +499,22 @@ static int __init mtd_pagetest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void)
 	pgcnt = mtd->erasesize / mtd->writesize;
 	pgsize = mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void)
 	bufsize = pgsize * 2;
 	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	twopages = kmalloc(bufsize, GFP_KERNEL);
 	if (!twopages) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	boundary = kmalloc(bufsize, GFP_KERNEL);
 	if (!boundary) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void)
 		goto out;
 
 	/* Erase all eraseblocks */
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void)
 			goto out;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 
 	/* Write all eraseblocks */
 	simple_srand(1);
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(1);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = crosstest();
 	if (err)
@@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 out:
 
 	kfree(bbt);
@@ -615,7 +615,7 @@ out:
 	kfree(writebuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:38:01 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:08:01 +0530
Subject: [PATCH RESEND 4/9] mtd_tests/mtd_readtest: Replace printk with
 pr_{info, err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B279.40407@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_readtest.c |   42 +++++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 121aba1..ec3efb5 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,8 +29,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_readtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -56,7 +56,7 @@ static int read_eraseblock_by_page(int ebnum)
 		if (ret == -EUCLEAN)
 			ret = 0;
 		if (ret || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr);
 			if (!err)
 				err = ret;
@@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum)
 			ret = mtd_read_oob(mtd, addr, &ops);
 			if ((ret && !mtd_is_bitflip(ret)) ||
 					ops.oobretlen != mtd->oobsize) {
-				printk(PRINT_PREF "error: read oob failed at "
+				pr_err("error: read oob failed at "
 						  "%#llx\n", (long long)addr);
 				if (!err)
 					err = ret;
@@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum)
 	char line[128];
 	int pg, oob;
 
-	printk(PRINT_PREF "dumping eraseblock %d\n", ebnum);
+	pr_info("dumping eraseblock %d\n", ebnum);
 	n = mtd->erasesize;
 	for (i = 0; i < n;) {
 		char *p = line;
@@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum)
 	}
 	if (!mtd->oobsize)
 		return;
-	printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum);
+	pr_info("dumping oob from eraseblock %d\n", ebnum);
 	n = mtd->oobsize;
 	for (pg = 0, i = 0; pg < pgcnt; pg++)
 		for (oob = 0; oob < n;) {
@@ -134,7 +134,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		return 0;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: Cannot get MTD device\n");
+		pr_err("error: Cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void)
 	err = -ENOMEM;
 	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf1) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void)
 		goto out;
 
 	/* Read all eraseblocks 1 page at a time */
-	printk(PRINT_PREF "testing page read\n");
+	pr_info("testing page read\n");
 	for (i = 0; i < ebcnt; ++i) {
 		int ret;
 
@@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void)
 	}
 
 	if (err)
-		printk(PRINT_PREF "finished with errors\n");
+		pr_info("finished with errors\n");
 	else
-		printk(PRINT_PREF "finished\n");
+		pr_info("finished\n");
 
 out:
 
@@ -246,7 +246,7 @@ out:
 	kfree(bbt);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From ckhardin at exablox.com  Wed Oct 10 13:31:08 2012
From: ckhardin at exablox.com (Charles Hardin)
Date: Wed, 10 Oct 2012 10:31:08 -0700
Subject: [QUESTION] MLC NAND and ECC over OOB area
Message-ID: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>

All,

So, in working with the latest linux MTD driver updates to support BCH ECC and other requirements for MLC NAND parts, I noticed something that was a bit odd from the data sheets and a few conversations with some Flash Hardware engineers that bit errors are expected in the OOB area as well.

For instance, on a MT29F16G08CBACA - the error correction is stated in the data sheet to be 24-bit over 1080 bytes (which I thought was a typo and should have been 1024).

This makes sense once you get the stats of the NAND part that is 

Page Size: 4096
OOB: 224
Total: 4096 + 224 = 4320
From the data sheet: 1080 * 4 = 4320

After testing the NAND I did find bit errors in the OOB (the bad block marker pattern in particular) so ECC is required over the "mtd->writesize + mtd->oobsize".

This is not supported in the latest mtd drivers in the 3.6 or 3.5 because of some assumptions in nand_base.c like?

int nand_scan_tail(struct mtd_info *mtd)
{
	? snip snip snip ?

        /*
         * Set the number of read / write steps for one page depending on ECC
         * mode.
         */
        chip->ecc.steps = mtd->writesize / chip->ecc.size;
        if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
                pr_warn("Invalid ECC parameters\n");
                BUG();
        }
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;

	? snip snip snip ?
}

This assumption that the ecc is only over the "write size" might permeate more of the code, so I really have two questions
- Is anyone already working on handling ECC including the OOB as well?
- Is the expectation that this is going to have to be flagged as specific to MLC or a generic relayout of the ECC when using BCH over the entire data set instead of the write payload alone?

Regards,
Charles Hardin

--
This email is probably not that important



From vikram186 at gmail.com  Wed Oct 10 13:40:02 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:10:02 +0530
Subject: [PATCH RESEND 5/9] mtd_tests/mtd_speedtest: Replace printk with
 pr_{info, crit, err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B2F2.2000008@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_speedtest.c |   88 ++++++++++++++++++------------------
 1 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 42b0f74..8a5803b 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -28,8 +30,6 @@
 #include <linux/sched.h>
 #include <linux/random.h>
 
-#define PRINT_PREF KERN_INFO "mtd_speedtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -70,12 +70,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
+		pr_err("some erase error occurred at EB %d\n",
 		       ebnum);
 		return -EIO;
 	}
@@ -96,13 +96,13 @@ static int multiblock_erase(int ebnum, int blocks)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n",
+		pr_err("error %d while erasing EB %d, blocks %d\n",
 		       err, ebnum, blocks);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d,"
+		pr_err("some erase error occurred at EB %d,"
 		       "blocks %d\n", ebnum, blocks);
 		return -EIO;
 	}
@@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum)
 
 	err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf);
 	if (err || written != mtd->erasesize) {
-		printk(PRINT_PREF "error: write failed at %#llx\n", addr);
+		pr_err("error: write failed at %#llx\n", addr);
 		if (!err)
 			err = -EINVAL;
 	}
@@ -152,7 +152,7 @@ static int write_eraseblock_by_page(int ebnum)
 	for (i = 0; i < pgcnt; i++) {
 		err = mtd_write(mtd, addr, pgsize, &written, buf);
 		if (err || written != pgsize) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_err("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -175,7 +175,7 @@ static int write_eraseblock_by_2pages(int ebnum)
 	for (i = 0; i < n; i++) {
 		err = mtd_write(mtd, addr, sz, &written, buf);
 		if (err || written != sz) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_err("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -187,7 +187,7 @@ static int write_eraseblock_by_2pages(int ebnum)
 	if (pgcnt % 2) {
 		err = mtd_write(mtd, addr, pgsize, &written, buf);
 		if (err || written != pgsize) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_err("error: write failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -208,7 +208,7 @@ static int read_eraseblock(int ebnum)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (err || read != mtd->erasesize) {
-		printk(PRINT_PREF "error: read failed at %#llx\n", addr);
+		pr_err("error: read failed at %#llx\n", addr);
 		if (!err)
 			err = -EINVAL;
 	}
@@ -229,7 +229,7 @@ static int read_eraseblock_by_page(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -255,7 +255,7 @@ static int read_eraseblock_by_2pages(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != sz) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -270,7 +270,7 @@ static int read_eraseblock_by_2pages(int ebnum)
 		if (mtd_is_bitflip(err))
 			err = 0;
 		if (err || read != pgsize) {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       addr);
 			if (!err)
 				err = -EINVAL;
@@ -287,7 +287,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -321,21 +321,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		goto out;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 out:
 	goodebcnt = ebcnt - bad;
 	return 0;
@@ -351,25 +351,25 @@ static int __init mtd_speedtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
 	if (count)
-		printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count);
+		pr_info("MTD device: %d    count: %d\n", dev, count);
 	else
-		printk(PRINT_PREF "MTD device: %d\n", dev);
+		pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -380,7 +380,7 @@ static int __init mtd_speedtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -392,7 +392,7 @@ static int __init mtd_speedtest_init(void)
 	err = -ENOMEM;
 	iobuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!iobuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -407,7 +407,7 @@ static int __init mtd_speedtest_init(void)
 		goto out;
 
 	/* Write all eraseblocks, 1 eraseblock at a time */
-	printk(PRINT_PREF "testing eraseblock write speed\n");
+	pr_info("testing eraseblock write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -419,10 +419,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed);
+	pr_info("eraseblock write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 1 eraseblock at a time */
-	printk(PRINT_PREF "testing eraseblock read speed\n");
+	pr_info("testing eraseblock read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -434,14 +434,14 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed);
+	pr_info("eraseblock read speed is %ld KiB/s\n", speed);
 
 	err = erase_whole_device();
 	if (err)
 		goto out;
 
 	/* Write all eraseblocks, 1 page at a time */
-	printk(PRINT_PREF "testing page write speed\n");
+	pr_info("testing page write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -453,10 +453,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed);
+	pr_info("page write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 1 page at a time */
-	printk(PRINT_PREF "testing page read speed\n");
+	pr_info("testing page read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -468,14 +468,14 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed);
+	pr_info("page read speed is %ld KiB/s\n", speed);
 
 	err = erase_whole_device();
 	if (err)
 		goto out;
 
 	/* Write all eraseblocks, 2 pages at a time */
-	printk(PRINT_PREF "testing 2 page write speed\n");
+	pr_info("testing 2 page write speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -487,10 +487,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed);
+	pr_info("2 page write speed is %ld KiB/s\n", speed);
 
 	/* Read all eraseblocks, 2 pages at a time */
-	printk(PRINT_PREF "testing 2 page read speed\n");
+	pr_info("testing 2 page read speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -502,10 +502,10 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed);
+	pr_info("2 page read speed is %ld KiB/s\n", speed);
 
 	/* Erase all eraseblocks */
-	printk(PRINT_PREF "Testing erase speed\n");
+	pr_info("Testing erase speed\n");
 	start_timing();
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -517,12 +517,12 @@ static int __init mtd_speedtest_init(void)
 	}
 	stop_timing();
 	speed = calc_speed();
-	printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed);
+	pr_info("erase speed is %ld KiB/s\n", speed);
 
 	/* Multi-block erase all eraseblocks */
 	for (k = 1; k < 7; k++) {
 		blocks = 1 << k;
-		printk(PRINT_PREF "Testing %dx multi-block erase speed\n",
+		pr_info("Testing %dx multi-block erase speed\n",
 		       blocks);
 		start_timing();
 		for (i = 0; i < ebcnt; ) {
@@ -541,16 +541,16 @@ static int __init mtd_speedtest_init(void)
 		}
 		stop_timing();
 		speed = calc_speed();
-		printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n",
+		pr_info("%dx multi-block erase speed is %ld KiB/s\n",
 		       blocks, speed);
 	}
-	printk(PRINT_PREF "finished\n");
+	pr_info("finished\n");
 out:
 	kfree(iobuf);
 	kfree(bbt);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:40:22 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:10:22 +0530
Subject: [PATCH RESEND 6/9] mtd_tests/mtd_stresstest: Replace printk with
 pr_{info,crit,err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B306.4040102@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_stresstest.c |   44 ++++++++++++++++++------------------
 1 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index cb268ce..fea1dd7 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -29,8 +31,6 @@
 #include <linux/vmalloc.h>
 #include <linux/random.h>
 
-#define PRINT_PREF KERN_INFO "mtd_stresstest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -94,12 +94,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (unlikely(err)) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (unlikely(ei.state == MTD_ERASE_FAILED)) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
+		pr_err("some erase error occurred at EB %d\n",
 		       ebnum);
 		return -EIO;
 	}
@@ -114,7 +114,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -137,7 +137,7 @@ static int do_read(void)
 	if (mtd_is_bitflip(err))
 		err = 0;
 	if (unlikely(err || read != len)) {
-		printk(PRINT_PREF "error: read failed at 0x%llx\n",
+		pr_err("error: read failed at 0x%llx\n",
 		       (long long)addr);
 		if (!err)
 			err = -EINVAL;
@@ -174,7 +174,7 @@ static int do_write(void)
 	addr = eb * mtd->erasesize + offs;
 	err = mtd_write(mtd, addr, len, &written, writebuf);
 	if (unlikely(err || written != len)) {
-		printk(PRINT_PREF "error: write failed at 0x%llx\n",
+		pr_err("error: write failed at 0x%llx\n",
 		       (long long)addr);
 		if (!err)
 			err = -EINVAL;
@@ -203,21 +203,21 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
 	if (!mtd_can_have_bb(mtd))
 		return 0;
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -231,22 +231,22 @@ static int __init mtd_stresstest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
@@ -257,14 +257,14 @@ static int __init mtd_stresstest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / pgsize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
 	       pgsize, ebcnt, pgcnt, mtd->oobsize);
 
 	if (ebcnt < 2) {
-		printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
+		pr_err("error: need at least 2 eraseblocks\n");
 		err = -ENOSPC;
 		goto out_put_mtd;
 	}
@@ -277,7 +277,7 @@ static int __init mtd_stresstest_init(void)
 	writebuf = vmalloc(bufsize);
 	offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL);
 	if (!readbuf || !writebuf || !offsets) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	for (i = 0; i < ebcnt; i++)
@@ -290,16 +290,16 @@ static int __init mtd_stresstest_init(void)
 		goto out;
 
 	/* Do operations */
-	printk(PRINT_PREF "doing operations\n");
+	pr_info("doing operations\n");
 	for (op = 0; op < count; op++) {
 		if ((op & 1023) == 0)
-			printk(PRINT_PREF "%d operations done\n", op);
+			pr_info("%d operations done\n", op);
 		err = do_operation();
 		if (err)
 			goto out;
 		cond_resched();
 	}
-	printk(PRINT_PREF "finished, %d operations done\n", op);
+	pr_info("finished, %d operations done\n", op);
 
 out:
 	kfree(offsets);
@@ -309,7 +309,7 @@ out:
 out_put_mtd:
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:41:06 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:11:06 +0530
Subject: [PATCH RESEND 7/9] mtd_tests/mtd_subpagetest: Replace printk with
 pr_{info,crit,err}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B332.8030304@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_subpagetest.c |  124 +++++++++++++++++-----------------
 1 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c
index 9667bf5..8813b0e 100644
--- a/drivers/mtd/tests/mtd_subpagetest.c
+++ b/drivers/mtd/tests/mtd_subpagetest.c
@@ -19,6 +19,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,8 +29,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_subpagetest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -82,12 +82,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
+		pr_err("some erase error occurred at EB %d\n",
 		       ebnum);
 		return -EIO;
 	}
@@ -100,7 +100,7 @@ static int erase_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -109,7 +109,7 @@ static int erase_whole_device(void)
 			return err;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -122,11 +122,11 @@ static int write_eraseblock(int ebnum)
 	set_random_data(writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_err("error: write failed at %#llx\n",
 		       (long long)addr);
 		if (written != subpgsize) {
-			printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-			printk(PRINT_PREF "  written: %#zx\n", written);
+			pr_err("  write size: %#x\n", subpgsize);
+			pr_err("  written: %#zx\n", written);
 		}
 		return err ? err : -1;
 	}
@@ -136,11 +136,11 @@ static int write_eraseblock(int ebnum)
 	set_random_data(writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
-		printk(PRINT_PREF "error: write failed at %#llx\n",
+		pr_err("error: write failed at %#llx\n",
 		       (long long)addr);
 		if (written != subpgsize) {
-			printk(PRINT_PREF "  write size: %#x\n", subpgsize);
-			printk(PRINT_PREF "  written: %#zx\n", written);
+			pr_err("  write size: %#x\n", subpgsize);
+			pr_err("  written: %#zx\n", written);
 		}
 		return err ? err : -1;
 	}
@@ -160,12 +160,12 @@ static int write_eraseblock2(int ebnum)
 		set_random_data(writebuf, subpgsize * k);
 		err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
 		if (unlikely(err || written != subpgsize * k)) {
-			printk(PRINT_PREF "error: write failed at %#llx\n",
+			pr_err("error: write failed at %#llx\n",
 			       (long long)addr);
 			if (written != subpgsize) {
-				printk(PRINT_PREF "  write size: %#x\n",
+				pr_err("  write size: %#x\n",
 				       subpgsize * k);
-				printk(PRINT_PREF "  written: %#08zx\n",
+				pr_err("  written: %#08zx\n",
 				       written);
 			}
 			return err ? err : -1;
@@ -198,23 +198,23 @@ static int verify_eraseblock(int ebnum)
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
 		if (mtd_is_bitflip(err) && read == subpgsize) {
-			printk(PRINT_PREF "ECC correction at %#llx\n",
+			pr_info("ECC correction at %#llx\n",
 			       (long long)addr);
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err ? err : -1;
 		}
 	}
 	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_err("error: verify failed at %#llx\n",
 		       (long long)addr);
-		printk(PRINT_PREF "------------- written----------------\n");
+		pr_info("------------- written----------------\n");
 		print_subpage(writebuf);
-		printk(PRINT_PREF "------------- read ------------------\n");
+		pr_info("------------- read ------------------\n");
 		print_subpage(readbuf);
-		printk(PRINT_PREF "-------------------------------------\n");
+		pr_info("-------------------------------------\n");
 		errcnt += 1;
 	}
 
@@ -225,23 +225,23 @@ static int verify_eraseblock(int ebnum)
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
 		if (mtd_is_bitflip(err) && read == subpgsize) {
-			printk(PRINT_PREF "ECC correction at %#llx\n",
+			pr_info("ECC correction at %#llx\n",
 			       (long long)addr);
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read failed at %#llx\n",
+			pr_err("error: read failed at %#llx\n",
 			       (long long)addr);
 			return err ? err : -1;
 		}
 	}
 	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_info("error: verify failed at %#llx\n",
 		       (long long)addr);
-		printk(PRINT_PREF "------------- written----------------\n");
+		pr_info("------------- written----------------\n");
 		print_subpage(writebuf);
-		printk(PRINT_PREF "------------- read ------------------\n");
+		pr_info("------------- read ------------------\n");
 		print_subpage(readbuf);
-		printk(PRINT_PREF "-------------------------------------\n");
+		pr_info("-------------------------------------\n");
 		errcnt += 1;
 	}
 
@@ -262,17 +262,17 @@ static int verify_eraseblock2(int ebnum)
 		err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
 		if (unlikely(err || read != subpgsize * k)) {
 			if (mtd_is_bitflip(err) && read == subpgsize * k) {
-				printk(PRINT_PREF "ECC correction at %#llx\n",
+				pr_info("ECC correction at %#llx\n",
 				       (long long)addr);
 				err = 0;
 			} else {
-				printk(PRINT_PREF "error: read failed at "
+				pr_err("error: read failed at "
 				       "%#llx\n", (long long)addr);
 				return err ? err : -1;
 			}
 		}
 		if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
@@ -295,17 +295,17 @@ static int verify_eraseblock_ff(int ebnum)
 		err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 		if (unlikely(err || read != subpgsize)) {
 			if (mtd_is_bitflip(err) && read == subpgsize) {
-				printk(PRINT_PREF "ECC correction at %#llx\n",
+				pr_info("ECC correction at %#llx\n",
 				       (long long)addr);
 				err = 0;
 			} else {
-				printk(PRINT_PREF "error: read failed at "
+				pr_err("error: read failed at "
 				       "%#llx\n", (long long)addr);
 				return err ? err : -1;
 			}
 		}
 		if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
-			printk(PRINT_PREF "error: verify 0xff failed at "
+			pr_err("error: verify 0xff failed at "
 			       "%#llx\n", (long long)addr);
 			errcnt += 1;
 		}
@@ -320,7 +320,7 @@ static int verify_all_eraseblocks_ff(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "verifying all eraseblocks for 0xff\n");
+	pr_info("verifying all eraseblocks for 0xff\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -328,10 +328,10 @@ static int verify_all_eraseblocks_ff(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -342,7 +342,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -352,18 +352,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kzalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -377,22 +377,22 @@ static int __init mtd_subpagetest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -402,7 +402,7 @@ static int __init mtd_subpagetest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, subpage size %u, count of eraseblocks %u, "
 	       "pages per eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -412,12 +412,12 @@ static int __init mtd_subpagetest_init(void)
 	bufsize = subpgsize * 32;
 	writebuf = kmalloc(bufsize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 	readbuf = kmalloc(bufsize, GFP_KERNEL);
 	if (!readbuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_info("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -429,7 +429,7 @@ static int __init mtd_subpagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	simple_srand(1);
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -438,13 +438,13 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	simple_srand(1);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -452,10 +452,10 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = erase_whole_device();
 	if (err)
@@ -467,7 +467,7 @@ static int __init mtd_subpagetest_init(void)
 
 	/* Write all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "writing whole device\n");
+	pr_info("writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -475,14 +475,14 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -490,10 +490,10 @@ static int __init mtd_subpagetest_init(void)
 		if (unlikely(err))
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	err = erase_whole_device();
 	if (err)
@@ -503,7 +503,7 @@ static int __init mtd_subpagetest_init(void)
 	if (err)
 		goto out;
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 
 out:
 	kfree(bbt);
@@ -511,7 +511,7 @@ out:
 	kfree(writebuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:41:37 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:11:37 +0530
Subject: [PATCH RESEND 8/9] mtd_tests/mtd_torturetest: Replace printk with
 pr_{info,crit}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B351.4050309@gmail.com>

Use pr_fmt instead of PRINT_PREF macro

Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_torturetest.c |   73 ++++++++++++++++++-----------------
 1 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c
index b65861b..98d2a82 100644
--- a/drivers/mtd/tests/mtd_torturetest.c
+++ b/drivers/mtd/tests/mtd_torturetest.c
@@ -23,6 +23,8 @@
  * damage caused by this program.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -31,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_torturetest: "
 #define RETRIES 3
 
 static int eb = 8;
@@ -107,12 +108,12 @@ static inline int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
+		pr_err("some erase error occurred at EB %d\n",
 		       ebnum);
 		return -EIO;
 	}
@@ -139,40 +140,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
 retry:
 	err = mtd_read(mtd, addr, len, &read, check_buf);
 	if (mtd_is_bitflip(err))
-		printk(PRINT_PREF "single bit flip occurred at EB %d "
+		pr_err("single bit flip occurred at EB %d "
 		       "MTD reported that it was fixed.\n", ebnum);
 	else if (err) {
-		printk(PRINT_PREF "error %d while reading EB %d, "
+		pr_err("error %d while reading EB %d, "
 		       "read %zd\n", err, ebnum, read);
 		return err;
 	}
 
 	if (read != len) {
-		printk(PRINT_PREF "failed to read %zd bytes from EB %d, "
+		pr_err("failed to read %zd bytes from EB %d, "
 		       "read only %zd, but no error reported\n",
 		       len, ebnum, read);
 		return -EIO;
 	}
 
 	if (memcmp(buf, check_buf, len)) {
-		printk(PRINT_PREF "read wrong data from EB %d\n", ebnum);
+		pr_err("read wrong data from EB %d\n", ebnum);
 		report_corrupt(check_buf, buf);
 
 		if (retries++ < RETRIES) {
 			/* Try read again */
 			yield();
-			printk(PRINT_PREF "re-try reading data from EB %d\n",
+			pr_info("re-try reading data from EB %d\n",
 			       ebnum);
 			goto retry;
 		} else {
-			printk(PRINT_PREF "retried %d times, still errors, "
+			pr_info("retried %d times, still errors, "
 			       "give-up\n", RETRIES);
 			return -EINVAL;
 		}
 	}
 
 	if (retries != 0)
-		printk(PRINT_PREF "only attempt number %d was OK (!!!)\n",
+		pr_info("only attempt number %d was OK (!!!)\n",
 		       retries);
 
 	return 0;
@@ -191,12 +192,12 @@ static inline int write_pattern(int ebnum, void *buf)
 	}
 	err = mtd_write(mtd, addr, len, &written, buf);
 	if (err) {
-		printk(PRINT_PREF "error %d while writing EB %d, written %zd"
+		pr_err("error %d while writing EB %d, written %zd"
 		      " bytes\n", err, ebnum, written);
 		return err;
 	}
 	if (written != len) {
-		printk(PRINT_PREF "written only %zd bytes of %zd, but no error"
+		pr_info("written only %zd bytes of %zd, but no error"
 		       " reported\n", written, len);
 		return -EIO;
 	}
@@ -211,64 +212,64 @@ static int __init tort_init(void)
 
 	printk(KERN_INFO "\n");
 	printk(KERN_INFO "=================================================\n");
-	printk(PRINT_PREF "Warning: this program is trying to wear out your "
+	pr_info("Warning: this program is trying to wear out your "
 	       "flash, stop it if this is not wanted.\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
-	printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
+	pr_info("MTD device: %d\n", dev);
+	pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n",
 	       ebcnt, eb, eb + ebcnt - 1, dev);
 	if (pgcnt)
-		printk(PRINT_PREF "torturing just %d pages per eraseblock\n",
+		pr_info("torturing just %d pages per eraseblock\n",
 			pgcnt);
-	printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled");
+	pr_info("write verify %s\n", check ? "enabled" : "disabled");
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->writesize == 1) {
-		printk(PRINT_PREF "not NAND flash, assume page size is 512 "
+		pr_info("not NAND flash, assume page size is 512 "
 		       "bytes.\n");
 		pgsize = 512;
 	} else
 		pgsize = mtd->writesize;
 
 	if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) {
-		printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt);
+		pr_err("error: invalid pgcnt value %d\n", pgcnt);
 		goto out_mtd;
 	}
 
 	err = -ENOMEM;
 	patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_5A5) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out_mtd;
 	}
 
 	patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_A5A) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out_patt_5A5;
 	}
 
 	patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!patt_FF) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out_patt_A5A;
 	}
 
 	check_buf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!check_buf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out_patt_FF;
 	}
 
@@ -295,13 +296,13 @@ static int __init tort_init(void)
 			err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize);
 
 			if (err < 0) {
-				printk(PRINT_PREF "block_isbad() returned %d "
+				pr_info("block_isbad() returned %d "
 				       "for EB %d\n", err, i);
 				goto out;
 			}
 
 			if (err) {
-				printk("EB %d is bad. Skip it.\n", i);
+				pr_err("EB %d is bad. Skip it.\n", i);
 				bad_ebs[i - eb] = 1;
 			}
 		}
@@ -329,7 +330,7 @@ static int __init tort_init(void)
 					continue;
 				err = check_eraseblock(i, patt_FF);
 				if (err) {
-					printk(PRINT_PREF "verify failed"
+					pr_info("verify failed"
 					       " for 0xFF... pattern\n");
 					goto out;
 				}
@@ -362,7 +363,7 @@ static int __init tort_init(void)
 					patt = patt_A5A;
 				err = check_eraseblock(i, patt);
 				if (err) {
-					printk(PRINT_PREF "verify failed for %s"
+					pr_info("verify failed for %s"
 					       " pattern\n",
 					       ((eb + erase_cycles) & 1) ?
 					       "0x55AA55..." : "0xAA55AA...");
@@ -380,7 +381,7 @@ static int __init tort_init(void)
 			stop_timing();
 			ms = (finish.tv_sec - start.tv_sec) * 1000 +
 			     (finish.tv_usec - start.tv_usec) / 1000;
-			printk(PRINT_PREF "%08u erase cycles done, took %lu "
+			pr_info("%08u erase cycles done, took %lu "
 			       "milliseconds (%lu seconds)\n",
 			       erase_cycles, ms, ms / 1000);
 			start_timing();
@@ -391,7 +392,7 @@ static int __init tort_init(void)
 	}
 out:
 
-	printk(PRINT_PREF "finished after %u erase cycles\n",
+	pr_info("finished after %u erase cycles\n",
 	       erase_cycles);
 	kfree(check_buf);
 out_patt_FF:
@@ -403,7 +404,7 @@ out_patt_5A5:
 out_mtd:
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred during torturing\n", err);
+		pr_info("error %d occurred during torturing\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
@@ -441,9 +442,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
 			       &bits) >= 0)
 			pages++;
 
-	printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n",
+	pr_info("verify fails on %d pages, %d bytes/%d bits\n",
 	       pages, bytes, bits);
-	printk(PRINT_PREF "The following is a list of all differences between"
+	pr_info("The following is a list of all differences between"
 	       " what was read from flash and what was expected\n");
 
 	for (i = 0; i < check_len; i += pgsize) {
@@ -457,7 +458,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written)
 		printk("-------------------------------------------------------"
 		       "----------------------------------\n");
 
-		printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify,"
+		pr_info("Page %zd has %d bytes/%d bits failing verify,"
 		       " starting at offset 0x%x\n",
 		       (mtd->erasesize - check_len + i) / pgsize,
 		       bytes, bits, first);
-- 
1.7.4.1




From vikram186 at gmail.com  Wed Oct 10 13:42:02 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Wed, 10 Oct 2012 23:12:02 +0530
Subject: [PATCH RESEND 9/9] mtd: mtd_oobtest: printk -> pr_{info,err,crit}
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <5075B36A.3050009@gmail.com>

Use pr_info() and pr_err() while defining pr_fmt(). This saves a few
characters, joins a few lines, and makes the code a little more readable
(and grep-able).

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
 drivers/mtd/tests/mtd_oobtest.c |  171 +++++++++++++++++++--------------------
 1 files changed, 84 insertions(+), 87 deletions(-)

diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index ed9b628..e86bb29 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -28,8 +30,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_oobtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -80,13 +80,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
+		pr_err("some erase error occurred at EB %d\n", ebnum);
 		return -EIO;
 	}
 
@@ -98,7 +97,7 @@ static int erase_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -107,7 +106,7 @@ static int erase_whole_device(void)
 			return err;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -141,9 +140,9 @@ static int write_eraseblock(int ebnum)
 		ops.oobbuf    = writebuf;
 		err = mtd_write_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
-			printk(PRINT_PREF "error: writeoob failed at %#llx\n",
+			pr_err("error: writeoob failed at %#llx\n",
 			       (long long)addr);
-			printk(PRINT_PREF "error: use_len %d, use_offset %d\n",
+			pr_err("error: use_len %d, use_offset %d\n",
 			       use_len, use_offset);
 			errcnt += 1;
 			return err ? err : -1;
@@ -160,7 +159,7 @@ static int write_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "writing OOBs of whole device\n");
+	pr_info("writing OOBs of whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -168,10 +167,10 @@ static int write_whole_device(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -194,17 +193,17 @@ static int verify_eraseblock(int ebnum)
 		ops.oobbuf    = readbuf;
 		err = mtd_read_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
-			printk(PRINT_PREF "error: readoob failed at %#llx\n",
+			pr_err("error: readoob failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			return err ? err : -1;
 		}
 		if (memcmp(readbuf, writebuf, use_len)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			if (errcnt > 1000) {
-				printk(PRINT_PREF "error: too many errors\n");
+				pr_err("error: too many errors\n");
 				return -1;
 			}
 		}
@@ -221,29 +220,28 @@ static int verify_eraseblock(int ebnum)
 			ops.oobbuf    = readbuf;
 			err = mtd_read_oob(mtd, addr, &ops);
 			if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
-				printk(PRINT_PREF "error: readoob failed at "
-				       "%#llx\n", (long long)addr);
+				pr_err("error: readoob failed at %#llx\n",
+						(long long)addr);
 				errcnt += 1;
 				return err ? err : -1;
 			}
 			if (memcmp(readbuf + use_offset, writebuf, use_len)) {
-				printk(PRINT_PREF "error: verify failed at "
-				       "%#llx\n", (long long)addr);
+				pr_err("error: verify failed at %#llx\n",
+						(long long)addr);
 				errcnt += 1;
 				if (errcnt > 1000) {
-					printk(PRINT_PREF "error: too many "
-					       "errors\n");
+					pr_err("error: too many errors\n");
 					return -1;
 				}
 			}
 			for (k = 0; k < use_offset; ++k)
 				if (readbuf[k] != 0xff) {
-					printk(PRINT_PREF "error: verify 0xff "
+					pr_err("error: verify 0xff "
 					       "failed at %#llx\n",
 					       (long long)addr);
 					errcnt += 1;
 					if (errcnt > 1000) {
-						printk(PRINT_PREF "error: too "
+						pr_err("error: too "
 						       "many errors\n");
 						return -1;
 					}
@@ -251,12 +249,12 @@ static int verify_eraseblock(int ebnum)
 			for (k = use_offset + use_len;
 			     k < mtd->ecclayout->oobavail; ++k)
 				if (readbuf[k] != 0xff) {
-					printk(PRINT_PREF "error: verify 0xff "
+					pr_err("error: verify 0xff "
 					       "failed at %#llx\n",
 					       (long long)addr);
 					errcnt += 1;
 					if (errcnt > 1000) {
-						printk(PRINT_PREF "error: too "
+						pr_err("error: too "
 						       "many errors\n");
 						return -1;
 					}
@@ -286,17 +284,17 @@ static int verify_eraseblock_in_one_go(int ebnum)
 	ops.oobbuf    = readbuf;
 	err = mtd_read_oob(mtd, addr, &ops);
 	if (err || ops.oobretlen != len) {
-		printk(PRINT_PREF "error: readoob failed at %#llx\n",
+		pr_err("error: readoob failed at %#llx\n",
 		       (long long)addr);
 		errcnt += 1;
 		return err ? err : -1;
 	}
 	if (memcmp(readbuf, writebuf, len)) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_err("error: verify failed at %#llx\n",
 		       (long long)addr);
 		errcnt += 1;
 		if (errcnt > 1000) {
-			printk(PRINT_PREF "error: too many errors\n");
+			pr_err("error: too many errors\n");
 			return -1;
 		}
 	}
@@ -309,7 +307,7 @@ static int verify_all_eraseblocks(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -317,10 +315,10 @@ static int verify_all_eraseblocks(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -331,7 +329,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -341,18 +339,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kmalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -368,22 +366,22 @@ static int __init mtd_oobtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -392,7 +390,7 @@ static int __init mtd_oobtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -401,12 +399,12 @@ static int __init mtd_oobtest_init(void)
 	err = -ENOMEM;
 	readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!readbuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -420,7 +418,7 @@ static int __init mtd_oobtest_init(void)
 	vary_offset = 0;
 
 	/* First test: write all OOB, read it back and verify */
-	printk(PRINT_PREF "test 1 of 5\n");
+	pr_info("test 1 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -440,7 +438,7 @@ static int __init mtd_oobtest_init(void)
 	 * Second test: write all OOB, a block at a time, read it back and
 	 * verify.
 	 */
-	printk(PRINT_PREF "test 2 of 5\n");
+	pr_info("test 2 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -453,7 +451,7 @@ static int __init mtd_oobtest_init(void)
 
 	/* Check all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -461,16 +459,16 @@ static int __init mtd_oobtest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	/*
 	 * Third test: write OOB at varying offsets and lengths, read it back
 	 * and verify.
 	 */
-	printk(PRINT_PREF "test 3 of 5\n");
+	pr_info("test 3 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -503,7 +501,7 @@ static int __init mtd_oobtest_init(void)
 	vary_offset = 0;
 
 	/* Fourth test: try to write off end of device */
-	printk(PRINT_PREF "test 4 of 5\n");
+	pr_info("test 4 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -522,14 +520,14 @@ static int __init mtd_oobtest_init(void)
 	ops.ooboffs   = mtd->ecclayout->oobavail;
 	ops.datbuf    = NULL;
 	ops.oobbuf    = writebuf;
-	printk(PRINT_PREF "attempting to start write past end of OOB\n");
-	printk(PRINT_PREF "an error is expected...\n");
+	pr_info("attempting to start write past end of OOB\n");
+	pr_info("an error is expected...\n");
 	err = mtd_write_oob(mtd, addr0, &ops);
 	if (err) {
-		printk(PRINT_PREF "error occurred as expected\n");
+		pr_info("error occurred as expected\n");
 		err = 0;
 	} else {
-		printk(PRINT_PREF "error: can write past end of OOB\n");
+		pr_err("error: can write past end of OOB\n");
 		errcnt += 1;
 	}
 
@@ -542,19 +540,19 @@ static int __init mtd_oobtest_init(void)
 	ops.ooboffs   = mtd->ecclayout->oobavail;
 	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
-	printk(PRINT_PREF "attempting to start read past end of OOB\n");
-	printk(PRINT_PREF "an error is expected...\n");
+	pr_info("attempting to start read past end of OOB\n");
+	pr_info("an error is expected...\n");
 	err = mtd_read_oob(mtd, addr0, &ops);
 	if (err) {
-		printk(PRINT_PREF "error occurred as expected\n");
+		pr_info("error occurred as expected\n");
 		err = 0;
 	} else {
-		printk(PRINT_PREF "error: can read past end of OOB\n");
+		pr_err("error: can read past end of OOB\n");
 		errcnt += 1;
 	}
 
 	if (bbt[ebcnt - 1])
-		printk(PRINT_PREF "skipping end of device tests because last "
+		pr_info("skipping end of device tests because last "
 		       "block is bad\n");
 	else {
 		/* Attempt to write off end of device */
@@ -566,14 +564,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 0;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
-		printk(PRINT_PREF "attempting to write past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to write past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: wrote past end of device\n");
+			pr_err("error: wrote past end of device\n");
 			errcnt += 1;
 		}
 
@@ -586,14 +584,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 0;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
-		printk(PRINT_PREF "attempting to read past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to read past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read past end of device\n");
+			pr_err("error: read past end of device\n");
 			errcnt += 1;
 		}
 
@@ -610,14 +608,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 1;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
-		printk(PRINT_PREF "attempting to write past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to write past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: wrote past end of device\n");
+			pr_err("error: wrote past end of device\n");
 			errcnt += 1;
 		}
 
@@ -630,20 +628,20 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 1;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
-		printk(PRINT_PREF "attempting to read past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to read past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read past end of device\n");
+			pr_err("error: read past end of device\n");
 			errcnt += 1;
 		}
 	}
 
 	/* Fifth test: write / read across block boundaries */
-	printk(PRINT_PREF "test 5 of 5\n");
+	pr_info("test 5 of 5\n");
 
 	/* Erase all eraseblocks */
 	err = erase_whole_device();
@@ -652,7 +650,7 @@ static int __init mtd_oobtest_init(void)
 
 	/* Write all eraseblocks */
 	simple_srand(11);
-	printk(PRINT_PREF "writing OOBs of whole device\n");
+	pr_info("writing OOBs of whole device\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		int cnt = 2;
 		int pg;
@@ -674,17 +672,16 @@ static int __init mtd_oobtest_init(void)
 			if (err)
 				goto out;
 			if (i % 256 == 0)
-				printk(PRINT_PREF "written up to eraseblock "
-				       "%u\n", i);
+				pr_info("written up to eraseblock %u\n", i);
 			cond_resched();
 			addr += mtd->writesize;
 		}
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(11);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		if (bbt[i] || bbt[i + 1])
 			continue;
@@ -702,28 +699,28 @@ static int __init mtd_oobtest_init(void)
 		if (err)
 			goto out;
 		if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			if (errcnt > 1000) {
-				printk(PRINT_PREF "error: too many errors\n");
+				pr_err("error: too many errors\n");
 				goto out;
 			}
 		}
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 out:
 	kfree(bbt);
 	kfree(writebuf);
 	kfree(readbuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1




From ivan.djelic at parrot.com  Wed Oct 10 14:13:07 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Wed, 10 Oct 2012 20:13:07 +0200
Subject: [QUESTION] MLC NAND and ECC over OOB area
In-Reply-To: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>
References: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>
Message-ID: <20121010181307.GB14389@parrot.com>

On Wed, Oct 10, 2012 at 06:31:08PM +0100, Charles Hardin wrote:
> All,
> 
> So, in working with the latest linux MTD driver updates to support BCH ECC and other requirements for MLC NAND parts, I noticed something that was a bit odd from the data sheets and a few conversations with some Flash Hardware engineers that bit errors are expected in the OOB area as well.
> 
> For instance, on a MT29F16G08CBACA - the error correction is stated in the data sheet to be 24-bit over 1080 bytes (which I thought was a typo and should have been 1024).
> 
> This makes sense once you get the stats of the NAND part that is 
> 
> Page Size: 4096
> OOB: 224
> Total: 4096 + 224 = 4320
> From the data sheet: 1080 * 4 = 4320
> 
> After testing the NAND I did find bit errors in the OOB (the bad block marker pattern in particular) so ECC is required over the "mtd->writesize + mtd->oobsize".
> 
> This is not supported in the latest mtd drivers in the 3.6 or 3.5 because of some assumptions in nand_base.c like?
> 
> int nand_scan_tail(struct mtd_info *mtd)
> {
> 	? snip snip snip ?
> 
>         /*
>          * Set the number of read / write steps for one page depending on ECC
>          * mode.
>          */
>         chip->ecc.steps = mtd->writesize / chip->ecc.size;
>         if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
>                 pr_warn("Invalid ECC parameters\n");
>                 BUG();
>         }
>         chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
> 
> 	? snip snip snip ?
> }
> 
> This assumption that the ecc is only over the "write size" might permeate more of the code, so I really have two questions
> - Is anyone already working on handling ECC including the OOB as well?
> - Is the expectation that this is going to have to be flagged as specific to MLC or a generic relayout of the ECC when using BCH over the entire data set instead of the write payload alone?

Hi Charles,

The OOB area is primarily used to store:
- a bad block marker
- ECC bytes

The ECC is generally designed to protect the data area, and the ECC bytes themselves (data+ECC bytes form a long codeword).
The bad block marker normally has two useful values only: 0xff or 0x00, therefore it can be successfully read even with
several bitflips, by looking at its Hamming weight (the number of 1s in the byte).

Now, if you want to store additional stuff (metadata) in the OOB area, _then_ you will need an ECC that covers data + metadata.
This is possible with some drivers; this can also be done with the software BCH library (with a patch).

But the general trend is to avoid using the OOB area for that, because you never know how much space the next NAND generation
will require for ECC, and you'll be in trouble once your metadata does not fit anymore in the remaining space.

BR,
-- 
Ivan


From srinivas.kandagatla at st.com  Wed Oct 10 14:39:59 2012
From: srinivas.kandagatla at st.com (Srinivas KANDAGATLA)
Date: Wed, 10 Oct 2012 19:39:59 +0100
Subject: [PATCH 3.6.0-] mtd/spear_smi: use module_platform_driver macro
Message-ID: <1349894399-9715-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla at st.com>

This patch removes some code duplication by using
module_platform_driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at st.com>
---
 drivers/mtd/devices/spear_smi.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index 6796036..e5f0699 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -1129,18 +1129,7 @@ static struct platform_driver spear_smi_driver = {
 	.suspend = spear_smi_suspend,
 	.resume = spear_smi_resume,
 };
-
-static int spear_smi_init(void)
-{
-	return platform_driver_register(&spear_smi_driver);
-}
-module_init(spear_smi_init);
-
-static void spear_smi_exit(void)
-{
-	platform_driver_unregister(&spear_smi_driver);
-}
-module_exit(spear_smi_exit);
+module_platform_driver(spear_smi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim at st.com>");
-- 
1.7.0.4



From nicolas.pitre at linaro.org  Wed Oct 10 16:21:53 2012
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Wed, 10 Oct 2012 16:21:53 -0400 (EDT)
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
 <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
Message-ID: <alpine.LFD.2.02.1210101559250.16518@xanadu.home>

On Wed, 10 Oct 2012, Linus Walleij wrote:

> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> 
> > change_bit routine accepts only ulong pointers as buffer, so an unaligned char
> > pointer passed to change_bit may lead to a crash.
> >
> > Fix this bug by accessing the buffer as char pointer.
> 
> Why not see if we can fix change_bit() instead?
> Since I suspect this is on ARM I bet Russell and Nico
> want to hear about this if there is a problem.
> 
> Can the ARM change_bit() not be fixed, so that
> long arguments are the only option?

No.  It is this code which is totally broken.

The change_bit() is defined to operate on long values, in the _native_ 
endian.  Now imagine what this is going to do to your data buffer if 
instead you are running on a big endian device.

And I doubt there is anything requiring atomic bit manipulation here 
either.

> >                 if (err_idx[i] < chip->ecc.size * 8) {
> > -                       change_bit(err_idx[i], (unsigned long *)dat);
> > +                       uint8_t *p = dat + err_idx[i] / 8;
> > +                       *p = *p ^ (1 << (err_idx[i] % 8));
> 
> I'm one of these people who would write >>3 and
> &7 rather than /8 or %8 but I guess we are all
> different. Atleast consider it if you stick with this...

Better yet:

		dat[err_idx[i] / 8] ^= (1 << (err_idx[i] % 8));

The /8 and %8 will be changed into >>3 and &7 by the compiler anyway, 
while the /8 and %8 form is possibly a bit less obscure.

Of course, this needs to be done over _all_ this driver, not only a few 
cases.


Nicolas


From linux at arm.linux.org.uk  Wed Oct 10 16:45:46 2012
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 10 Oct 2012 21:45:46 +0100
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
 <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
Message-ID: <20121010204546.GK4625@n2100.arm.linux.org.uk>

On Wed, Oct 10, 2012 at 07:22:04PM +0200, Linus Walleij wrote:
> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:
> 
> > change_bit routine accepts only ulong pointers as buffer, so an unaligned char
> > pointer passed to change_bit may lead to a crash.
> >
> > Fix this bug by accessing the buffer as char pointer.
> 
> Why not see if we can fix change_bit() instead?
> Since I suspect this is on ARM I bet Russell and Nico
> want to hear about this if there is a problem.

Not particularly.  There's a reason the argument to change_bit() is typed
'unsigned long' and that's not because it can take a void, char, or a
short.  It's because it _expects_ the buffer to be aligned to an
"unsigned long" quantity.

That's because on many architectures, misaligned loads and stores are
not atomic operations - and in this case, load/store exclusive will
fail when they're misalighed.

So...

-                       change_bit(err_idx[i], (unsigned long *)dat);

is highly invalid code.

> Can the ARM change_bit() not be fixed, so that
> long arguments are the only option?

Spot the intentional cast:

> > -                       change_bit(err_idx[i], (unsigned long *)dat);

which tries to work around this.  Remember my attitude towards casts:
if you're having to use a cast, you are _probably_ doing something
wrong.  In this case, it's hiding a warning which was saying that
the code is doing something wrong, and then the result blows up.
By adding that cast, the wrong wire was cut... you get to keep the
remains. ;)


From vincenzo.aliberti at gmail.com  Wed Oct 10 17:15:39 2012
From: vincenzo.aliberti at gmail.com (Vincenzo Aliberti)
Date: Wed, 10 Oct 2012 23:15:39 +0200
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <1349385434-3073-1-git-send-email-valibert@micron.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
Message-ID: <5075E57B.1090702@gmail.com>

David,
     can you pull this patch in the main line?

On 10/04/2012 11:17 PM, Vincenzo Aliberti wrote:
> Dear All,
>      continuing Micron support activity on PCM memories you can find here-below a
> patch containing MTD driver for LPDDR2-NVM memories as demoed during Q2 Linaro
> Connect in Hong Kong.
>
> Let me thank TI Panda open source team for support on platform enablement
> activity and Arnd for his first feedback on driver implementation
>
> Regards,
> 	Vincenzo
>
>
> Signed-off-by: Vincenzo Aliberti <vincenzo.aliberti at gmail.com>
> ---
>   drivers/mtd/Kconfig                 |    2 +
>   drivers/mtd/Makefile                |    2 +-
>   drivers/mtd/lpddr2_nvm/Kconfig      |    9 +
>   drivers/mtd/lpddr2_nvm/Makefile     |    5 +
>   drivers/mtd/lpddr2_nvm/lpddr2_nvm.c |  547 +++++++++++++++++++++++++++++++++++
>   include/mtd/mtd-abi.h               |    1 +
>   6 files changed, 565 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/mtd/lpddr2_nvm/Kconfig
>   create mode 100644 drivers/mtd/lpddr2_nvm/Makefile
>   create mode 100644 drivers/mtd/lpddr2_nvm/lpddr2_nvm.c
>

Thanks,
     Vincenzo


From viresh.kumar at linaro.org  Wed Oct 10 23:16:04 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Thu, 11 Oct 2012 08:46:04 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
Message-ID: <CAOh2x==Up=mOc+YA6-yKD7xpoxFyzfb-XtoQ6DENTXayTa=vtA@mail.gmail.com>

On Wed, Oct 10, 2012 at 10:37 PM, Linus Walleij
<linus.walleij at linaro.org> wrote:
> The real problem is likely the DMA driver. The stuf that get
> fed into dma.device_prep_dma_memcpy() needs to be
> converted to a scatterlist and then set up in the LLI list
> for the controller.
>
> IIRC SPEAr is using drivers/dma/dw_dmac.c so

Both dw_dmac and pl080 for different SPEAr SoC's.

> check this driver's dwc_prep_dma_memcpy().
> It does seem like it is checking whether src or
> dest is scattered in this for() loop:
>
> for (offset = 0; offset < len; offset += xfer_count << src_width) {}
>
> dma_sync_single_for_device() is translating the virtual
> address to physical for every chunk BTW.
>
> So instead of doing this copying, debug the problem, and
> see if there is a bug in that for()-loop or similar, if it needs
> to be rewritten or so.

But what's the problem you saw vipin, for which you generated this patch?


From vipin.kumar at st.com  Thu Oct 11 00:07:16 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:37:16 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAOh2x==Up=mOc+YA6-yKD7xpoxFyzfb-XtoQ6DENTXayTa=vtA@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x==Up=mOc+YA6-yKD7xpoxFyzfb-XtoQ6DENTXayTa=vtA@mail.gmail.com>
Message-ID: <507645F4.1060607@st.com>

On 10/11/2012 8:46 AM, viresh kumar wrote:
> On Wed, Oct 10, 2012 at 10:37 PM, Linus Walleij
> <linus.walleij at linaro.org>  wrote:
>> The real problem is likely the DMA driver. The stuf that get
>> fed into dma.device_prep_dma_memcpy() needs to be
>> converted to a scatterlist and then set up in the LLI list
>> for the controller.
>>
>> IIRC SPEAr is using drivers/dma/dw_dmac.c so
>
> Both dw_dmac and pl080 for different SPEAr SoC's.
>
>> check this driver's dwc_prep_dma_memcpy().
>> It does seem like it is checking whether src or
>> dest is scattered in this for() loop:
>>
>> for (offset = 0; offset<  len; offset += xfer_count<<  src_width) {}
>>
>> dma_sync_single_for_device() is translating the virtual
>> address to physical for every chunk BTW.
>>
>> So instead of doing this copying, debug the problem, and
>> see if there is a bug in that for()-loop or similar, if it needs
>> to be rewritten or so.
>
> But what's the problem you saw vipin, for which you generated this patch?
> .
>

The nand tests were failing and that was because of a user pointer being 
passed to them but it was a long time back and this patch just carried 
on in the local repo. It is only now that I am sending it

It seems may be the dma drivers also got updated so it needs another 
test cycle it. I will do the needful and re-reply back on this mail

Vipin



From vipin.kumar at st.com  Thu Oct 11 00:08:42 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:38:42 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
Message-ID: <5076464A.6070309@st.com>

On 10/10/2012 10:37 PM, Linus Walleij wrote:
> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar<vipin.kumar at st.com>  wrote:
>
>> read_buf/write_buf callbacks should be able to accept a user space memory
>> address (virtually contiguous memory) as buffer pointer.
>>
>> This patch allocates a logically contiguous memory area which is use for dma
>
> You mean PHYSICALLY contigous, don't you?
>

Yes Sorry for that :)

>> xfers during read and write accesses.
>>
>> Signed-off-by: Vipin Kumar<vipin.kumar at st.com>
>
> If you really want a physically contigous buffer you need to use
> CMA, but I don't think that is the real problem here...
>
> We're already using userspace buffers in e.g. the MMCI driver
> (drivers/mmc/host/mmci.c).
>
> The real problem is likely the DMA driver. The stuf that get
> fed into dma.device_prep_dma_memcpy() needs to be
> converted to a scatterlist and then set up in the LLI list
> for the controller.
>
> IIRC SPEAr is using drivers/dma/dw_dmac.c so
> check this driver's dwc_prep_dma_memcpy().
> It does seem like it is checking whether src or
> dest is scattered in this for() loop:
>
> for (offset = 0; offset<  len; offset += xfer_count<<  src_width) {}
>
> dma_sync_single_for_device() is translating the virtual
> address to physical for every chunk BTW.
>
> So instead of doing this copying, debug the problem, and
> see if there is a bug in that for()-loop or similar, if it needs
> to be rewritten or so.
>

I would debug again and reply to this mail soon

> Yours,
> Linus Walleij
> .
>



From viresh.kumar at linaro.org  Thu Oct 11 00:15:59 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Thu, 11 Oct 2012 09:45:59 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
Message-ID: <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>

On Wed, Oct 10, 2012 at 10:37 PM, Linus Walleij
<linus.walleij at linaro.org> wrote:
> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar <vipin.kumar at st.com> wrote:

> The real problem is likely the DMA driver. The stuf that get
> fed into dma.device_prep_dma_memcpy() needs to be
> converted to a scatterlist and then set up in the LLI list
> for the controller.
>
> IIRC SPEAr is using drivers/dma/dw_dmac.c so
> check this driver's dwc_prep_dma_memcpy().
> It does seem like it is checking whether src or
> dest is scattered in this for() loop:
>
> for (offset = 0; offset < len; offset += xfer_count << src_width) {}
>
> dma_sync_single_for_device() is translating the virtual
> address to physical for every chunk BTW.

I pray that i am wrong here, otherwise i would be thrown out from
the maintainers list for this driver :)

dma_sync_single_for_device() is not doing anything on the buffer, but
on the LLI item. Actually it is flushing LLI struct so that DMA h/w can get
the correct values.

dwc_prep_dma_memcpy() doesn't expect a virtual address, look at type
of src & dest bufs: dma_addr_t. It is responsibility of user drivers to pass
physically contiguous address to it.

--
viresh


From vipin.kumar at st.com  Thu Oct 11 00:17:03 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:47:03 +0530
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <alpine.LFD.2.02.1210101559250.16518@xanadu.home>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
 <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
 <alpine.LFD.2.02.1210101559250.16518@xanadu.home>
Message-ID: <5076483F.5000102@st.com>

On 10/11/2012 1:51 AM, Nicolas Pitre wrote:
> On Wed, 10 Oct 2012, Linus Walleij wrote:
>
>> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar<vipin.kumar at st.com>  wrote:
>>
>>> change_bit routine accepts only ulong pointers as buffer, so an unaligned char
>>> pointer passed to change_bit may lead to a crash.
>>>
>>> Fix this bug by accessing the buffer as char pointer.
>>
>> Why not see if we can fix change_bit() instead?
>> Since I suspect this is on ARM I bet Russell and Nico
>> want to hear about this if there is a problem.
>>
>> Can the ARM change_bit() not be fixed, so that
>> long arguments are the only option?
>

Hello Nicolas

> No.  It is this code which is totally broken.
>

Yes, I understand and accept the probelm. That's why the fix

> The change_bit() is defined to operate on long values, in the _native_
> endian.  Now imagine what this is going to do to your data buffer if
> instead you are running on a big endian device.
>
> And I doubt there is anything requiring atomic bit manipulation here
> either.
>

No, there is no requirement for an atomic change_bit

>>>                  if (err_idx[i]<  chip->ecc.size * 8) {
>>> -                       change_bit(err_idx[i], (unsigned long *)dat);
>>> +                       uint8_t *p = dat + err_idx[i] / 8;
>>> +                       *p = *p ^ (1<<  (err_idx[i] % 8));
>>
>> I'm one of these people who would write>>3 and
>> &7 rather than /8 or %8 but I guess we are all
>> different. Atleast consider it if you stick with this...
>
> Better yet:
>
> 		dat[err_idx[i] / 8] ^= (1<<  (err_idx[i] % 8));
>
> The /8 and %8 will be changed into>>3 and&7 by the compiler anyway,
> while the /8 and %8 form is possibly a bit less obscure.
>

Yes, that's exactly why I kept /8 and %8. I would change the code as 
suggested by you

> Of course, this needs to be done over _all_ this driver, not only a few
> cases.
>

There is only one place which needs a change_bit. I would send a v2 with 
the suggested change

Vipin

>
> Nicolas
> .
>



From vipin.kumar at st.com  Thu Oct 11 00:20:05 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:50:05 +0530
Subject: [PATCH 09/11] fsmc/nand:FIX: replace change_bit routine
In-Reply-To: <20121010204546.GK4625@n2100.arm.linux.org.uk>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <ec169eb041e87e66c06108e85ea4a67e5797cecc.1349778821.git.vipin.kumar@st.com>
 <CACRpkdaot3DKCoJOBpUcJFVrJ89xRx2T58fDe4YKY_r4NFqEag@mail.gmail.com>
 <20121010204546.GK4625@n2100.arm.linux.org.uk>
Message-ID: <507648F5.1030404@st.com>

On 10/11/2012 2:15 AM, Russell King - ARM Linux wrote:
> On Wed, Oct 10, 2012 at 07:22:04PM +0200, Linus Walleij wrote:
>> On Tue, Oct 9, 2012 at 12:44 PM, Vipin Kumar<vipin.kumar at st.com>  wrote:
>>
>>> change_bit routine accepts only ulong pointers as buffer, so an unaligned char
>>> pointer passed to change_bit may lead to a crash.
>>>
>>> Fix this bug by accessing the buffer as char pointer.
>>
>> Why not see if we can fix change_bit() instead?
>> Since I suspect this is on ARM I bet Russell and Nico
>> want to hear about this if there is a problem.
>
> Not particularly.  There's a reason the argument to change_bit() is typed
> 'unsigned long' and that's not because it can take a void, char, or a
> short.  It's because it _expects_ the buffer to be aligned to an
> "unsigned long" quantity.
>
> That's because on many architectures, misaligned loads and stores are
> not atomic operations - and in this case, load/store exclusive will
> fail when they're misalighed.
>
> So...
>
> -                       change_bit(err_idx[i], (unsigned long *)dat);
>
> is highly invalid code.
>

Thanks. Got your point

>> Can the ARM change_bit() not be fixed, so that
>> long arguments are the only option?
>
> Spot the intentional cast:
>
>>> -                       change_bit(err_idx[i], (unsigned long *)dat);
>
> which tries to work around this.  Remember my attitude towards casts:
> if you're having to use a cast, you are _probably_ doing something
> wrong.  In this case, it's hiding a warning which was saying that
> the code is doing something wrong, and then the result blows up.
> By adding that cast, the wrong wire was cut... you get to keep the
> remains. ;)
> .

I agree with you. Although I was a bit relaxed this time, I would really 
think before adding a cast explicitly just to avoid a warning

-Vipin


From vapier.adi at gmail.com  Thu Oct 11 00:21:59 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Thu, 11 Oct 2012 00:21:59 -0400
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
In-Reply-To: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>

On Mon, Oct 8, 2012 at 11:25 AM, Uwe Kleine-K?nig wrote:
> --- a/drivers/mtd/maps/uclinux.c
> +++ b/drivers/mtd/maps/uclinux.c
> @@ -23,12 +23,13 @@
>
>  /****************************************************************************/
>
> -struct map_info uclinux_ram_map = {
> -       .name = "RAM",
> -       .phys = (unsigned long)__bss_stop,
> +static struct map_info uclinux_ram_map = {
>         .size = 0,
>  };

this change will break Blackfin systems.  i mentioned last time
someone tried to make this and we talked about adding a comment to
prevent future breakage, but that seems to not have happened.

i don't think's necessary either for the larger change here.  use the logic:
    if (physaddr != -1)
        mapp->phys = physaddr;
and keep the default initialization.
-mike


From vipin.kumar at st.com  Thu Oct 11 00:24:26 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:54:26 +0530
Subject: [PATCH 02/11] fsmc/nand: Rearrange the fsmc_nand_data structure
 and update comments
In-Reply-To: <20121009115245.GL12801@game.jcrosoft.org>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2aa2a9c00bcfa62605edfab8fb4c29448612ced3.1349778820.git.vipin.kumar@st.com>
 <20121009115245.GL12801@game.jcrosoft.org>
Message-ID: <507649FA.1060308@st.com>

On 10/9/2012 5:22 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
>> Signed-off-by: Vipin Kumar<vipin.kumar at st.com>
>> ---
>>   drivers/mtd/nand/fsmc_nand.c | 51 ++++++++++++++++++++++++++------------------
>>   1 file changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
>> index e96d7d1..bd89580 100644
>> --- a/drivers/mtd/nand/fsmc_nand.c
>> +++ b/drivers/mtd/nand/fsmc_nand.c
>> @@ -278,52 +278,61 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = {
>>    * struct fsmc_nand_data - structure for FSMC NAND device state
>>    *
>>    * @pid:		Part ID on the AMBA PrimeCell format
>> - * @mtd:		MTD info for a NAND flash.
>> - * @nand:		Chip related info for a NAND flash.
>> - * @partitions:		Partition info for a NAND Flash.
>> - * @nr_partitions:	Total number of partition of a NAND flash.
>> - *
>> - * @ecc_place:		ECC placing locations in oobfree type format.
>> - * @bank:		Bank number for probed device.
>> - * @clk:		Clock structure for FSMC.
>> + * @mtd:		MTD info for a NAND flash
>> + * @nand:		Chip related info for a NAND flash
>> + * @dev:		Device structure pointer
>> + * @clk:		Clock structure for FSMC
>> + * @ecc_place:		ECC placing locations in oobfree type format
>> + * @bank:		Bank number for probed device
>>    *
>>    * @read_dma_chan:	DMA channel for read access
>>    * @write_dma_chan:	DMA channel for write access to NAND
>>    * @dma_access_complete: Completion structure
>>    *
>> - * @data_pa:		NAND Physical port for Data.
>> - * @data_va:		NAND port for Data.
>> - * @cmd_va:		NAND port for Command.
>> - * @addr_va:		NAND port for Address.
>> - * @regs_va:		FSMC regs base address.
>> + * @dev_timings:	Timings to be programmed in controller
>> + * @partitions:		Partition info for a NAND Flash
>> + * @nr_partitions:	Total number of partition of a NAND flash
>> + * @mode:		Defines the NAND device access mode
>> + *			Can be one of:
>> + *			- DMA access
>> + *			- Word access (CPU)
>> + *			- None (Use driver default ie bus width specific
>> + *			  CPU access)
>> + * @select_chip:	Select a particular bank
>> + *
>> + * @data_pa:		NAND Physical port for Data
>> + * @data_va:		NAND port for Data
>> + * @cmd_va:		NAND port for Command
>> + * @addr_va:		NAND port for Address
>> + * @regs_va:		FSMC regs base address
>>    */
>>   struct fsmc_nand_data {
>>   	u32			pid;
>>   	struct mtd_info		mtd;
>>   	struct nand_chip	nand;
>> -	struct mtd_partition	*partitions;
>> -	unsigned int		nr_partitions;
>> -
>> -	struct fsmc_eccplace	*ecc_place;
>> -	unsigned int		bank;
>>   	struct device		*dev;
>> -	enum access_mode	mode;
>>   	struct clk		*clk;
>> +	struct fsmc_eccplace	*ecc_place;
>> +	unsigned int		bank;
>>
>>   	/* DMA related objects */
>>   	struct dma_chan		*read_dma_chan;
>>   	struct dma_chan		*write_dma_chan;
>>   	struct completion	dma_access_complete;
>>
>> +	/* Recieved from plat data */
>>   	struct fsmc_nand_timings *dev_timings;
>> +	struct mtd_partition	*partitions;
>> +	unsigned int		nr_partitions;
> where do you use those execpt at probe time

Yes, I can remove it completely. Thanks for that



From vipin.kumar at st.com  Thu Oct 11 00:25:31 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 11 Oct 2012 09:55:31 +0530
Subject: [PATCH 04/11] fsmc/nand: Accept nand timing parameters via DT
In-Reply-To: <20121009115705.GN12801@game.jcrosoft.org>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <54eda40e56e8ea02ed9c5332ca6d3fb90d617cc7.1349778821.git.vipin.kumar@st.com>
 <20121009115705.GN12801@game.jcrosoft.org>
Message-ID: <50764A3B.8070406@st.com>

On 10/9/2012 5:27 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:14 Tue 09 Oct     , Vipin Kumar wrote:
>> Add support to accept nand timing parameters via device tree
>>
>> Signed-off-by: Vipin Kumar<vipin.kumar at st.com>
>> ---
>>   .../devicetree/bindings/mtd/fsmc-nand.txt          | 20 ++++++++
>>   drivers/mtd/nand/fsmc_nand.c                       | 59 ++++++++++++++--------
>>   include/linux/mtd/fsmc.h                           |  2 +-
>>   3 files changed, 59 insertions(+), 22 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> index 29d1a2f..6a7fc43 100644
>> --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt
>> @@ -13,6 +13,18 @@ Optional properties:
>>     defaults to 1 byte
>>   - nand-skip-bbtscan: Indicates the the BBT scanning should be skipped
>>
>> +- nand-timings-enabled: Indicates if the timing parameters are passed
>> +  via DT
>> +- nand-timings,tclr:
>> +- nand-timings,tar:
>> +- nand-timings,thiz:
>> +- nand-timings,thold:
>> +- nand-timings,twait:
>> +- nand-timings,tset: All these timing parameters come from the actual
>> +  nand device specification. Each of this represents a number of time
>> +  period of hclk ie a number 4 in thold with hclk = 166MHz means that
>> +  thold = (1000 / 166) * 4 ns = 24.09ns
>> +
>>   Example:
>>
>>   	fsmc: flash at d1800000 {
>> @@ -26,6 +38,14 @@ Example:
>>   		st,cle-off =<0x10000>;
>>   		maxbanks =<1>;
>>
>> +		nand-timings-enabled;
>> +		nand-timings,tclr =<1>;
>> +		nand-timings,tar =<1>;
>> +		nand-timings,thiz =<1>;
>> +		nand-timings,thold =<4>;
>> +		nand-timings,twait =<6>;
>> +		nand-timings,tset =<0>;
>> +
>>   		bank-width =<1>;
>>   		nand-skip-bbtscan;
>>
>> diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
>> index fc6a044..f3d69b3 100644
>> --- a/drivers/mtd/nand/fsmc_nand.c
>> +++ b/drivers/mtd/nand/fsmc_nand.c
>> @@ -415,27 +415,13 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank,
>>   {
>>   	uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
>>   	uint32_t tclr, tar, thiz, thold, twait, tset;
>> -	struct fsmc_nand_timings *tims;
>> -	struct fsmc_nand_timings default_timings = {
>> -		.tclr	= FSMC_TCLR_1,
>> -		.tar	= FSMC_TAR_1,
>> -		.thiz	= FSMC_THIZ_1,
>> -		.thold	= FSMC_THOLD_4,
>> -		.twait	= FSMC_TWAIT_6,
>> -		.tset	= FSMC_TSET_0,
>> -	};
>> -
>> -	if (timings)
>> -		tims = timings;
>> -	else
>> -		tims =&default_timings;
>>
>> -	tclr = (tims->tclr&  FSMC_TCLR_MASK)<<  FSMC_TCLR_SHIFT;
>> -	tar = (tims->tar&  FSMC_TAR_MASK)<<  FSMC_TAR_SHIFT;
>> -	thiz = (tims->thiz&  FSMC_THIZ_MASK)<<  FSMC_THIZ_SHIFT;
>> -	thold = (tims->thold&  FSMC_THOLD_MASK)<<  FSMC_THOLD_SHIFT;
>> -	twait = (tims->twait&  FSMC_TWAIT_MASK)<<  FSMC_TWAIT_SHIFT;
>> -	tset = (tims->tset&  FSMC_TSET_MASK)<<  FSMC_TSET_SHIFT;
>> +	tclr = (timings->tclr&  FSMC_TCLR_MASK)<<  FSMC_TCLR_SHIFT;
>> +	tar = (timings->tar&  FSMC_TAR_MASK)<<  FSMC_TAR_SHIFT;
>> +	thiz = (timings->thiz&  FSMC_THIZ_MASK)<<  FSMC_THIZ_SHIFT;
>> +	thold = (timings->thold&  FSMC_THOLD_MASK)<<  FSMC_THOLD_SHIFT;
>> +	twait = (timings->twait&  FSMC_TWAIT_MASK)<<  FSMC_TWAIT_SHIFT;
>> +	tset = (timings->tset&  FSMC_TSET_MASK)<<  FSMC_TSET_SHIFT;
>>
>>   	if (busw)
>>   		writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC));
>> @@ -876,6 +862,14 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>>   					       struct device_node *np)
>>   {
>>   	struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
>> +	struct fsmc_nand_timings default_timings = {
>> +		.tclr	= FSMC_TCLR_1,
>> +		.tar	= FSMC_TAR_1,
>> +		.thiz	= FSMC_THIZ_1,
>> +		.thold	= FSMC_THOLD_4,
>> +		.twait	= FSMC_TWAIT_6,
>> +		.tset	= FSMC_TSET_0,
>> +	};
>>   	u32 val;
>>
>>   	/* Set default NAND width to 8 bits */
>> @@ -894,6 +888,29 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev,
>>   		pdata->options = NAND_SKIP_BBTSCAN;
>>   	of_property_read_u32(np, "maxbanks",&pdata->max_banks);
>>
>> +	if (of_property_read_bool(np, "nand-timings-enabled")) {
>> +		of_property_read_u32(np, "nand-timings,tclr",&val);
>> +		pdata->nand_timings.tclr = (uint8_t)val;
> use a mask will be better

OK, will add a mask in v2

>> +
>> +		of_property_read_u32(np, "nand-timings,tar",&val);
>> +		pdata->nand_timings.tar = (uint8_t)val;
>> +
>> +		of_property_read_u32(np, "nand-timings,thiz",&val);
>> +		pdata->nand_timings.thiz = (uint8_t)val;
>> +
>> +		of_property_read_u32(np, "nand-timings,thold",&val);
>> +		pdata->nand_timings.thold = (uint8_t)val;
>> +
>> +		of_property_read_u32(np, "nand-timings,twait",&val);
>> +		pdata->nand_timings.twait = (uint8_t)val;
>> +
>> +		of_property_read_u32(np, "nand-timings,tset",&val);
>> +		pdata->nand_timings.tset = (uint8_t)val;
>> +	} else {
>> +		memcpy(&pdata->nand_timings,&default_timings,
>> +				sizeof(default_timings));
>> +	}
>> +
>>   	return 0;
>>   }
>>   #else
>> @@ -1031,7 +1048,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
>>   	host->partitions = pdata->partitions;
>>   	host->nr_partitions = pdata->nr_partitions;
>>   	host->dev =&pdev->dev;
>> -	host->dev_timings = pdata->nand_timings;
>> +	host->dev_timings =&pdata->nand_timings;
>>   	host->mode = pdata->mode;
>>   	host->max_banks = pdata->max_banks;
>>
>> diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
>> index f0ab734..4fbdce4 100644
>> --- a/include/linux/mtd/fsmc.h
>> +++ b/include/linux/mtd/fsmc.h
>> @@ -148,7 +148,7 @@ enum access_mode {
>>    * this may be set to NULL
>>    */
>>   struct fsmc_nand_platform_data {
>> -	struct fsmc_nand_timings *nand_timings;
>> +	struct fsmc_nand_timings nand_timings;
>>   	struct mtd_partition	*partitions;
>>   	unsigned int		nr_partitions;
>>   	unsigned int		options;
>> --
>> 1.7.11.4
>>
> .
>



From afzal at ti.com  Thu Oct 11 01:24:58 2012
From: afzal at ti.com (Mohammed, Afzal)
Date: Thu, 11 Oct 2012 05:24:58 +0000
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <20121010163840.GA13585@parrot.com>
References: <cover.1349672877.git.afzal@ti.com>
 <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>
 <20121010163840.GA13585@parrot.com>
Message-ID: <C8443D0743D26F4388EA172BF4E2A7A93E9FB245@DBDE01.ent.ti.com>

On Wed, Oct 10, 2012 at 22:08:41, Ivan Djelic wrote:
> On Mon, Oct 08, 2012 at 07:08:08AM +0100, Mohammed, Afzal wrote:

> > Please verify that BCH[48] works as earlier with this series.

> I ran several mtd regression tests on a Beagle Board on your gpmc-czimage-v2 tag.
> All BCH error correcting tests passed successfully.
> 
> I occasionally had weird read errors though, especially when reading blank pages:
> the omap driver returned 512-byte sectors containing something like:

> I was able to reproduce the problem also on l2-mtd tip, albeit less often.
> The problem seems to occur quite randomly, it may be a hardware issue on
> my board...
> 
> Anyway, the ECC handling part looks OK to me.

Thanks Ivan

Regards
Afzal

From avinashphilip at ti.com  Thu Oct 11 01:27:13 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Thu, 11 Oct 2012 05:27:13 +0000
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <20121010170806.GB13585@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
 <20121010170806.GB13585@parrot.com>
Message-ID: <518397C60809E147AF5323E0420B992E3E9CB751@DBDE01.ent.ti.com>

On Wed, Oct 10, 2012 at 22:38:06, Ivan Djelic wrote:
> On Tue, Oct 09, 2012 at 01:36:50PM +0100, Philip, Avinash wrote:
> (...)
> > > There are at least 2 potential problems when reading an erased page with bitflips:
> > > 
> > > 1. bitflip in data area and no bitflip in spare area (all 0xff)
> > > Your code will not perform any ECC correction.
> > > UBIFS does not like finding bitflips in empty pages, see for instance
> > > http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.
> > 
> > In case of error correction using ELM, syndrome vector calculated after reading
> > Data area & OOB area. So handling of erased page requires a software workaround.
> > I am planning something as follows.
> > 
> > I will first check calculated ecc, which would be zero for non error pages.
> > Then I would check 0xFF in OOB area (for erased page) by checking number of
> > bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
> > set entire page as 0xFF if number of bit zeros is less than max bit flips
> > (8 or 4) by counting the number of bit zero's in data area.
> > 
> > This logic is implemented in fsmc_nand.c
> > 
> > See commit
> > mtd: fsmc: Newly erased page read algorithm implemented
> > 
> > > 
> > > 2. bitflip in ECC bytes in spare area
> > > Your code will report an uncorrectable error upon reading; if this happens while reading a partially programmed UBI block,
> > > I guess you will lose data.
> > 
> > In case of uncorrectable errors due to bit flips in spare area,
> > I can go on checking number of bit zero's in data area + OOB area
> > are less than max bit flips (8 or 4), I can go on setting the entire
> > page as 0xFF.
> > 
> 
> OK, sounds reasonable.
> Another simple strategy could use the fact that you add a 14th zero byte to
> the 13 BCH bytes for RBL compatibility:

RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.

So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
we can go for same approaches in BCH4 & BCH8 ecc scheme.

If I understood correctly, software BCH ecc scheme is modifying calculated
ecc data to handle bit flips in erased pages.

If that is the only reason, whether same logic can go for same ECC calculation
(remove modification of calculated ecc in case of software ecc correction)
by adding an extra byte (0) in spare area to handle erased pages.

So can you share if I am missing something?

> 
> Upon reading:
>  - if this 14th byte is zero (*) => page was programmed: perform ECC
>    correction as usual
>  - else, page was not programmed: do not perform ECC, read entire data+spare
>    area, and set it to 0xff if less than 8 or 4 (max bitflips) zero bits
>    were found
> 
> (*) for robustness to bitflip in 14th byte, replace condition
> "14th byte is zero" by e.g. "14th byte has less than 4 bits set to 1".
> 
> What do you think ?

This seems logically good.

Thanks
Avinash

> 
> BR,
> --
> Ivan
> 



From dedekind1 at gmail.com  Thu Oct 11 02:01:54 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 09:01:54 +0300
Subject: output file cannot be in the UBIFS root directory check is not
 working quite well
In-Reply-To: <alpine.LNX.2.02.1210101855001.1211@bas>
References: <alpine.LNX.2.02.1210032322590.1375@bas>
 <alpine.LNX.2.02.1210051949390.1375@bas>
 <alpine.DEB.2.00.1210081556130.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081833560.1375@bas>
 <alpine.DEB.2.00.1210081650200.19047@lnxricardw.se.axis.com>
 <alpine.LNX.2.02.1210081900410.1375@bas>
 <alpine.LNX.2.02.1210101855001.1211@bas>
Message-ID: <1349935314.20594.40.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 18:55 +0400, kyak wrote:
> Thanks Artem, your patch 
> (http://lists.infradead.org/pipermail/linux-mtd/2012-October/044477.html) 
> has fixed my problem as well.

Good!

> > Yes, it only needs to check if the output file is above the top level
> > of the input tree. But I guess it's not that easy - first things that come 
> > into my mind are symbolic links and mount --bind.

This patch should take care of symbolic links - realpath should resolve
them. WRT bind-mounts - well, I consider this an unlikely case and it is
not a big deal if we do not detect this. mkfs.ubifs will fail somewhere
else, I guess, then.

But of course, I will not object if someone improves the check and
submits a patch.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/3206ce04/attachment.sig>

From u.kleine-koenig at pengutronix.de  Thu Oct 11 02:13:53 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Thu, 11 Oct 2012 08:13:53 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>
Message-ID: <20121011061353.GH10151@pengutronix.de>

On Thu, Oct 11, 2012 at 12:21:59AM -0400, Mike Frysinger wrote:
> On Mon, Oct 8, 2012 at 11:25 AM, Uwe Kleine-K?nig wrote:
> > --- a/drivers/mtd/maps/uclinux.c
> > +++ b/drivers/mtd/maps/uclinux.c
> > @@ -23,12 +23,13 @@
> >
> >  /****************************************************************************/
> >
> > -struct map_info uclinux_ram_map = {
> > -       .name = "RAM",
> > -       .phys = (unsigned long)__bss_stop,
> > +static struct map_info uclinux_ram_map = {
> >         .size = 0,
> >  };
> 
> this change will break Blackfin systems.  i mentioned last time
> someone tried to make this and we talked about adding a comment to
> prevent future breakage, but that seems to not have happened.
yeah, I really think adding a comment would be the right thing as I
don't see what could be the problem here you're talking about.

> i don't think's necessary either for the larger change here.  use the logic:
>     if (physaddr != -1)
>         mapp->phys = physaddr;
> and keep the default initialization.
> -mike
 
Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From shawn.guo at linaro.org  Thu Oct 11 03:49:16 2012
From: shawn.guo at linaro.org (Shawn Guo)
Date: Thu, 11 Oct 2012 15:49:16 +0800
Subject: [PATCH] ARM: dts: mxs: add the "clock-names" for gpmi-nand
In-Reply-To: <1349864829-19565-1-git-send-email-b32955@freescale.com>
References: <201210101237.13640.marex@denx.de>
 <1349864829-19565-1-git-send-email-b32955@freescale.com>
Message-ID: <20121011074912.GB26298@S2101-09.ap.freescale.net>

On Wed, Oct 10, 2012 at 06:27:09PM +0800, Huang Shijie wrote:
> The current DT nodes for mx23/mx28 miss the `clocks-names` item for gpmi-nand.
> So the gpmi-nand driver could not find the proper clock.
> 
> This patch fixes this issue.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>

Applied, thanks.

Shawn


From dedekind1 at gmail.com  Thu Oct 11 03:54:23 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 10:54:23 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349882785.2552.1987.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
 <1349861452.20594.12.camel@sauron.fi.intel.com>
 <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>
 <1349868630.20594.16.camel@sauron.fi.intel.com>
 <1349882785.2552.1987.camel@lnxprebble2.se.axis.com>
Message-ID: <1349942063.20594.56.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 17:26 +0200, Marcus Prebble wrote:
> which was a tad confusing. Please find attached a new diff (based off
> yours) with a few minor suggested changes.

Do you want me to fold your patch in? Or you prefer to keep it as a
separate patch? In the latter case, please, send it as a patch, with
commit message, and signed-off-by.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/7fa0d550/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 03:56:13 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 10:56:13 +0300
Subject: mkfs.ubifs problem when output file really isn't in the UBIFS
 root directory
In-Reply-To: <1349882785.2552.1987.camel@lnxprebble2.se.axis.com>
References: <1348242118.2552.1460.camel@lnxprebble2.se.axis.com>
 <1349367416.20373.75.camel@sauron.fi.intel.com>
 <1349708696.2552.1821.camel@lnxprebble2.se.axis.com>
 <1349851661.20594.6.camel@sauron.fi.intel.com>
 <1349859856.2552.1962.camel@lnxprebble2.se.axis.com>
 <1349861452.20594.12.camel@sauron.fi.intel.com>
 <1349865249.2552.1965.camel@lnxprebble2.se.axis.com>
 <1349868630.20594.16.camel@sauron.fi.intel.com>
 <1349882785.2552.1987.camel@lnxprebble2.se.axis.com>
Message-ID: <1349942173.20594.57.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 17:26 +0200, Marcus Prebble wrote:
> which was a tad confusing. Please find attached a new diff (based off
> yours) with a few minor suggested changes.

Actually, I've just pushed my patch out to mtd-utils.git. Would you
please, send your diff as a normal patch on top of that?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/35f80953/attachment-0001.sig>

From ivan.djelic at parrot.com  Thu Oct 11 04:21:49 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Thu, 11 Oct 2012 10:21:49 +0200
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <518397C60809E147AF5323E0420B992E3E9CB751@DBDE01.ent.ti.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
 <20121010170806.GB13585@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CB751@DBDE01.ent.ti.com>
Message-ID: <20121011082149.GA15609@parrot.com>

On Thu, Oct 11, 2012 at 06:27:13AM +0100, Philip, Avinash wrote:
(...)
> > Another simple strategy could use the fact that you add a 14th zero byte to
> > the 13 BCH bytes for RBL compatibility:
> 
> RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.
> 
> So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
> we can go for same approaches in BCH4 & BCH8 ecc scheme.
> 
> If I understood correctly, software BCH ecc scheme is modifying calculated
> ecc data to handle bit flips in erased pages.
> 
> If that is the only reason, whether same logic can go for same ECC calculation
> (remove modification of calculated ecc in case of software ecc correction)
> by adding an extra byte (0) in spare area to handle erased pages.
> 
> So can you share if I am missing something?

Yes, the only reason why a constant polynomial is added to hw-generated ECC bytes is to transparently handle bitflips in erased pages.
Handling erased pages this way has several benefits over the zero byte hack:
- cleaner code, no checking of the zero byte
- no expensive scan of data+spare area when reading an erased block: this step can significantly slow down the initial UBI scan (lots of erased pages to read)
- no need to worry about the (very unlikely) possibility of having more than 4 bitflips in the zero byte

OTOH, having the same ECC codes for both ELM and non-ELM chips with RBL compatibility sounds nice and would also simplify things.
Note: on platforms where we use SW BCH correction, we also use the MLC OMAP boot mode, which is more robust and not compatible with 8-bit/4-bit BCH layouts.

I don't know which way is better for the OMAP community:
1. Unifying ECC modes = loosing the constant polynomial benefits, but gaining RBL compat and simplifying code
2. Keeping separate ECC modes = code bloat

Tony, do you have an opinion on this ?

BTW, Afzal is submitting a series of patches [1] which are not compatible with your series; is there any plan to merge your patches ?

BR,
--
Ivan

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-October/044374.html


From avinashphilip at ti.com  Thu Oct 11 05:05:38 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Thu, 11 Oct 2012 09:05:38 +0000
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <20121011082149.GA15609@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
 <20121010170806.GB13585@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CB751@DBDE01.ent.ti.com>
 <20121011082149.GA15609@parrot.com>
Message-ID: <518397C60809E147AF5323E0420B992E3E9CB982@DBDE01.ent.ti.com>

On Thu, Oct 11, 2012 at 13:51:49, Ivan Djelic wrote:
> On Thu, Oct 11, 2012 at 06:27:13AM +0100, Philip, Avinash wrote:
> (...)
> > > Another simple strategy could use the fact that you add a 14th zero byte to
> > > the 13 BCH bytes for RBL compatibility:
> > 
> > RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.
> > 
> > So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
> > we can go for same approaches in BCH4 & BCH8 ecc scheme.
> > 
> > If I understood correctly, software BCH ecc scheme is modifying calculated
> > ecc data to handle bit flips in erased pages.
> > 
> > If that is the only reason, whether same logic can go for same ECC calculation
> > (remove modification of calculated ecc in case of software ecc correction)
> > by adding an extra byte (0) in spare area to handle erased pages.
> > 
> > So can you share if I am missing something?
> 
> Yes, the only reason why a constant polynomial is added to hw-generated ECC
> bytes is to transparently handle bitflips in erased pages.
> Handling erased pages this way has several benefits over the zero byte hack:
> - cleaner code, no checking of the zero byte
> - no expensive scan of data+spare area when reading an erased block: this
>   step can significantly slow down the initial UBI scan (lots of erased
>    pages to read)

Thanks for raising this point.
In order to reduce scan time of data+spare area when reading an erased block,
we can follow below steps

1. Create a standard ecc vector for erased page & check against it with calculated
   ecc of erased page.
2. If the vectors won't match, go for counting bit flips in erased page.
3. Again filtering of erased page can done by checking zero at fixed locations
   in spare area.
Note:
Reading of bits in erased page should done only for pages having bitflips.

> - no need to worry about the (very unlikely) possibility of having more
>   than 4 bitflips in the zero byte
> 
> OTOH, having the same ECC codes for both ELM and non-ELM chips with RBL
> compatibility sounds nice and would also simplify things.
> Note: on platforms where we use SW BCH correction, we also use the
> MLC OMAP boot mode, which is more robust and not compatible
> with 8-bit/4-bit BCH layouts.
> 
> I don't know which way is better for the OMAP community:
> 1. Unifying ECC modes = loosing the constant polynomial benefits,
>    but gaining RBL compat and simplifying code
> 2. Keeping separate ECC modes = code bloat
> 
> Tony, do you have an opinion on this ?
> 
> BTW, Afzal is submitting a series of patches [1] which are not
> compatible with your series; is there any plan to merge your patches ?

My next series will be on top Afzal's changes.

Thanks
Avinash

> 
> BR,
> --
> Ivan
> 
> [1] http://lists.infradead.org/pipermail/linux-mtd/2012-October/044374.html
> 



From dedekind1 at gmail.com  Thu Oct 11 05:51:44 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 12:51:44 +0300
Subject: [PATCH 1/6] bcma: export PLL reading function
In-Reply-To: <1348746947-2349-1-git-send-email-zajec5@gmail.com>
References: <1348746947-2349-1-git-send-email-zajec5@gmail.com>
Message-ID: <1349949104.20594.66.camel@sauron.fi.intel.com>

On Thu, 2012-09-27 at 13:55 +0200, Rafa? Mi?ecki wrote:
> This is required by NAND flash driver for initializing wait counters.
> 
> Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
> ---
> 0001-bcma-export-PLL-reading-function.patch                           
> Successfully built configuration "mips-bcm47xx_defconfig,mips,mips-linux-", no issues

I think you did not enable the driver in the defconfig.

Tested the patch(es) on top of the following commits:
e3134a5 Quick fixes - applied by aiaiai
a7c1993 mtd: fsl_elbc_nand: remove unnecessary badblock_pattern
03ba2bf mtd: ofpart: Fix incorrect NULL check in parse_ofoldpart_partitions()
c525349 mtd: m25p80: add support for the windbond w25q256 chip

--------------------------------------------------------------------------------

Successfully built configuration "mips-bcm47xx_defconfig,mips,mips-linux-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c: In function 'bcm47xxnflash_ops_bcm4706_init':
+drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c:253:6: warning: variable 'col_mask' set but not used [-Wunused-but-set-variable]

--------------------------------------------------------------------------------

checkpatch.pl has some complaints:

--------------------------------------------------------------------------------

checkpatch.pl results for patch "[PATCH 2/6] mtd: prepare place for BCMA NAND flash driver(s)"

WARNING:CONFIG_DESCRIPTION: please write a paragraph that describes the config symbol fully
#33: FILE: drivers/mtd/nand/Kconfig:449:
+config MTD_NAND_BCM47XXNFLASH

WARNING:STATIC_CONST_CHAR_ARRAY: static const char * array should probably be static const char * const
#113: FILE: drivers/mtd/nand/bcm47xxnflash/main.c:24:
+static const char *probes[] = { "bcm47xxpart", NULL };

total: 0 errors, 2 warnings, 145 lines checked

--------------------------------------------------------------------------------

checkpatch.pl results for patch "[PATCH 4/6] mtd: bcm47xxnflash: support for NAND_CMD_READID command"

WARNING:LONG_LINE: line over 80 characters
#120: FILE: drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c:106:
+                       b47n->id_data[i] = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA) & 0xFF;

total: 0 errors, 1 warnings, 134 lines checked

--------------------------------------------------------------------------------

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/20522b8c/attachment.sig>

From artem.bityutskiy at linux.intel.com  Thu Oct 11 05:57:49 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 12:57:49 +0300
Subject: [REMINDER: PATCH 1/1] mtd:nand:clk: preparation for switch to
 common clock framework
In-Reply-To: <3E54258959B69E4282D79E01AB1F32B7041EF679@DFLE12.ent.ti.com>
References: <1347899860-24358-1-git-send-email-m-karicheri2@ti.com>
 <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
 <3E54258959B69E4282D79E01AB1F32B7041EF679@DFLE12.ent.ti.com>
Message-ID: <1349949469.20594.67.camel@sauron.fi.intel.com>

On Fri, 2012-09-28 at 16:10 +0000, Karicheri, Muralidharan wrote:
> >> -----Original Message-----
> >> From: Karicheri, Muralidharan
> >> Sent: Monday, September 17, 2012 12:38 PM
> >> To: dwmw2 at infradead.org; artem.bityutskiy at linux.intel.com; hs at denx.de;
> >> mikedunn at newsguy.com; linux-mtd at lists.infradead.org; linux-kernel at vger.kernel.org;
> >> davinci-linux-open-source at linux.davincidsp.com; linux-arm-kernel at lists.infradead.org
> >> Cc: Karicheri, Muralidharan
> >> Subject: [PATCH 1/1] mtd:nand:clk: preparation for switch to common clock framework

I do not see this patch in my mailbox. Can you please re-send with all
the acks?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/7d5ad1bf/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 06:04:02 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 13:04:02 +0300
Subject: [PATCH] mtd: m25p80: fix missing MTD module owner
In-Reply-To: <50728A5E.3020102@parrot.com>
References: <50728A5E.3020102@parrot.com>
Message-ID: <1349949842.12014.1.camel@sauron.fi.intel.com>

On Mon, 2012-10-08 at 10:10 +0200, Gr?gor Boirie wrote:
> Marek,
> 
> Sorry about that. I didn't really mean to submit an official patch at
> first...
> Nevermind, please find one just below.

It misses a nice commit message and Signed-off-by. Please, try again. Or
I can do it for you if you want (please, let me know), but then I will
be the patch author.

Also, please add the stable tree tag there, as this is a bugfix which is
worth having in -stable.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/b82e42d5/attachment.sig>

From nsekhar at ti.com  Thu Oct 11 06:07:01 2012
From: nsekhar at ti.com (Sekhar Nori)
Date: Thu, 11 Oct 2012 15:37:01 +0530
Subject: [REMINDER: PATCH 1/1] mtd:nand:clk: preparation for switch to
 common clock framework
In-Reply-To: <1349949469.20594.67.camel@sauron.fi.intel.com>
References: <1347899860-24358-1-git-send-email-m-karicheri2@ti.com>
 <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
 <3E54258959B69E4282D79E01AB1F32B7041EF679@DFLE12.ent.ti.com>
 <1349949469.20594.67.camel@sauron.fi.intel.com>
Message-ID: <50769A45.5030105@ti.com>

Hi Artem,

On 10/11/2012 3:27 PM, Artem Bityutskiy wrote:
> On Fri, 2012-09-28 at 16:10 +0000, Karicheri, Muralidharan wrote:
>>>> -----Original Message-----
>>>> From: Karicheri, Muralidharan
>>>> Sent: Monday, September 17, 2012 12:38 PM
>>>> To: dwmw2 at infradead.org; artem.bityutskiy at linux.intel.com; hs at denx.de;
>>>> mikedunn at newsguy.com; linux-mtd at lists.infradead.org; linux-kernel at vger.kernel.org;
>>>> davinci-linux-open-source at linux.davincidsp.com; linux-arm-kernel at lists.infradead.org
>>>> Cc: Karicheri, Muralidharan
>>>> Subject: [PATCH 1/1] mtd:nand:clk: preparation for switch to common clock framework
> 
> I do not see this patch in my mailbox. Can you please re-send with all
> the acks?

This patch is already applied to linux-next. Do you need it still?

http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commit;h=ea73fe7f0d562154975a77fe77ae3da6ab4d3e77

Thanks,
Sekhar


From artem.bityutskiy at linux.intel.com  Thu Oct 11 06:09:59 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 13:09:59 +0300
Subject: [REMINDER: PATCH 1/1] mtd:nand:clk: preparation for switch to
 common clock framework
In-Reply-To: <50769A45.5030105@ti.com>
References: <1347899860-24358-1-git-send-email-m-karicheri2@ti.com>
 <1347899860-24358-2-git-send-email-m-karicheri2@ti.com>
 <3E54258959B69E4282D79E01AB1F32B7041EF679@DFLE12.ent.ti.com>
 <1349949469.20594.67.camel@sauron.fi.intel.com> <50769A45.5030105@ti.com>
Message-ID: <1349950199.12014.2.camel@sauron.fi.intel.com>

On Thu, 2012-10-11 at 15:37 +0530, Sekhar Nori wrote:
> Hi Artem,
> 
> On 10/11/2012 3:27 PM, Artem Bityutskiy wrote:
> > On Fri, 2012-09-28 at 16:10 +0000, Karicheri, Muralidharan wrote:
> >>>> -----Original Message-----
> >>>> From: Karicheri, Muralidharan
> >>>> Sent: Monday, September 17, 2012 12:38 PM
> >>>> To: dwmw2 at infradead.org; artem.bityutskiy at linux.intel.com; hs at denx.de;
> >>>> mikedunn at newsguy.com; linux-mtd at lists.infradead.org; linux-kernel at vger.kernel.org;
> >>>> davinci-linux-open-source at linux.davincidsp.com; linux-arm-kernel at lists.infradead.org
> >>>> Cc: Karicheri, Muralidharan
> >>>> Subject: [PATCH 1/1] mtd:nand:clk: preparation for switch to common clock framework
> > 
> > I do not see this patch in my mailbox. Can you please re-send with all
> > the acks?
> 
> This patch is already applied to linux-next. Do you need it still?
> 
> http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commit;h=ea73fe7f0d562154975a77fe77ae3da6ab4d3e77

Ah, right, no, I don't, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/684817ab/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 06:17:50 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 13:17:50 +0300
Subject: nand/denali: split the driver into 3 parts: generic, PCI and DT
In-Reply-To: <1348765086-27286-1-git-send-email-dinguyen@altera.com>
References: <1348765086-27286-1-git-send-email-dinguyen@altera.com>
Message-ID: <1349950670.12014.3.camel@sauron.fi.intel.com>

On Thu, 2012-09-27 at 10:58 -0600, dinguyen at altera.com wrote:
> Hello,
> 
> The following 2 patches attempts to make the current Denali NAND controller, 
> which is PCI-based, to be both PCI and device tree drivers.

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/4e15f2bd/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:04:27 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:04:27 +0300
Subject: [PATCH] mtd-www: Add fastmap doc
In-Reply-To: <1349799781-5132-1-git-send-email-richard@nod.at>
References: <CAN8TOE_BC6JGbrMcTYf5oMWnaAAx=LSh3V08vMnaGQVhkT-Yrw@mail.gmail.com>
 <1349799781-5132-1-git-send-email-richard@nod.at>
Message-ID: <1349953467.12014.7.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 18:23 +0200, Richard Weinberger wrote:
> Add documentation on fastmap to mtd-www.
> 
> Signed-off-by: Richard Weinberger <richard at nod.at>

Pushed to mtd-www.git, thanks!
-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/7921a0ef/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:07:12 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:07:12 +0300
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
References: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <1349953632.12014.8.camel@sauron.fi.intel.com>

On Thu, 2012-10-04 at 09:28 +0200, Linus Walleij wrote:
> The Nomadik NAND driver is really just a subset of the existing
> FSMC driver, so let's switch over to using that driver instead,
> since it handles more variants of this chip. The callbacks for
> setting up the chip is doing stuff now handled by the FSMC
> driver.
> 
> Cc: Alessandro Rubini <rubini at unipv.it>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

Pushed both to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/fdb275c4/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:15:21 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:15:21 +0300
Subject: [PATCH 1/1] mtd: st fsmc_nand: pass the ale and cmd resource
 via resource
In-Reply-To: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
References: <1349356456-13371-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1349954121.12014.9.camel@sauron.fi.intel.com>

On Thu, 2012-10-04 at 15:14 +0200, Jean-Christophe PLAGNIOL-VILLARD
wrote:
> Do not use the platform_data to pass resource and be smart in the drivers.
> Just pass it via resource
> 
> Switch to devm_request_and_ioremap at the sametime
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/85228016/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:20:05 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:20:05 +0300
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <1349385434-3073-1-git-send-email-valibert@micron.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
Message-ID: <1349954405.12014.11.camel@sauron.fi.intel.com>

On Thu, 2012-10-04 at 23:17 +0200, Vincenzo Aliberti wrote:
> +menu "LPDDR2_NVM memory drivers"
> +	depends on MTD!=n

Just 'depends on MTD'

> +# linux/drivers/mtd/lpddr2_nvm/Makefile

Why did you decide to create a separate directory for this one?
I think you should just put it to 'drivers/mtd/lpddr' instead.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/a675f660/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:22:57 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:22:57 +0300
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <1349385434-3073-1-git-send-email-valibert@micron.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
Message-ID: <1349954577.12014.13.camel@sauron.fi.intel.com>

On Thu, 2012-10-04 at 23:17 +0200, Vincenzo Aliberti wrote:
> Dear All,
>     continuing Micron support activity on PCM memories you can find here-below a 
> patch containing MTD driver for LPDDR2-NVM memories as demoed during Q2 Linaro 
> Connect in Hong Kong.
> 
> Let me thank TI Panda open source team for support on platform enablement 
> activity and Arnd for his first feedback on driver implementation

include/mtd/mtd-abi.h file does not longer exist, please re-base your
driver. Could you please also feed it to the checkpatch.pl tool and fix
style issues?

> +		pr_alert(
> +		"lpddr2_nvm_probe: Failed to allocate memory for map\n");

Just join this into 1 line. It is OK to have lines longer than 80
sybmols if you print a string.

Do this for all other similar places please.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/bc1748f1/attachment-0001.sig>

From dedekind1 at gmail.com  Thu Oct 11 07:25:07 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 14:25:07 +0300
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <201210050345.49507.marex@denx.de>
References: <201210050345.49507.marex@denx.de>
Message-ID: <1349954707.12014.14.camel@sauron.fi.intel.com>

On Fri, 2012-10-05 at 03:45 +0200, Marek Vasut wrote:
> Hello guys,
> 
> I tried integck from mtd-utils 1.5.0 on GPMI NAND driver since I suspect it 
> still has issues with UBI. See the outcome for yourself, log attached. Any 
> suggestions would be very appreciated.
> 
> :~/mtd-utils-1.5.0/tests/fs-tests/integrity# ./integck /media

Wait, you have power-cut emulation enabled, did you deliberately enable
it via UBIFS debugfs files?

> (pid 492): power_cut_emulated: failing after 19403ms

^^^^

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/16139e69/attachment.sig>

From marex at denx.de  Thu Oct 11 07:55:33 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 11 Oct 2012 13:55:33 +0200
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <1349954707.12014.14.camel@sauron.fi.intel.com>
References: <201210050345.49507.marex@denx.de>
 <1349954707.12014.14.camel@sauron.fi.intel.com>
Message-ID: <201210111355.33836.marex@denx.de>

Dear Artem Bityutskiy,

> On Fri, 2012-10-05 at 03:45 +0200, Marek Vasut wrote:
> > Hello guys,
> > 
> > I tried integck from mtd-utils 1.5.0 on GPMI NAND driver since I suspect
> > it still has issues with UBI. See the outcome for yourself, log
> > attached. Any suggestions would be very appreciated.
> > 
> > :~/mtd-utils-1.5.0/tests/fs-tests/integrity# ./integck /media
> 
> Wait, you have power-cut emulation enabled, did you deliberately enable
> it via UBIFS debugfs files?

I enabled this:
echo 1 > /sys/kernel/debug/ubifs/tst_recovery

Yes.

> > (pid 492): power_cut_emulated: failing after 19403ms
> 
> ^^^^

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Thu Oct 11 10:33:05 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 11 Oct 2012 17:33:05 +0300
Subject: [bug reportish] UBI_MAX_ERASECOUNTER not used consistently
In-Reply-To: <20121005065704.GA26466@elgon.mountain>
References: <20121005065704.GA26466@elgon.mountain>
Message-ID: <1349965985.12014.16.camel@sauron.fi.intel.com>

On Fri, 2012-10-05 at 09:57 +0300, Dan Carpenter wrote:
> Hi Artem,
> 
> I normally audit for underflows and I had a question about this code.
> 
> mtd/ubi/attach.c
>    665  static int early_erase_peb(struct ubi_device *ubi,
>    666                             const struct ubi_attach_info *ai, int pnum, int ec)
>    667  {
>    668          int err;
>    669          struct ubi_ec_hdr *ec_hdr;
>    670  
>    671          if ((long long)ec >= UBI_MAX_ERASECOUNTER) {
> 
> Casting to long long doesn't serve any purpose.  We normally say that
> "> UBI_MAX_ERASECOUNTER" is invalid but "== UBI_MAX_ERASECOUNTER" is Ok.
> The "ec" variable is signed and negative values are missed on this
> check.

Yes, the cast is bogus. I can fix it by removing the cast, but would
like to give you a chance to send the patch so that you get the credit
being the author in the git history. Let me know what you prefer.

Thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121011/646f5d37/attachment.sig>

From tony at atomide.com  Thu Oct 11 10:41:37 2012
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 11 Oct 2012 07:41:37 -0700
Subject: [PATCH 4/4] mtd: nand: omap2: Add data correction support
In-Reply-To: <20121011082149.GA15609@parrot.com>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-5-git-send-email-avinashphilip@ti.com>
 <20121003192044.GB27502@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9B8A65@DBDE01.ent.ti.com>
 <20121005142338.GA7199@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CA829@DBDE01.ent.ti.com>
 <20121010170806.GB13585@parrot.com>
 <518397C60809E147AF5323E0420B992E3E9CB751@DBDE01.ent.ti.com>
 <20121011082149.GA15609@parrot.com>
Message-ID: <20121011144137.GA12552@atomide.com>

* Ivan Djelic <ivan.djelic at parrot.com> [121011 01:23]:
> 
> I don't know which way is better for the OMAP community:
> 1. Unifying ECC modes = loosing the constant polynomial benefits, but gaining RBL compat and simplifying code
> 2. Keeping separate ECC modes = code bloat
> 
> Tony, do you have an opinion on this ?

Well right now I'm mostly interested in making device
drivers independent of the arch/arm/*omap*/* code.
That's where Afzal's patches help quite a bit, so let's
get those in first. So from that point of view, option #1
above sounds better as the first step :)

Ideally of course option #1 should not limit us from
adding extra features in the long run.

Regards,

Tony 


From linus.walleij at linaro.org  Thu Oct 11 12:06:49 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 11 Oct 2012 18:06:49 +0200
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
Message-ID: <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>

On Thu, Oct 11, 2012 at 6:15 AM, viresh kumar <viresh.kumar at linaro.org> wrote:
> On Wed, Oct 10, 2012 at 10:37 PM, Linus Walleij
> <linus.walleij at linaro.org> wrote:

>> dma_sync_single_for_device() is translating the virtual
>> address to physical for every chunk BTW.
>
> I pray that i am wrong here, otherwise i would be thrown out from
> the maintainers list for this driver :)
>
> dma_sync_single_for_device() is not doing anything on the buffer, but
> on the LLI item. Actually it is flushing LLI struct so that DMA h/w can get
> the correct values.

Sorry no, I'm the one who's wrong...

So the DMA engine memcpy() is not mapping virt->phys
but expects physical addresses to be provided.

So dma_map_single() needs to be called on the stuff
passed in to dev->device_prep_dma_memcpy().

And currently there is indeed a dma_map_single() in
dma_xfer() in fsmc_nand.c which should work just fine.

dma_map_single() will only work if the buffer is
physically contiguous.

And the block layer of the subsystem should take care
of only handing the driver buffers that are contiguous
I think? Not that I'm an expert here ... more some
guesswork :-/

Artem will know I hope!

Yours,
Linus Walleij


From viresh.kumar at linaro.org  Thu Oct 11 13:07:09 2012
From: viresh.kumar at linaro.org (viresh kumar)
Date: Thu, 11 Oct 2012 22:37:09 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
Message-ID: <CAOh2x=mr4jQ1WQTC50H6OsN_E+7gtVSy_UMwjrt6Rj-QbQRtOA@mail.gmail.com>

On Thu, Oct 11, 2012 at 9:36 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Thu, Oct 11, 2012 at 6:15 AM, viresh kumar <viresh.kumar at linaro.org> wrote:
>> I pray that i am wrong here, otherwise i would be thrown out from

s/am/am not/ :(

>> the maintainers list for this driver :)
>>
>> dma_sync_single_for_device() is not doing anything on the buffer, but
>> on the LLI item. Actually it is flushing LLI struct so that DMA h/w can get
>> the correct values.
>
> Sorry no, I'm the one who's wrong...

Glad to hear that. :)
It happens very few times in one's lifetime, that a beginner like me is correct
and an expert like you is not. Just kidding :)

> And the block layer of the subsystem should take care
> of only handing the driver buffers that are contiguous

But why should that be a constraint on block layer? It is working in virtual
space and is concerned about that onlly.

--
viresh


From plagnioj at jcrosoft.com  Thu Oct 11 14:04:06 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 11 Oct 2012 20:04:06 +0200
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <1349953632.12014.8.camel@sauron.fi.intel.com>
References: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
 <1349953632.12014.8.camel@sauron.fi.intel.com>
Message-ID: <20121011180406.GX12801@game.jcrosoft.org>

On 14:07 Thu 11 Oct     , Artem Bityutskiy wrote:
> On Thu, 2012-10-04 at 09:28 +0200, Linus Walleij wrote:
> > The Nomadik NAND driver is really just a subset of the existing
> > FSMC driver, so let's switch over to using that driver instead,
> > since it handles more variants of this chip. The callbacks for
> > setting up the chip is doing stuff now handled by the FSMC
> > driver.
> > 
> > Cc: Alessandro Rubini <rubini at unipv.it>
> > Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> 
> Pushed both to l2-mtd.git, thanks!
wait on this one Linus said he will send an other version based on my patch
for fmsc

Best Regards,
J.
> 
> -- 
> Best Regards,
> Artem Bityutskiy



> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From ckhardin at exablox.com  Thu Oct 11 14:22:18 2012
From: ckhardin at exablox.com (Charles Hardin)
Date: Thu, 11 Oct 2012 11:22:18 -0700
Subject: [QUESTION] MLC NAND and ECC over OOB area
In-Reply-To: <20121010181307.GB14389@parrot.com>
References: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>
 <20121010181307.GB14389@parrot.com>
Message-ID: <AD7F07FE-BAD4-48F6-BF24-520FA8BCFCB2@exablox.com>

On Oct 10, 2012, at 11:13 AM, Ivan Djelic wrote:

> 
> Hi Charles,
> 
> The OOB area is primarily used to store:
> - a bad block marker
> - ECC bytes
> 
> The ECC is generally designed to protect the data area, and the ECC bytes themselves (data+ECC bytes form a long codeword).
> The bad block marker normally has two useful values only: 0xff or 0x00, therefore it can be successfully read even with
> several bitflips, by looking at its Hamming weight (the number of 1s in the byte).
> 
> Now, if you want to store additional stuff (metadata) in the OOB area, _then_ you will need an ECC that covers data + metadata.
> This is possible with some drivers; this can also be done with the software BCH library (with a patch).
> 
> But the general trend is to avoid using the OOB area for that, because you never know how much space the next NAND generation
> will require for ECC, and you'll be in trouble once your metadata does not fit anymore in the remaining space.
> 
> BR,
> -- 
> Ivan


Ok, that seems reasonable - and, following this line of thought - then the expectation would be to change the nand_bbt.c code to check for the "weight of a bad block pattern" instead of looking for an exact match on the pattern.

For example the following would change:

/**
 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
 * @buf: the buffer to search
 * @td: search pattern descriptor
 *
 * Check for a pattern at the given place. Used to search bad block tables and
 * good / bad block identifiers. Same as check_pattern, but no optional empty
 * check.
 */
static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
{
        int i;
        uint8_t *p = buf;

        /* Compare the pattern */
        for (i = 0; i < td->len; i++) {
                if (p[td->offs + i] != td->pattern[i])
                        return -1;
        }
        return 0;
}

to something like the pseudo code below:

static in check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
{
	int i;
	int weight = 0;
	int tweight = 0;
	uint8_t *p = buf;

	/* Compute and compare the weight */
	for (i = 0; i < td->len; i++) {
		uint8_t w;

		w = p[td->offs+i];
		w = (w & 0x55) + ((w >> 1) & 0x55);
		w = (w & 0x33) + ((w >> 2) & 0x33);
		w = (w & 0x0f) + ((w >> 4) & 0x0f);
		weight += w;

		w = td->pattern[i];
		w = (w & 0x55) + ((w >> 1) & 0x55);
		w = (w & 0x33) + ((w >> 2) & 0x33);
		w = (w & 0x0f) + ((w >> 4) & 0x0f);
		tweight += w;
	}

	/* if the weight of the buf is more then half the weight of the pattern */
	if (weight > (tweight / 2))
		return 0;

	return -1;
}

This is a not an overly complex concept for nand_bbt code path, but it would change the exact match done currently to a heuristic match done by weight. My guess is that this behavior change will be done by the driver itself and override the nand_scan_bbt functions. However, I don't see an interface to plugin a specific BBT implementation in the underneath the nand_scan_bbt and nand_update_bbt functions currently in the hand drivers.

Regards,
Charles

--
Bits go in, bytes go out



From ckhardin at exablox.com  Thu Oct 11 15:02:51 2012
From: ckhardin at exablox.com (Charles Hardin)
Date: Thu, 11 Oct 2012 12:02:51 -0700
Subject: [QUESTION] MLC NAND and ECC over OOB area
In-Reply-To: <AD7F07FE-BAD4-48F6-BF24-520FA8BCFCB2@exablox.com>
References: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>
 <20121010181307.GB14389@parrot.com>
 <AD7F07FE-BAD4-48F6-BF24-520FA8BCFCB2@exablox.com>
Message-ID: <11F63AD4-A169-498F-8477-9FA9227EA110@exablox.com>


On Oct 11, 2012, at 11:22 AM, Charles Hardin wrote:

> Ok, that seems reasonable - and, following this line of thought - then the expectation would be to change the nand_bbt.c code to check for the "weight of a bad block pattern" instead of looking for an exact match on the pattern.
> 
> For example the following would change:
> 
> /**
> * check_short_pattern - [GENERIC] check if a pattern is in the buffer
> * @buf: the buffer to search
> * @td: search pattern descriptor
> *
> * Check for a pattern at the given place. Used to search bad block tables and
> * good / bad block identifiers. Same as check_pattern, but no optional empty
> * check.
> */
> static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
> {
>        int i;
>        uint8_t *p = buf;
> 
>        /* Compare the pattern */
>        for (i = 0; i < td->len; i++) {
>                if (p[td->offs + i] != td->pattern[i])
>                        return -1;
>        }
>        return 0;
> }
> 
> to something like the pseudo code below:
> 
> static in check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
> {
> 	int i;
> 	int weight = 0;
> 	int tweight = 0;
> 	uint8_t *p = buf;
> 
> 	/* Compute and compare the weight */
> 	for (i = 0; i < td->len; i++) {
> 		uint8_t w;
> 
> 		w = p[td->offs+i];
> 		w = (w & 0x55) + ((w >> 1) & 0x55);
> 		w = (w & 0x33) + ((w >> 2) & 0x33);
> 		w = (w & 0x0f) + ((w >> 4) & 0x0f);
> 		weight += w;
> 
> 		w = td->pattern[i];
> 		w = (w & 0x55) + ((w >> 1) & 0x55);
> 		w = (w & 0x33) + ((w >> 2) & 0x33);
> 		w = (w & 0x0f) + ((w >> 4) & 0x0f);
> 		tweight += w;
> 	}
> 
> 	/* if the weight of the buf is more then half the weight of the pattern */
> 	if (weight > (tweight / 2))
> 		return 0;
> 
> 	return -1;
> }
> 
> This is a not an overly complex concept for nand_bbt code path, but it would change the exact match done currently to a heuristic match done by weight. My guess is that this behavior change will be done by the driver itself and override the nand_scan_bbt functions. However, I don't see an interface to plugin a specific BBT implementation in the underneath the nand_scan_bbt and nand_update_bbt functions currently in the hand drivers.
> 
> Regards,
> Charles


Oops, wrong call path - I just looked into nand_base.c and on the nand_block_bad function, I was looking at the generation of the in core memory bbt - I'll poke around a bit more now on the proper code path to construct a better world view.

Regards,
Charles

From linus.walleij at linaro.org  Thu Oct 11 17:51:25 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 11 Oct 2012 23:51:25 +0200
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAOh2x=mr4jQ1WQTC50H6OsN_E+7gtVSy_UMwjrt6Rj-QbQRtOA@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <CAOh2x=mr4jQ1WQTC50H6OsN_E+7gtVSy_UMwjrt6Rj-QbQRtOA@mail.gmail.com>
Message-ID: <CACRpkdZvO3Df58UxFDc_T10JDhE=O5KKHZTzd9g0BOn60NWZcA@mail.gmail.com>

On Thu, Oct 11, 2012 at 7:07 PM, viresh kumar <viresh.kumar at linaro.org> wrote:
> On Thu, Oct 11, 2012 at 9:36 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
>>
>> And the block layer of the subsystem should take care
>> of only handing the driver buffers that are contiguous
>
> But why should that be a constraint on block layer? It is working in virtual
> space and is concerned about that onlly.

Not the block layer, the block layer of the subsystem.

It has to pick out the chunks that get transferred down to the drivers.

For example drivers/mmc/card/block.c will convert transfers into
sglists and pass down to the MMC drivers. mmc_queue_map_sg()
calls blk_rq_map_sg() to do the job. It's even documented in
Documentation/block/biodoc.txt

I don't know how that works in MTD...

Yours,
Linus Walleij


From malwinakrajewskasr45 at wp.pl  Thu Oct 11 17:17:36 2012
From: malwinakrajewskasr45 at wp.pl (shannan)
Date: Thu, 11 Oct 2012 14:17:36 -0700
Subject: hi there
Message-ID: <5076D4FD.E2C79D7E@smtp.wp.pl>


Hola ! 
I viewed your main picture on facebook. I love you a lot.  Let's communicate !
I can send you my picture as well if you want...

All my love,












From linus.walleij at linaro.org  Thu Oct 11 18:20:37 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 12 Oct 2012 00:20:37 +0200
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <20121011180406.GX12801@game.jcrosoft.org>
References: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
 <1349953632.12014.8.camel@sauron.fi.intel.com>
 <20121011180406.GX12801@game.jcrosoft.org>
Message-ID: <CACRpkdb+=EPVjuwcCHqc-HE09cBhjo1fAf69iWVdHC+auEyc8w@mail.gmail.com>

On Thu, Oct 11, 2012 at 8:04 PM, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj at jcrosoft.com> wrote:
> On 14:07 Thu 11 Oct     , Artem Bityutskiy wrote:
>>
>> Pushed both to l2-mtd.git, thanks!
>
> wait on this one Linus said he will send an other version based on my patch
> for fmsc

I made a fix-up patch instead, that's simpler I guess... mailing out now.

Thanks,
Linus Walleij


From linus.walleij at linaro.org  Thu Oct 11 18:23:02 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 12 Oct 2012 00:23:02 +0200
Subject: [PATCH] ARM: nomadik: fixup some FSMC merge problems
Message-ID: <1349994182-26116-1-git-send-email-linus.walleij@linaro.org>

Due to a clash between refactoring and due to loss of a header
file that remained in my working tree the Nomadik stopped
compiling after switching to the FSMC driver. This patch fixes
it up.

Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-nomadik/board-nhk8815.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index a105d1b..3f97ef4 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -37,14 +37,15 @@
 #include <plat/mtu.h>
 #include <plat/pincfg.h>
 
-#include <mach/fsmc.h>
-
 #include "cpu-8815.h"
 
 /* Initial value for SRC control register: all timers use MXTAL/8 source */
 #define SRC_CR_INIT_MASK	0x00007fff
 #define SRC_CR_INIT_VAL		0x2aaa8000
 
+#define ALE_OFF 0x1000000
+#define CLE_OFF 0x800000
+
 /* These addresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
 	{
@@ -53,6 +54,16 @@ static struct resource nhk8815_nand_resources[] = {
 		.end = 0x40000000 + SZ_16K - 1,
 		.flags = IORESOURCE_MEM,
 	}, {
+		.name = "nand_addr",
+		.start = 0x40000000 + ALE_OFF,
+		.end = 0x40000000 +ALE_OFF + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.name = "nand_cmd",
+		.start = 0x40000000 + CLE_OFF,
+		.end = 0x40000000 + CLE_OFF + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
 		.name  = "fsmc_regs",
 		.start = NOMADIK_FSMC_BASE,
 		.end   = NOMADIK_FSMC_BASE + SZ_4K - 1,
@@ -105,8 +116,6 @@ static struct fsmc_nand_platform_data nhk8815_nand_platform_data = {
 	.partitions = nhk8815_partitions,
 	.nr_partitions = ARRAY_SIZE(nhk8815_partitions),
 	.width = FSMC_NAND_BW8,
-	.ale_off = 0x1000000,
-	.cle_off = 0x800000,
 };
 
 static struct platform_device nhk8815_nand_device = {
@@ -171,6 +180,10 @@ static struct platform_device nhk8815_onenand_device = {
 	.num_resources	= ARRAY_SIZE(nhk8815_onenand_resource),
 };
 
+/* bus control reg. and bus timing reg. for CS0..CS3 */
+#define FSMC_BCR(x)	(NOMADIK_FSMC_VA + (x << 3))
+#define FSMC_BTR(x)	(NOMADIK_FSMC_VA + (x << 3) + 0x04)
+
 static void __init nhk8815_onenand_init(void)
 {
 #ifdef CONFIG_MTD_ONENAND
-- 
1.7.11.4



From mturquette at ti.com  Thu Oct 11 19:49:52 2012
From: mturquette at ti.com (Mike Turquette)
Date: Thu, 11 Oct 2012 16:49:52 -0700
Subject: [PATCH 1/2] ARM: nomadik: switch over to using the FSMC driver
In-Reply-To: <CACRpkdYMz05DwtLtHkggvo8VFOtvPLpovwq6fLceeiFK0Wci0Q@mail.gmail.com>
References: <1349335709-13399-1-git-send-email-linus.walleij@linaro.org>
 <CACRpkdYMz05DwtLtHkggvo8VFOtvPLpovwq6fLceeiFK0Wci0Q@mail.gmail.com>
Message-ID: <20121011234952.2941.18793@nucleus>

Quoting Linus Walleij (2012-10-05 05:52:06)
> On Thu, Oct 4, 2012 at 9:28 AM, Linus Walleij <linus.walleij at linaro.org> wrote:
> 
> > The Nomadik NAND driver is really just a subset of the existing
> > FSMC driver, so let's switch over to using that driver instead,
> > since it handles more variants of this chip. The callbacks for
> > setting up the chip is doing stuff now handled by the FSMC
> > driver.
> >
> > Cc: Alessandro Rubini <rubini at unipv.it>
> > Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> > ---
> > I'm requesting Mike Turquette's ACK on this patch so I can merge
> > it through ARM SoC.
> 
> Still requesting Mike's ACK, but not for merging through ARM SoC
> but through MTD.
> 

Sorry for the late response but I just returned from vacation.  Might be
too late but:

Acked-by: Mike Turquette <mturquette at linaro.org>

Thanks,
Mike

> If you apply Jean-Christophe's patch first (please do that) I will
> send a v2 of this patch set to be applied onto MTD as well
> (should be OK).
> 
> Yours,
> Linus Walleij


From dinguyen at altera.com  Fri Oct 12 00:36:56 2012
From: dinguyen at altera.com (dinguyen at altera.com)
Date: Thu, 11 Oct 2012 22:36:56 -0600
Subject: [PATCH] denali: nand: Fix build break for driver when built as a
 module
Message-ID: <1350016616-22098-1-git-send-email-dinguyen@altera.com>

From: Dinh Nguyen <dinguyen at altera.com>

Make denali_init and denali_remove accessible when the driver
is built as a loadable module.

Signed-off-by: Dinh Nguyen <dinguyen at altera.com>
---
 drivers/mtd/nand/denali.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 8f99e9b..0c8bb6b 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1596,6 +1596,7 @@ failed_req_irq:
 
 	return ret;
 }
+EXPORT_SYMBOL(denali_init);
 
 /* driver exit point */
 void denali_remove(struct denali_nand_info *denali)
@@ -1604,3 +1605,4 @@ void denali_remove(struct denali_nand_info *denali)
 	dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
 			DMA_BIDIRECTIONAL);
 }
+EXPORT_SYMBOL(denali_remove);
-- 
1.7.9.5




From dinguyen at altera.com  Fri Oct 12 00:46:09 2012
From: dinguyen at altera.com (dinguyen at altera.com)
Date: Thu, 11 Oct 2012 22:46:09 -0600
Subject: [PATCH] denali: nand: Fix build break for driver when built as a
 module
Message-ID: <1350017169-22166-1-git-send-email-dinguyen@altera.com>

From: Dinh Nguyen <dinguyen at altera.com>

Make denali_init and denali_remove accessible when the driver
is built as a loadable module.

Signed-off-by: Dinh Nguyen <dinguyen at altera.com>
---
 drivers/mtd/nand/denali.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 8f99e9b..0c8bb6b 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1596,6 +1596,7 @@ failed_req_irq:
 
 	return ret;
 }
+EXPORT_SYMBOL(denali_init);
 
 /* driver exit point */
 void denali_remove(struct denali_nand_info *denali)
@@ -1604,3 +1605,4 @@ void denali_remove(struct denali_nand_info *denali)
 	dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
 			DMA_BIDIRECTIONAL);
 }
+EXPORT_SYMBOL(denali_remove);
-- 
1.7.9.5




From vipin.kumar at st.com  Thu Oct 11 23:55:34 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Fri, 12 Oct 2012 09:25:34 +0530
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
Message-ID: <507794B6.2000107@st.com>

On 10/11/2012 9:36 PM, Linus Walleij wrote:
> On Thu, Oct 11, 2012 at 6:15 AM, viresh kumar<viresh.kumar at linaro.org>  wrote:
>> On Wed, Oct 10, 2012 at 10:37 PM, Linus Walleij
>> <linus.walleij at linaro.org>  wrote:
>
>>> dma_sync_single_for_device() is translating the virtual
>>> address to physical for every chunk BTW.
>>
>> I pray that i am wrong here, otherwise i would be thrown out from
>> the maintainers list for this driver :)
>>
>> dma_sync_single_for_device() is not doing anything on the buffer, but
>> on the LLI item. Actually it is flushing LLI struct so that DMA h/w can get
>> the correct values.
>
> Sorry no, I'm the one who's wrong...
>
> So the DMA engine memcpy() is not mapping virt->phys
> but expects physical addresses to be provided.
>
> So dma_map_single() needs to be called on the stuff
> passed in to dev->device_prep_dma_memcpy().
>
> And currently there is indeed a dma_map_single() in
> dma_xfer() in fsmc_nand.c which should work just fine.
>
> dma_map_single() will only work if the buffer is
> physically contiguous.
>
> And the block layer of the subsystem should take care
> of only handing the driver buffers that are contiguous
> I think? Not that I'm an expert here ... more some
> guesswork :-/

The buffers provided to the driver are actually user buffers. The reason 
I say that is because the generic nand test modules eg 
drivers/mtd/nand/mtd_stresstest.c calls mtd->_read with a user buffer as 
an argument

This same buffer directly trickles down to the driver

Artem, should we clearly cast this buffer as a user pointer instead of 
just a 'uint8_t *'.

Regards
Vipin


From vapier.adi at gmail.com  Fri Oct 12 00:46:04 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Fri, 12 Oct 2012 00:46:04 -0400
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
In-Reply-To: <5073FE55.2000402@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
Message-ID: <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>

On Tue, Oct 9, 2012 at 6:37 AM, Greg Ungerer <gerg at snapgear.com> wrote:
> On 10/09/2012 06:44 PM, Uwe Kleine-K?nig wrote:
>> On Tue, Oct 09, 2012 at 01:29:46PM +1000, Greg Ungerer wrote:
>>> On 09/10/12 01:25, Uwe Kleine-K??nig wrote:
>>>> This allows to put the filesystem at a defined address in ROM allowing
>>>> to save more precious RAM.
>>>>
>>>> I think it's save to default to ROM because the intention of using the
>>>> uclinux map is to use a romfs and so mtd-ram doesn't give you anything
>>>> that mtd-rom doesn't.
>>>>
>>>> Signed-off-by: Uwe Kleine-K?????nig <u.kleine-koenig at pengutronix.de>
>>>
>>> Looks good to me, so:
>>>
>>> Acked-by: Greg Ungerer <gerg at uclinux.org>
>>>
>>> Couple of things to be aware of. Artem currently has a couple of
>>> patches against this file (looks like at least 1 of them is currently
>>> in linux-next). It will probably conflict with your changes, should
>>> be easy enough to fix up.
>>
>> If you tell me a branch to test, I can do so.
>
> Sure. All three patches I sent to the linux-mtd list are here:
>
> The following changes since commit 979570e02981d4a8fc20b3cc8fd651856c98ee9d:
>   Linus Torvalds (1):
>         Linux 3.6-rc7
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git cfmmu
>
> Greg Ungerer (3):
>       mtd: fix wrong usage of ioremap_nocache() in uclinux.c map driver
>       mtd: allow uclinux map driver to be used on any ColdFire CPU platform
>       mtd: clean up uclinux.c map driver
>
>  drivers/mtd/maps/Kconfig   |    2 +-
>  drivers/mtd/maps/uclinux.c |   42
> +++++++++++++++++++-----------------------
>  2 files changed, 20 insertions(+), 24 deletions(-)
>
>
> As far as I can see Artem has pushed the first 2 into for linux-next,
> but not the third. I am hoping he hops in here and lets us know what
> his intentions are with the third...

so to be clear, Uwe's patch hasn't been picked up by anyone yet so we
can get it fixed first ?
-mike


From gerg at snapgear.com  Fri Oct 12 01:57:59 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Fri, 12 Oct 2012 15:57:59 +1000
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
 <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
Message-ID: <5077B167.40009@snapgear.com>

On 12/10/12 14:46, Mike Frysinger wrote:
> On Tue, Oct 9, 2012 at 6:37 AM, Greg Ungerer <gerg at snapgear.com> wrote:
>> On 10/09/2012 06:44 PM, Uwe Kleine-K??nig wrote:
>>> On Tue, Oct 09, 2012 at 01:29:46PM +1000, Greg Ungerer wrote:
>>>> On 09/10/12 01:25, Uwe Kleine-K?????nig wrote:
>>>>> This allows to put the filesystem at a defined address in ROM allowing
>>>>> to save more precious RAM.
>>>>>
>>>>> I think it's save to default to ROM because the intention of using the
>>>>> uclinux map is to use a romfs and so mtd-ram doesn't give you anything
>>>>> that mtd-rom doesn't.
>>>>>
>>>>> Signed-off-by: Uwe Kleine-K???????????nig <u.kleine-koenig at pengutronix.de>
>>>>
>>>> Looks good to me, so:
>>>>
>>>> Acked-by: Greg Ungerer <gerg at uclinux.org>
>>>>
>>>> Couple of things to be aware of. Artem currently has a couple of
>>>> patches against this file (looks like at least 1 of them is currently
>>>> in linux-next). It will probably conflict with your changes, should
>>>> be easy enough to fix up.
>>>
>>> If you tell me a branch to test, I can do so.
>>
>> Sure. All three patches I sent to the linux-mtd list are here:
>>
>> The following changes since commit 979570e02981d4a8fc20b3cc8fd651856c98ee9d:
>>    Linus Torvalds (1):
>>          Linux 3.6-rc7
>>
>> are available in the git repository at:
>>
>>    git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git cfmmu
>>
>> Greg Ungerer (3):
>>        mtd: fix wrong usage of ioremap_nocache() in uclinux.c map driver
>>        mtd: allow uclinux map driver to be used on any ColdFire CPU platform
>>        mtd: clean up uclinux.c map driver
>>
>>   drivers/mtd/maps/Kconfig   |    2 +-
>>   drivers/mtd/maps/uclinux.c |   42
>> +++++++++++++++++++-----------------------
>>   2 files changed, 20 insertions(+), 24 deletions(-)
>>
>>
>> As far as I can see Artem has pushed the first 2 into for linux-next,
>> but not the third. I am hoping he hops in here and lets us know what
>> his intentions are with the third...
>
> so to be clear, Uwe's patch hasn't been picked up by anyone yet so we
> can get it fixed first ?

I haven't picked it up. I assumed Artem would, but I have not seen
any response from him on this yet.

I thought you where going to put a comment in there,
http://mailman.uclinux.org/pipermail/uclinux-dev/2012-May/051873.html

In any case, Uwe, that thread states what the issue is when it came
up a few months back.

Regards
Greg



-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From u.kleine-koenig at pengutronix.de  Fri Oct 12 03:22:21 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Fri, 12 Oct 2012 09:22:21 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <5077B167.40009@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com>
 <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
 <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
 <5077B167.40009@snapgear.com>
Message-ID: <20121012072221.GB639@pengutronix.de>

Hello,

On Fri, Oct 12, 2012 at 03:57:59PM +1000, Greg Ungerer wrote:
> >so to be clear, Uwe's patch hasn't been picked up by anyone yet so we
> >can get it fixed first ?
ok, so for blackfin uclinux_ram_map must not be static because it is
used in arch/blackfin/kernel/setup.c. If I tried to introduce such code
for an ARM platform people would run away scared maybe after telling me
I should fix my boot loader.  I really don't know the situation on
blackfin, but this really has potential for generalisation. But I don't
even know if you have/need a boot loader at all there. Here is what I
found quickly:

diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index fb96e60..24478a2 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -583,7 +583,7 @@ static __init void memory_setup(void)
 
 #ifdef CONFIG_MPU
 	/* Round up to multiple of 4MB */
-	memory_start = (_ramstart + 0x3fffff) & ~0x3fffff;
+	memory_start = ALIGN(_ramstart, 0x400000);
 #else
 	memory_start = PAGE_ALIGN(_ramstart);
 #endif
@@ -593,6 +593,13 @@ static __init void memory_setup(void)
 	memory_mtd_end = memory_end;
 
 	mtd_phys = _ramstart;
+
+	/*
+	 * Since the default MTD_UCLINUX has no magic number, we just blindly
+	 * read 8 past the end of the kernel's image, and look at it.
+	 * When no image is attached, mtd_size is set to a random number.
+	 * So do some basic sanity checks before operating on things.
+	 */
 	mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8)));
 
 # if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS)
@@ -621,11 +628,6 @@ static __init void memory_setup(void)
 	}
 # endif				/* CONFIG_ROMFS_FS */
 
-	/* Since the default MTD_UCLINUX has no magic number, we just blindly
-	 * read 8 past the end of the kernel's image, and look at it.
-	 * When no image is attached, mtd_size is set to a random number
-	 * Do some basic sanity checks before operating on things
-	 */
 	if (mtd_size == 0 || memory_end <= mtd_size) {
 		pr_emerg("Could not find valid ram mtd attached.\n");
 	} else {

If you had a boot loader, my patch (making the location of the uclinux
map settable by a kernel parameter) should be a move in the right
direction for you, too.

I will fix my patch keeping uclinux_ram_map non-static and resend.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From u.kleine-koenig at pengutronix.de  Fri Oct 12 03:41:00 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Fri, 12 Oct 2012 09:41:00 +0200
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>
Message-ID: <20121012074100.GC639@pengutronix.de>

On Thu, Oct 11, 2012 at 12:21:59AM -0400, Mike Frysinger wrote:
> On Mon, Oct 8, 2012 at 11:25 AM, Uwe Kleine-K?nig wrote:
> > --- a/drivers/mtd/maps/uclinux.c
> > +++ b/drivers/mtd/maps/uclinux.c
> > @@ -23,12 +23,13 @@
> >
> >  /****************************************************************************/
> >
> > -struct map_info uclinux_ram_map = {
> > -       .name = "RAM",
> > -       .phys = (unsigned long)__bss_stop,
> > +static struct map_info uclinux_ram_map = {
> >         .size = 0,
> >  };
> 
> this change will break Blackfin systems.  i mentioned last time
> someone tried to make this and we talked about adding a comment to
> prevent future breakage, but that seems to not have happened.
Will send a patch in a moment.

> i don't think's necessary either for the larger change here.  use the logic:
>     if (physaddr != -1)
>         mapp->phys = physaddr;
> and keep the default initialization.
I keep my way as it seems to be more robust for possible future changes.
(I don't know if that will ever happen, but consider platform device
support or just a retry of instatiation after physaddr changed from
something back to -1.)

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From u.kleine-koenig at pengutronix.de  Fri Oct 12 03:41:32 2012
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 12 Oct 2012 09:41:32 +0200
Subject: [PATCH 1/2 RFC v2] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>

This allows to put the filesystem at a defined address in ROM allowing
to save more precious RAM.

I think it's save to default to ROM because the intention of using the
uclinux map is to use a romfs and so mtd-ram doesn't give you anything
that mtd-rom doesn't.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
--
Changed since (implicit) v1:

 - don't make uclinux_ram_map static as pointed out by Mike and Greg.

 drivers/mtd/maps/Kconfig   |    2 +-
 drivers/mtd/maps/uclinux.c |   28 ++++++++++++++++++++++------
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 5ba2458..d945950 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -443,7 +443,7 @@ config MTD_GPIO_ADDR
 
 config MTD_UCLINUX
 	bool "Generic uClinux RAM/ROM filesystem support"
-	depends on MTD_RAM=y && !MMU
+	depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
 	help
 	  Map driver to support image based filesystems for uClinux.
 
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index c3bb304..f5e8e9a 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -24,11 +24,12 @@
 /****************************************************************************/
 
 struct map_info uclinux_ram_map = {
-	.name = "RAM",
-	.phys = (unsigned long)__bss_stop,
 	.size = 0,
 };
 
+static unsigned long physaddr = -1;
+module_param(physaddr, ulong, S_IRUGO);
+
 static struct mtd_info *uclinux_ram_mtdinfo;
 
 /****************************************************************************/
@@ -60,11 +61,17 @@ static int __init uclinux_mtd_init(void)
 	struct map_info *mapp;
 
 	mapp = &uclinux_ram_map;
+
+	if (physaddr == -1)
+		mapp->phys = (resource_size_t)__bss_stop;
+	else
+		mapp->phys = physaddr;
+
 	if (!mapp->size)
 		mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
 	mapp->bankwidth = 4;
 
-	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
+	printk("uclinux[mtd]: RAM/ROM probe address=0x%x size=0x%x\n",
 	       	(int) mapp->phys, (int) mapp->size);
 
 	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
@@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
 
 	simple_map_init(mapp);
 
-	mtd = do_map_probe("map_ram", mapp);
+	mapp->name = "ROM";
+	mtd = do_map_probe("map_rom", mapp);
+	if (!mtd) {
+		/* fall back to ram probing for compatibility reasons */
+		mapp->name = "RAM";
+		mtd = do_map_probe("map_ram", mapp);
+		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
+			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
+	}
+
 	if (!mtd) {
-		printk("uclinux[mtd]: failed to find a mapping?\n");
+		printk("uclinux[mtd]: failed to find a rom/ram mapping?\n");
 		iounmap(mapp->virt);
 		return(-ENXIO);
 	}
@@ -115,6 +131,6 @@ module_exit(uclinux_mtd_cleanup);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Greg Ungerer <gerg at snapgear.com>");
-MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
+MODULE_DESCRIPTION("Generic RAM/ROM based MTD for uClinux");
 
 /****************************************************************************/
-- 
1.7.10.4



From u.kleine-koenig at pengutronix.de  Fri Oct 12 03:41:33 2012
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 12 Oct 2012 09:41:33 +0200
Subject: [PATCH 2/2] mtd/uclinux: add a comment about why uclinux_ram_map must
 not be static
In-Reply-To: <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <1350027693-19528-2-git-send-email-u.kleine-koenig@pengutronix.de>

I was (at least) the second person trying to fix a warning by sparse, so
document in the code why this is a bad idea.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
Hello,

it's a bit exaggerated to claim that sparse is happy now, but at least
we have one warning less :-)

Uwe
 drivers/mtd/maps/uclinux.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index f5e8e9a..18cf6d0 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -23,6 +23,12 @@
 
 /****************************************************************************/
 
+/*
+ * Blackfin uses uclinux_ram_map during startup, so it must not be static.
+ * Provide a dummy declaration to make sparse happy.
+ */
+extern struct map_info uclinux_ram_map;
+
 struct map_info uclinux_ram_map = {
 	.size = 0,
 };
-- 
1.7.10.4



From matthieu.castet at parrot.com  Fri Oct 12 03:57:39 2012
From: matthieu.castet at parrot.com (Matthieu CASTET)
Date: Fri, 12 Oct 2012 09:57:39 +0200
Subject: [QUESTION] MLC NAND and ECC over OOB area
In-Reply-To: <AD7F07FE-BAD4-48F6-BF24-520FA8BCFCB2@exablox.com>
References: <0A090286-986E-4B22-AEC3-EE1C48EC466E@gmail.com>
 <20121010181307.GB14389@parrot.com>
 <AD7F07FE-BAD4-48F6-BF24-520FA8BCFCB2@exablox.com>
Message-ID: <5077CD73.802@parrot.com>

Charles Hardin a ?crit :
> On Oct 10, 2012, at 11:13 AM, Ivan Djelic wrote:
> 
>> Hi Charles,
>>
>> The OOB area is primarily used to store:
>> - a bad block marker
>> - ECC bytes
>>
>> The ECC is generally designed to protect the data area, and the ECC bytes themselves (data+ECC bytes form a long codeword).
>> The bad block marker normally has two useful values only: 0xff or 0x00, therefore it can be successfully read even with
>> several bitflips, by looking at its Hamming weight (the number of 1s in the byte).
>>
>> Now, if you want to store additional stuff (metadata) in the OOB area, _then_ you will need an ECC that covers data + metadata.
>> This is possible with some drivers; this can also be done with the software BCH library (with a patch).
>>
>> But the general trend is to avoid using the OOB area for that, because you never know how much space the next NAND generation
>> will require for ECC, and you'll be in trouble once your metadata does not fit anymore in the remaining space.
>>
>> BR,
>> -- 
>> Ivan
> 
> 
> Ok, that seems reasonable - and, following this line of thought - then the expectation would be to change the nand_bbt.c code to check for the "weight of a bad block pattern" instead of looking for an exact match on the pattern.
> 
They were some work on this :
http://thread.gmane.org/gmane.linux.drivers.mtd/42243follow d


From Thomas.Betker at rohde-schwarz.com  Fri Oct 12 04:40:26 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Fri, 12 Oct 2012 10:40:26 +0200
Subject: JFFS2 deadlock, kernel 3.4.11
In-Reply-To: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
References: <OFB9AE3BAC.A5615989-ONC1257A8A.0032CA58-C1257A8B.004EAAA5@rohde-schwarz.com>
Message-ID: <OFBD733ECD.FFA516F7-ONC1257A95.002EA2AB-C1257A95.002FA73F@rohde-schwarz.com>

Hello Joakim,

there was a minor error in my original post:

> The GC thread hangs in lock_page(page), the write thread hangs in the 
> first mutex_lock(&f->sem). The cause seems to be an AB-BA deadlock:

When retesting, I found that the write thread hangs in the _second_ 
mutex_lock(&f->sem), i.e., the one for jffs2_do_readpage_nolock(); looking 
at my notes, I am pretty sure that this was also the case in the first 
deadlocks.

Actually, it seems that the path with jffs2_reserve_space() is never taken 
in the 'scp' tests. For testing the patch, I would like to make sure that 
this path also works, but so far, I couldn't find a way to force jffs2 to 
take it. I will have to dig a bit deeper for this ...

Best regards,
Thomas



From plagnioj at jcrosoft.com  Fri Oct 12 05:37:30 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 12 Oct 2012 11:37:30 +0200
Subject: [PATCH] ARM: nomadik: fixup some FSMC merge problems
In-Reply-To: <1349994182-26116-1-git-send-email-linus.walleij@linaro.org>
References: <1349994182-26116-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20121012093730.GA12801@game.jcrosoft.org>

On 00:23 Fri 12 Oct     , Linus Walleij wrote:
> 
> Due to a clash between refactoring and due to loss of a header
> file that remained in my working tree the Nomadik stopped
> compiling after switching to the FSMC driver. This patch fixes
> it up.
> 
> Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Best Regards,
J.
> ---
>  arch/arm/mach-nomadik/board-nhk8815.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
> index a105d1b..3f97ef4 100644
> --- a/arch/arm/mach-nomadik/board-nhk8815.c
> +++ b/arch/arm/mach-nomadik/board-nhk8815.c
> @@ -37,14 +37,15 @@
>  #include <plat/mtu.h>
>  #include <plat/pincfg.h>
>  
> -#include <mach/fsmc.h>
> -
>  #include "cpu-8815.h"
>  
>  /* Initial value for SRC control register: all timers use MXTAL/8 source */
>  #define SRC_CR_INIT_MASK	0x00007fff
>  #define SRC_CR_INIT_VAL		0x2aaa8000
>  
> +#define ALE_OFF 0x1000000
> +#define CLE_OFF 0x800000
> +
>  /* These addresses span 16MB, so use three individual pages */
>  static struct resource nhk8815_nand_resources[] = {
>  	{
> @@ -53,6 +54,16 @@ static struct resource nhk8815_nand_resources[] = {
>  		.end = 0x40000000 + SZ_16K - 1,
>  		.flags = IORESOURCE_MEM,
>  	}, {
> +		.name = "nand_addr",
> +		.start = 0x40000000 + ALE_OFF,
> +		.end = 0x40000000 +ALE_OFF + SZ_16K - 1,
> +		.flags = IORESOURCE_MEM,
> +	}, {
> +		.name = "nand_cmd",
> +		.start = 0x40000000 + CLE_OFF,
> +		.end = 0x40000000 + CLE_OFF + SZ_16K - 1,
> +		.flags = IORESOURCE_MEM,
> +	}, {
>  		.name  = "fsmc_regs",
>  		.start = NOMADIK_FSMC_BASE,
>  		.end   = NOMADIK_FSMC_BASE + SZ_4K - 1,
> @@ -105,8 +116,6 @@ static struct fsmc_nand_platform_data nhk8815_nand_platform_data = {
>  	.partitions = nhk8815_partitions,
>  	.nr_partitions = ARRAY_SIZE(nhk8815_partitions),
>  	.width = FSMC_NAND_BW8,
> -	.ale_off = 0x1000000,
> -	.cle_off = 0x800000,
>  };
>  
>  static struct platform_device nhk8815_nand_device = {
> @@ -171,6 +180,10 @@ static struct platform_device nhk8815_onenand_device = {
>  	.num_resources	= ARRAY_SIZE(nhk8815_onenand_resource),
>  };
>  
> +/* bus control reg. and bus timing reg. for CS0..CS3 */
> +#define FSMC_BCR(x)	(NOMADIK_FSMC_VA + (x << 3))
> +#define FSMC_BTR(x)	(NOMADIK_FSMC_VA + (x << 3) + 0x04)
> +
>  static void __init nhk8815_onenand_init(void)
>  {
>  #ifdef CONFIG_MTD_ONENAND
> -- 
> 1.7.11.4
> 


From vapier.adi at gmail.com  Fri Oct 12 12:09:19 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Fri, 12 Oct 2012 12:09:19 -0400
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
In-Reply-To: <20121012072221.GB639@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
 <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
 <5077B167.40009@snapgear.com> <20121012072221.GB639@pengutronix.de>
Message-ID: <CAMjpGUf0Jq_fPCHsUwN+OFL-RJSA2a-Usqih39hc22jM8Q7KNg@mail.gmail.com>

On Fri, Oct 12, 2012 at 3:22 AM, Uwe Kleine-K?nig wrote:
> On Fri, Oct 12, 2012 at 03:57:59PM +1000, Greg Ungerer wrote:
>> >so to be clear, Uwe's patch hasn't been picked up by anyone yet so we
>> >can get it fixed first ?
>
> ok, so for blackfin uclinux_ram_map must not be static because it is
> used in arch/blackfin/kernel/setup.c. If I tried to introduce such code
> for an ARM platform people would run away scared maybe after telling me
> I should fix my boot loader.

i would point out that code merged many many years ago had a much
lower bar than today.  also, this isn't the boot loader passing the
rootfs into the kernel.  when the kernel is created, the build system
appends the rootfs to it.

> I really don't know the situation on
> blackfin, but this really has potential for generalisation.

sure ... we're open to doing it differently as long as it's backwards compatible

> But I don't even know if you have/need a boot loader at all there.

we run u-boot like everyone else, but u-boot doesn't handle passing
the rootfs in.

> Here is what I found quickly:

updated comments here look nice, thanks
-mike


From vapier.adi at gmail.com  Fri Oct 12 12:18:41 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Fri, 12 Oct 2012 12:18:41 -0400
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
In-Reply-To: <20121012074100.GC639@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <CAMjpGUcRni7ni-FtVAN-pqnuHDK-WeeO6U=480K=1sCDhb7qjQ@mail.gmail.com>
 <20121012074100.GC639@pengutronix.de>
Message-ID: <CAMjpGUdKf98R1=YrAYBc8qv=soTq2erK6ievNwyWJZDkFwxNAA@mail.gmail.com>

On Fri, Oct 12, 2012 at 3:41 AM, Uwe Kleine-K?nig wrote:
> On Thu, Oct 11, 2012 at 12:21:59AM -0400, Mike Frysinger wrote:
>> i don't think's necessary either for the larger change here.  use the logic:
>>     if (physaddr != -1)
>>         mapp->phys = physaddr;
>> and keep the default initialization.
>
> I keep my way as it seems to be more robust for possible future changes.
> (I don't know if that will ever happen, but consider platform device
> support or just a retry of instatiation after physaddr changed from
> something back to -1.)

i'm afraid that will still break things.  the arch code initializes
the mtd map in setup_arch() which i believe is before the
module_init() (which is device_initcall() when it is compiled into).
so clobbering uclinux_ram_map.phys in the module_init will undo what
was done in setup_arch().
-mike


From vapier.adi at gmail.com  Fri Oct 12 12:22:54 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Fri, 12 Oct 2012 12:22:54 -0400
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the base
 address
In-Reply-To: <CAMjpGUf0Jq_fPCHsUwN+OFL-RJSA2a-Usqih39hc22jM8Q7KNg@mail.gmail.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
 <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
 <5077B167.40009@snapgear.com> <20121012072221.GB639@pengutronix.de>
 <CAMjpGUf0Jq_fPCHsUwN+OFL-RJSA2a-Usqih39hc22jM8Q7KNg@mail.gmail.com>
Message-ID: <CAMjpGUfpmUSBhk7QWexqXUtiuG=BFFuexnneyVbMWmoTDHxZgA@mail.gmail.com>

On Fri, Oct 12, 2012 at 12:09 PM, Mike Frysinger wrote:
> On Fri, Oct 12, 2012 at 3:22 AM, Uwe Kleine-K?nig wrote:
>> I really don't know the situation on
>> blackfin, but this really has potential for generalisation.
>
> sure ... we're open to doing it differently as long as it's backwards compatible

thinking a bit more, i think the answer here is:
 - move all the mtd_size checks out of Blackfin's memory_setup() into
the uclinux mtd map's uclinux_mtd_init() logic
 - rename your new physaddr to "uclinux_ram_map_physaddr", drop the
"static", and add a comment that this needs to stay externally visible
 - change Blackfin's memory_setup() logic to set
"uclinux_ram_map_physaddr" rather than "uclinux_ram_map"
-mike


From vapier.adi at gmail.com  Fri Oct 12 12:23:47 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Fri, 12 Oct 2012 12:23:47 -0400
Subject: [PATCH 2/2] mtd/uclinux: add a comment about why uclinux_ram_map
 must not be static
In-Reply-To: <1350027693-19528-2-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-2-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <CAMjpGUd4t4fVeK+OsKGij4LcQS=mL-pGb+vRpT=wjK7Kn+GRJQ@mail.gmail.com>

On Fri, Oct 12, 2012 at 3:41 AM, Uwe Kleine-K?nig wrote:
> I was (at least) the second person trying to fix a warning by sparse, so
> document in the code why this is a bad idea.

Acked-by: Mike Frysinger <vapier at gentoo.org>
-mike


From shijie8 at gmail.com  Sat Oct 13 13:03:29 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Sat, 13 Oct 2012 13:03:29 -0400
Subject: [PATCH] mtd: gpmi: remove unneccessary header
Message-ID: <1350147809-19616-1-git-send-email-shijie8@gmail.com>

The whole gpmi-nand driver has turned to pure devicetree supported.
So the linux/mtd/gpmi-nand.h is not neccessary now. Just remove it,
and move some macros to the gpmi-nand driver itself.

Signed-off-by: Huang Shijie <shijie8 at gmail.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |    1 -
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    7 +++-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |    1 -
 include/linux/mtd/gpmi-nand.h          |   68 --------------------------------
 4 files changed, 6 insertions(+), 71 deletions(-)
 delete mode 100644 include/linux/mtd/gpmi-nand.h

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 3502acc..1585c5b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -18,7 +18,6 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#include <linux/mtd/gpmi-nand.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index e2c56fc..d376198 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/mtd/gpmi-nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/of.h>
@@ -33,6 +32,12 @@
 #include <linux/of_mtd.h>
 #include "gpmi-nand.h"
 
+/* Resource names for the GPMI NAND driver. */
+#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
+#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
+#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
+#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
+
 /* add our owner bbt descriptor */
 static uint8_t scan_ff_pattern[] = { 0xff };
 static struct nand_bbt_descr gpmi_bbt_descr = {
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 7ac25c1..3d93a5e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -130,7 +130,6 @@ struct gpmi_nand_data {
 	/* System Interface */
 	struct device		*dev;
 	struct platform_device	*pdev;
-	struct gpmi_nand_platform_data	*pdata;
 
 	/* Resources */
 	struct resources	resources;
diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h
deleted file mode 100644
index ed3c4e0..0000000
--- a/include/linux/mtd/gpmi-nand.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __MACH_MXS_GPMI_NAND_H__
-#define __MACH_MXS_GPMI_NAND_H__
-
-/* The size of the resources is fixed. */
-#define GPMI_NAND_RES_SIZE	6
-
-/* Resource names for the GPMI NAND driver. */
-#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
-#define GPMI_NAND_GPMI_INTERRUPT_RES_NAME  "GPMI NAND GPMI Interrupt"
-#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
-#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
-#define GPMI_NAND_DMA_CHANNELS_RES_NAME    "GPMI NAND DMA Channels"
-#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
-
-/**
- * struct gpmi_nand_platform_data - GPMI NAND driver platform data.
- *
- * This structure communicates platform-specific information to the GPMI NAND
- * driver that can't be expressed as resources.
- *
- * @platform_init:           A pointer to a function the driver will call to
- *                           initialize the platform (e.g., set up the pin mux).
- * @min_prop_delay_in_ns:    Minimum propagation delay of GPMI signals to and
- *                           from the NAND Flash device, in nanoseconds.
- * @max_prop_delay_in_ns:    Maximum propagation delay of GPMI signals to and
- *                           from the NAND Flash device, in nanoseconds.
- * @max_chip_count:          The maximum number of chips for which the driver
- *                           should configure the hardware. This value most
- *                           likely reflects the number of pins that are
- *                           connected to a NAND Flash device. If this is
- *                           greater than the SoC hardware can support, the
- *                           driver will print a message and fail to initialize.
- * @partitions:              An optional pointer to an array of partition
- *                           descriptions.
- * @partition_count:         The number of elements in the partitions array.
- */
-struct gpmi_nand_platform_data {
-	/* SoC hardware information. */
-	int		(*platform_init)(void);
-
-	/* NAND Flash information. */
-	unsigned int	min_prop_delay_in_ns;
-	unsigned int	max_prop_delay_in_ns;
-	unsigned int	max_chip_count;
-
-	/* Medium information. */
-	struct		mtd_partition *partitions;
-	unsigned	partition_count;
-};
-#endif
-- 
1.7.4.4



From elba_estrada at inah.gob.mx  Sat Oct 13 05:03:50 2012
From: elba_estrada at inah.gob.mx (CHEVRON TEXACO DEVELOPMENT FUNDS)
Date: Sat, 13 Oct 2012 04:03:50 -0500 (CDT)
Subject: CONGRATULATIONS!
Message-ID: <1444302763.170800.1350119030764.JavaMail.root@tonali.inah.gob.mx>



From elba_estrada at inah.gob.mx  Sat Oct 13 05:08:18 2012
From: elba_estrada at inah.gob.mx (CHEVRON TEXACO DEVELOPMENT FUNDS)
Date: Sat, 13 Oct 2012 04:08:18 -0500 (CDT)
Subject: Attention
Message-ID: <578553053.170803.1350119298603.JavaMail.root@tonali.inah.gob.mx>



From plagnioj at jcrosoft.com  Sat Oct 13 08:06:22 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 13 Oct 2012 14:06:22 +0200
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc,
 gpio and ioremap
Message-ID: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>

this will allow to simply the error and remove path

Cc: linux-mtd at lists.infradead.org
Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
 drivers/mtd/nand/atmel_nand.c |  163 ++++++++++++++---------------------------
 1 file changed, 54 insertions(+), 109 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 92623ac..2b43656 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -364,43 +364,33 @@ static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
 			table_size * sizeof(int16_t);
 }
 
-static void pmecc_data_free(struct atmel_nand_host *host)
-{
-	kfree(host->pmecc_partial_syn);
-	kfree(host->pmecc_si);
-	kfree(host->pmecc_lmu);
-	kfree(host->pmecc_smu);
-	kfree(host->pmecc_mu);
-	kfree(host->pmecc_dmu);
-	kfree(host->pmecc_delta);
-}
-
 static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
 {
 	const int cap = host->pmecc_corr_cap;
+	int size;
+
+	size = (2 * cap + 1) * sizeof(int16_t);
+	host->pmecc_partial_syn = devm_kzalloc(host->dev, size, GFP_KERNEL);
+	host->pmecc_si = devm_kzalloc(host->dev, size, GFP_KERNEL);
+	host->pmecc_lmu = devm_kzalloc(host->dev,
+			(cap + 1) * sizeof(int16_t), GFP_KERNEL);
+	host->pmecc_smu = devm_kzalloc(host->dev,
+			(cap + 2) * (2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
+	size = (cap + 1) * sizeof(int);
+	host->pmecc_mu = devm_kzalloc(host->dev, size, GFP_KERNEL);
+	host->pmecc_dmu = devm_kzalloc(host->dev, size, GFP_KERNEL);
+	host->pmecc_delta = devm_kzalloc(host->dev, size, GFP_KERNEL);
+
+	if (!host->pmecc_partial_syn ||
+		!host->pmecc_si ||
+		!host->pmecc_lmu ||
+		!host->pmecc_smu ||
+		!host->pmecc_mu ||
+		!host->pmecc_dmu ||
+		!host->pmecc_delta)
+		return -ENOMEM;
 
-	host->pmecc_partial_syn = kzalloc((2 * cap + 1) * sizeof(int16_t),
-					GFP_KERNEL);
-	host->pmecc_si = kzalloc((2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
-	host->pmecc_lmu = kzalloc((cap + 1) * sizeof(int16_t), GFP_KERNEL);
-	host->pmecc_smu = kzalloc((cap + 2) * (2 * cap + 1) * sizeof(int16_t),
-					GFP_KERNEL);
-	host->pmecc_mu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
-	host->pmecc_dmu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
-	host->pmecc_delta = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
-
-	if (host->pmecc_partial_syn &&
-			host->pmecc_si &&
-			host->pmecc_lmu &&
-			host->pmecc_smu &&
-			host->pmecc_mu &&
-			host->pmecc_dmu &&
-			host->pmecc_delta)
-		return 0;
-
-	/* error happened */
-	pmecc_data_free(host);
-	return -ENOMEM;
+	return 0;
 }
 
 static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
@@ -923,27 +913,25 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
 		return 0;
 	}
 
-	host->ecc = ioremap(regs->start, resource_size(regs));
+	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
 	if (host->ecc == NULL) {
 		dev_err(host->dev, "ioremap failed\n");
 		err_no = -EIO;
-		goto err_pmecc_ioremap;
+		goto err;
 	}
 
 	regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
 	regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3);
 	if (regs_pmerr && regs_rom) {
-		host->pmerrloc_base = ioremap(regs_pmerr->start,
-			resource_size(regs_pmerr));
-		host->pmecc_rom_base = ioremap(regs_rom->start,
-			resource_size(regs_rom));
+		host->pmerrloc_base = devm_request_and_ioremap(&pdev->dev, regs_pmerr);
+		host->pmecc_rom_base = devm_request_and_ioremap(&pdev->dev, regs_rom);
 	}
 
 	if (!host->pmerrloc_base || !host->pmecc_rom_base) {
 		dev_err(host->dev,
 			"Can not get I/O resource for PMECC ERRLOC controller or ROM!\n");
 		err_no = -EIO;
-		goto err_pmloc_ioremap;
+		goto err;
 	}
 
 	/* ECC is calculated for the whole page (1 step) */
@@ -968,7 +956,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
 		if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
 			dev_err(host->dev, "No room for ECC bytes\n");
 			err_no = -EINVAL;
-			goto err_no_ecc_room;
+			goto err;
 		}
 		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
 					mtd->oobsize,
@@ -993,7 +981,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
 	if (err_no) {
 		dev_err(host->dev,
 				"Cannot allocate memory for PMECC computation!\n");
-		goto err_pmecc_data_alloc;
+		goto err;
 	}
 
 	nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
@@ -1003,15 +991,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
 
 	return 0;
 
-err_pmecc_data_alloc:
-err_no_ecc_room:
-err_pmloc_ioremap:
-	iounmap(host->ecc);
-	if (host->pmerrloc_base)
-		iounmap(host->pmerrloc_base);
-	if (host->pmecc_rom_base)
-		iounmap(host->pmecc_rom_base);
-err_pmecc_ioremap:
+err:
 	return err_no;
 }
 
@@ -1315,7 +1295,7 @@ static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
 		return 0;
 	}
 
-	host->ecc = ioremap(regs->start, resource_size(regs));
+	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
 	if (host->ecc == NULL) {
 		dev_err(host->dev, "ioremap failed\n");
 		return -EIO;
@@ -1380,20 +1360,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 	}
 
 	/* Allocate memory for the device structure (and zero it) */
-	host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
+	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
 	if (!host) {
 		printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n");
 		return -ENOMEM;
 	}
 
-	host->io_phys = (dma_addr_t)mem->start;
-
-	host->io_base = ioremap(mem->start, resource_size(mem));
+	host->io_base = devm_request_and_ioremap(&pdev->dev, mem);
 	if (host->io_base == NULL) {
 		printk(KERN_ERR "atmel_nand: ioremap failed\n");
 		res = -EIO;
 		goto err_nand_ioremap;
 	}
+	host->io_phys = (dma_addr_t)mem->start;
 
 	mtd = &host->mtd;
 	nand_chip = &host->nand_chip;
@@ -1401,7 +1380,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 	if (pdev->dev.of_node) {
 		res = atmel_of_init_port(host, pdev->dev.of_node);
 		if (res)
-			goto err_ecc_ioremap;
+			goto err_nand_ioremap;
 	} else {
 		memcpy(&host->board, pdev->dev.platform_data,
 		       sizeof(struct atmel_nand_data));
@@ -1420,44 +1399,42 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 	if (IS_ERR(pinctrl)) {
 		dev_err(host->dev, "Failed to request pinctrl\n");
 		res = PTR_ERR(pinctrl);
-		goto err_ecc_ioremap;
+		goto err_nand_ioremap;
 	}
 
 	if (gpio_is_valid(host->board.rdy_pin)) {
-		res = gpio_request(host->board.rdy_pin, "nand_rdy");
+		res = devm_gpio_request(&pdev->dev,
+				host->board.rdy_pin, "nand_rdy");
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request rdy gpio %d\n",
-				host->board.rdy_pin);
-			goto err_ecc_ioremap;
+				"can't request rdy gpio %d\n", host->board.rdy_pin);
+			goto err_nand_ioremap;
 		}
 
 		res = gpio_direction_input(host->board.rdy_pin);
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request input direction rdy gpio %d\n",
-				host->board.rdy_pin);
-			goto err_ecc_ioremap;
+				"can't request input direction rdy gpio %d\n", host->board.rdy_pin);
+			goto err_nand_ioremap;
 		}
 
 		nand_chip->dev_ready = atmel_nand_device_ready;
 	}
 
 	if (gpio_is_valid(host->board.enable_pin)) {
-		res = gpio_request(host->board.enable_pin, "nand_enable");
+		res = devm_gpio_request(&pdev->dev,
+				host->board.enable_pin, "nand_enable");
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request enable gpio %d\n",
-				host->board.enable_pin);
-			goto err_ecc_ioremap;
+				"can't request enable gpio %d\n", host->board.enable_pin);
+			goto err_nand_ioremap;
 		}
 
 		res = gpio_direction_output(host->board.enable_pin, 1);
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request output direction enable gpio %d\n",
-				host->board.enable_pin);
-			goto err_ecc_ioremap;
+				"can't request output direction enable gpio %d\n", host->board.enable_pin);
+			goto err_nand_ioremap;
 		}
 	}
 
@@ -1474,19 +1451,18 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 	atmel_nand_enable(host);
 
 	if (gpio_is_valid(host->board.det_pin)) {
-		res = gpio_request(host->board.det_pin, "nand_det");
+		res = devm_gpio_request(&pdev->dev,
+				host->board.det_pin, "nand_det");
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request det gpio %d\n",
-				host->board.det_pin);
+				"can't request det gpio %d\n", host->board.det_pin);
 			goto err_no_card;
 		}
 
 		res = gpio_direction_input(host->board.det_pin);
 		if (res < 0) {
 			dev_err(&pdev->dev,
-				"can't request input direction det gpio %d\n",
-				host->board.det_pin);
+				"can't request input direction det gpio %d\n", host->board.det_pin);
 			goto err_no_card;
 		}
 
@@ -1552,16 +1528,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 		return res;
 
 err_scan_tail:
-	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
+	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW)
 		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
-		pmecc_data_free(host);
-	}
-	if (host->ecc)
-		iounmap(host->ecc);
-	if (host->pmerrloc_base)
-		iounmap(host->pmerrloc_base);
-	if (host->pmecc_rom_base)
-		iounmap(host->pmecc_rom_base);
 err_hw_ecc:
 err_scan_ident:
 err_no_card:
@@ -1569,10 +1537,7 @@ err_no_card:
 	platform_set_drvdata(pdev, NULL);
 	if (host->dma_chan)
 		dma_release_channel(host->dma_chan);
-err_ecc_ioremap:
-	iounmap(host->io_base);
 err_nand_ioremap:
-	kfree(host);
 	return res;
 }
 
@@ -1592,31 +1557,11 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
 		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
 		pmerrloc_writel(host->pmerrloc_base, ELDIS,
 				PMERRLOC_DISABLE);
-		pmecc_data_free(host);
 	}
 
-	if (gpio_is_valid(host->board.det_pin))
-		gpio_free(host->board.det_pin);
-
-	if (gpio_is_valid(host->board.enable_pin))
-		gpio_free(host->board.enable_pin);
-
-	if (gpio_is_valid(host->board.rdy_pin))
-		gpio_free(host->board.rdy_pin);
-
-	if (host->ecc)
-		iounmap(host->ecc);
-	if (host->pmecc_rom_base)
-		iounmap(host->pmecc_rom_base);
-	if (host->pmerrloc_base)
-		iounmap(host->pmerrloc_base);
-
 	if (host->dma_chan)
 		dma_release_channel(host->dma_chan);
 
-	iounmap(host->io_base);
-	kfree(host);
-
 	return 0;
 }
 
-- 
1.7.10.4



From vikram186 at gmail.com  Sun Oct 14 05:10:26 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Sun, 14 Oct 2012 14:40:26 +0530
Subject: [PATCH RESEND 9/9] mtd: mtd_oobtest: printk -> pr_{info, err,
 crit}
In-Reply-To: <5075B36A.3050009@gmail.com>
References: <5075B105.4080701@gmail.com> <5075B36A.3050009@gmail.com>
Message-ID: <507A8182.8070003@gmail.com>

>From a1969e36d924285da0200c8b932b79165ff7df87 Mon Sep 17 00:00:00 2001
From: Brian Norris <computersforpeace at gmail.com>
Date: Wed, 26 Sep 2012 16:37:02 +0000
Subject: [PATCH RESEND 9/9] mtd: mtd_oobtest: printk -> pr_{info,err,crit}

Use pr_info() and pr_err() while defining pr_fmt(). This saves a few
characters, joins a few lines, and makes the code a little more readable
(and grep-able).

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Vikram Narayanan <vikram186 at gmail.com>
---
Posting this patch with the headers, as Brian is the original author.
Please take this one and discard the previously posted patch.

 drivers/mtd/tests/mtd_oobtest.c |  171 +++++++++++++++++++--------------------
 1 files changed, 84 insertions(+), 87 deletions(-)

diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index ed9b628..e86bb29 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -19,6 +19,8 @@
  * Author: Adrian Hunter <ext-adrian.hunter at nokia.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <asm/div64.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -28,8 +30,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 
-#define PRINT_PREF KERN_INFO "mtd_oobtest: "
-
 static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -80,13 +80,12 @@ static int erase_eraseblock(int ebnum)
 
 	err = mtd_erase(mtd, &ei);
 	if (err) {
-		printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum);
+		pr_err("error %d while erasing EB %d\n", err, ebnum);
 		return err;
 	}
 
 	if (ei.state == MTD_ERASE_FAILED) {
-		printk(PRINT_PREF "some erase error occurred at EB %d\n",
-		       ebnum);
+		pr_err("some erase error occurred at EB %d\n", ebnum);
 		return -EIO;
 	}
 
@@ -98,7 +97,7 @@ static int erase_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "erasing whole device\n");
+	pr_info("erasing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -107,7 +106,7 @@ static int erase_whole_device(void)
 			return err;
 		cond_resched();
 	}
-	printk(PRINT_PREF "erased %u eraseblocks\n", i);
+	pr_info("erased %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -141,9 +140,9 @@ static int write_eraseblock(int ebnum)
 		ops.oobbuf    = writebuf;
 		err = mtd_write_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
-			printk(PRINT_PREF "error: writeoob failed at %#llx\n",
+			pr_err("error: writeoob failed at %#llx\n",
 			       (long long)addr);
-			printk(PRINT_PREF "error: use_len %d, use_offset %d\n",
+			pr_err("error: use_len %d, use_offset %d\n",
 			       use_len, use_offset);
 			errcnt += 1;
 			return err ? err : -1;
@@ -160,7 +159,7 @@ static int write_whole_device(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "writing OOBs of whole device\n");
+	pr_info("writing OOBs of whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -168,10 +167,10 @@ static int write_whole_device(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "written up to eraseblock %u\n", i);
+			pr_info("written up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -194,17 +193,17 @@ static int verify_eraseblock(int ebnum)
 		ops.oobbuf    = readbuf;
 		err = mtd_read_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
-			printk(PRINT_PREF "error: readoob failed at %#llx\n",
+			pr_err("error: readoob failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			return err ? err : -1;
 		}
 		if (memcmp(readbuf, writebuf, use_len)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			if (errcnt > 1000) {
-				printk(PRINT_PREF "error: too many errors\n");
+				pr_err("error: too many errors\n");
 				return -1;
 			}
 		}
@@ -221,29 +220,28 @@ static int verify_eraseblock(int ebnum)
 			ops.oobbuf    = readbuf;
 			err = mtd_read_oob(mtd, addr, &ops);
 			if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
-				printk(PRINT_PREF "error: readoob failed at "
-				       "%#llx\n", (long long)addr);
+				pr_err("error: readoob failed at %#llx\n",
+						(long long)addr);
 				errcnt += 1;
 				return err ? err : -1;
 			}
 			if (memcmp(readbuf + use_offset, writebuf, use_len)) {
-				printk(PRINT_PREF "error: verify failed at "
-				       "%#llx\n", (long long)addr);
+				pr_err("error: verify failed at %#llx\n",
+						(long long)addr);
 				errcnt += 1;
 				if (errcnt > 1000) {
-					printk(PRINT_PREF "error: too many "
-					       "errors\n");
+					pr_err("error: too many errors\n");
 					return -1;
 				}
 			}
 			for (k = 0; k < use_offset; ++k)
 				if (readbuf[k] != 0xff) {
-					printk(PRINT_PREF "error: verify 0xff "
+					pr_err("error: verify 0xff "
 					       "failed at %#llx\n",
 					       (long long)addr);
 					errcnt += 1;
 					if (errcnt > 1000) {
-						printk(PRINT_PREF "error: too "
+						pr_err("error: too "
 						       "many errors\n");
 						return -1;
 					}
@@ -251,12 +249,12 @@ static int verify_eraseblock(int ebnum)
 			for (k = use_offset + use_len;
 			     k < mtd->ecclayout->oobavail; ++k)
 				if (readbuf[k] != 0xff) {
-					printk(PRINT_PREF "error: verify 0xff "
+					pr_err("error: verify 0xff "
 					       "failed at %#llx\n",
 					       (long long)addr);
 					errcnt += 1;
 					if (errcnt > 1000) {
-						printk(PRINT_PREF "error: too "
+						pr_err("error: too "
 						       "many errors\n");
 						return -1;
 					}
@@ -286,17 +284,17 @@ static int verify_eraseblock_in_one_go(int ebnum)
 	ops.oobbuf    = readbuf;
 	err = mtd_read_oob(mtd, addr, &ops);
 	if (err || ops.oobretlen != len) {
-		printk(PRINT_PREF "error: readoob failed at %#llx\n",
+		pr_err("error: readoob failed at %#llx\n",
 		       (long long)addr);
 		errcnt += 1;
 		return err ? err : -1;
 	}
 	if (memcmp(readbuf, writebuf, len)) {
-		printk(PRINT_PREF "error: verify failed at %#llx\n",
+		pr_err("error: verify failed at %#llx\n",
 		       (long long)addr);
 		errcnt += 1;
 		if (errcnt > 1000) {
-			printk(PRINT_PREF "error: too many errors\n");
+			pr_err("error: too many errors\n");
 			return -1;
 		}
 	}
@@ -309,7 +307,7 @@ static int verify_all_eraseblocks(void)
 	int err;
 	unsigned int i;
 
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -317,10 +315,10 @@ static int verify_all_eraseblocks(void)
 		if (err)
 			return err;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 	return 0;
 }
 
@@ -331,7 +329,7 @@ static int is_block_bad(int ebnum)
 
 	ret = mtd_block_isbad(mtd, addr);
 	if (ret)
-		printk(PRINT_PREF "block %d is bad\n", ebnum);
+		pr_info("block %d is bad\n", ebnum);
 	return ret;
 }
 
@@ -341,18 +339,18 @@ static int scan_for_bad_eraseblocks(void)
 
 	bbt = kmalloc(ebcnt, GFP_KERNEL);
 	if (!bbt) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		return -ENOMEM;
 	}
 
-	printk(PRINT_PREF "scanning for bad eraseblocks\n");
+	pr_info("scanning for bad eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		bbt[i] = is_block_bad(i) ? 1 : 0;
 		if (bbt[i])
 			bad += 1;
 		cond_resched();
 	}
-	printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad);
+	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 	return 0;
 }
 
@@ -368,22 +366,22 @@ static int __init mtd_oobtest_init(void)
 	printk(KERN_INFO "=================================================\n");
 
 	if (dev < 0) {
-		printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
-		printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+		pr_info("Please specify a valid mtd-device via module paramter\n");
+		pr_crit(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
 		return -EINVAL;
 	}
 
-	printk(PRINT_PREF "MTD device: %d\n", dev);
+	pr_info("MTD device: %d\n", dev);
 
 	mtd = get_mtd_device(NULL, dev);
 	if (IS_ERR(mtd)) {
 		err = PTR_ERR(mtd);
-		printk(PRINT_PREF "error: cannot get MTD device\n");
+		pr_err("error: cannot get MTD device\n");
 		return err;
 	}
 
 	if (mtd->type != MTD_NANDFLASH) {
-		printk(PRINT_PREF "this test requires NAND flash\n");
+		pr_info("this test requires NAND flash\n");
 		goto out;
 	}
 
@@ -392,7 +390,7 @@ static int __init mtd_oobtest_init(void)
 	ebcnt = tmp;
 	pgcnt = mtd->erasesize / mtd->writesize;
 
-	printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, "
+	pr_info("MTD device size %llu, eraseblock size %u, "
 	       "page size %u, count of eraseblocks %u, pages per "
 	       "eraseblock %u, OOB size %u\n",
 	       (unsigned long long)mtd->size, mtd->erasesize,
@@ -401,12 +399,12 @@ static int __init mtd_oobtest_init(void)
 	err = -ENOMEM;
 	readbuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!readbuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 	writebuf = kmalloc(mtd->erasesize, GFP_KERNEL);
 	if (!writebuf) {
-		printk(PRINT_PREF "error: cannot allocate memory\n");
+		pr_err("error: cannot allocate memory\n");
 		goto out;
 	}
 
@@ -420,7 +418,7 @@ static int __init mtd_oobtest_init(void)
 	vary_offset = 0;
 
 	/* First test: write all OOB, read it back and verify */
-	printk(PRINT_PREF "test 1 of 5\n");
+	pr_info("test 1 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -440,7 +438,7 @@ static int __init mtd_oobtest_init(void)
 	 * Second test: write all OOB, a block at a time, read it back and
 	 * verify.
 	 */
-	printk(PRINT_PREF "test 2 of 5\n");
+	pr_info("test 2 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -453,7 +451,7 @@ static int __init mtd_oobtest_init(void)
 
 	/* Check all eraseblocks */
 	simple_srand(3);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -461,16 +459,16 @@ static int __init mtd_oobtest_init(void)
 		if (err)
 			goto out;
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
 	/*
 	 * Third test: write OOB at varying offsets and lengths, read it back
 	 * and verify.
 	 */
-	printk(PRINT_PREF "test 3 of 5\n");
+	pr_info("test 3 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -503,7 +501,7 @@ static int __init mtd_oobtest_init(void)
 	vary_offset = 0;
 
 	/* Fourth test: try to write off end of device */
-	printk(PRINT_PREF "test 4 of 5\n");
+	pr_info("test 4 of 5\n");
 
 	err = erase_whole_device();
 	if (err)
@@ -522,14 +520,14 @@ static int __init mtd_oobtest_init(void)
 	ops.ooboffs   = mtd->ecclayout->oobavail;
 	ops.datbuf    = NULL;
 	ops.oobbuf    = writebuf;
-	printk(PRINT_PREF "attempting to start write past end of OOB\n");
-	printk(PRINT_PREF "an error is expected...\n");
+	pr_info("attempting to start write past end of OOB\n");
+	pr_info("an error is expected...\n");
 	err = mtd_write_oob(mtd, addr0, &ops);
 	if (err) {
-		printk(PRINT_PREF "error occurred as expected\n");
+		pr_info("error occurred as expected\n");
 		err = 0;
 	} else {
-		printk(PRINT_PREF "error: can write past end of OOB\n");
+		pr_err("error: can write past end of OOB\n");
 		errcnt += 1;
 	}
 
@@ -542,19 +540,19 @@ static int __init mtd_oobtest_init(void)
 	ops.ooboffs   = mtd->ecclayout->oobavail;
 	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
-	printk(PRINT_PREF "attempting to start read past end of OOB\n");
-	printk(PRINT_PREF "an error is expected...\n");
+	pr_info("attempting to start read past end of OOB\n");
+	pr_info("an error is expected...\n");
 	err = mtd_read_oob(mtd, addr0, &ops);
 	if (err) {
-		printk(PRINT_PREF "error occurred as expected\n");
+		pr_info("error occurred as expected\n");
 		err = 0;
 	} else {
-		printk(PRINT_PREF "error: can read past end of OOB\n");
+		pr_err("error: can read past end of OOB\n");
 		errcnt += 1;
 	}
 
 	if (bbt[ebcnt - 1])
-		printk(PRINT_PREF "skipping end of device tests because last "
+		pr_info("skipping end of device tests because last "
 		       "block is bad\n");
 	else {
 		/* Attempt to write off end of device */
@@ -566,14 +564,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 0;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
-		printk(PRINT_PREF "attempting to write past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to write past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: wrote past end of device\n");
+			pr_err("error: wrote past end of device\n");
 			errcnt += 1;
 		}
 
@@ -586,14 +584,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 0;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
-		printk(PRINT_PREF "attempting to read past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to read past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read past end of device\n");
+			pr_err("error: read past end of device\n");
 			errcnt += 1;
 		}
 
@@ -610,14 +608,14 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 1;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
-		printk(PRINT_PREF "attempting to write past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to write past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: wrote past end of device\n");
+			pr_err("error: wrote past end of device\n");
 			errcnt += 1;
 		}
 
@@ -630,20 +628,20 @@ static int __init mtd_oobtest_init(void)
 		ops.ooboffs   = 1;
 		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
-		printk(PRINT_PREF "attempting to read past end of device\n");
-		printk(PRINT_PREF "an error is expected...\n");
+		pr_info("attempting to read past end of device\n");
+		pr_info("an error is expected...\n");
 		err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops);
 		if (err) {
-			printk(PRINT_PREF "error occurred as expected\n");
+			pr_info("error occurred as expected\n");
 			err = 0;
 		} else {
-			printk(PRINT_PREF "error: read past end of device\n");
+			pr_err("error: read past end of device\n");
 			errcnt += 1;
 		}
 	}
 
 	/* Fifth test: write / read across block boundaries */
-	printk(PRINT_PREF "test 5 of 5\n");
+	pr_info("test 5 of 5\n");
 
 	/* Erase all eraseblocks */
 	err = erase_whole_device();
@@ -652,7 +650,7 @@ static int __init mtd_oobtest_init(void)
 
 	/* Write all eraseblocks */
 	simple_srand(11);
-	printk(PRINT_PREF "writing OOBs of whole device\n");
+	pr_info("writing OOBs of whole device\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		int cnt = 2;
 		int pg;
@@ -674,17 +672,16 @@ static int __init mtd_oobtest_init(void)
 			if (err)
 				goto out;
 			if (i % 256 == 0)
-				printk(PRINT_PREF "written up to eraseblock "
-				       "%u\n", i);
+				pr_info("written up to eraseblock %u\n", i);
 			cond_resched();
 			addr += mtd->writesize;
 		}
 	}
-	printk(PRINT_PREF "written %u eraseblocks\n", i);
+	pr_info("written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
 	simple_srand(11);
-	printk(PRINT_PREF "verifying all eraseblocks\n");
+	pr_info("verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		if (bbt[i] || bbt[i + 1])
 			continue;
@@ -702,28 +699,28 @@ static int __init mtd_oobtest_init(void)
 		if (err)
 			goto out;
 		if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) {
-			printk(PRINT_PREF "error: verify failed at %#llx\n",
+			pr_err("error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 			if (errcnt > 1000) {
-				printk(PRINT_PREF "error: too many errors\n");
+				pr_err("error: too many errors\n");
 				goto out;
 			}
 		}
 		if (i % 256 == 0)
-			printk(PRINT_PREF "verified up to eraseblock %u\n", i);
+			pr_info("verified up to eraseblock %u\n", i);
 		cond_resched();
 	}
-	printk(PRINT_PREF "verified %u eraseblocks\n", i);
+	pr_info("verified %u eraseblocks\n", i);
 
-	printk(PRINT_PREF "finished with %d errors\n", errcnt);
+	pr_info("finished with %d errors\n", errcnt);
 out:
 	kfree(bbt);
 	kfree(writebuf);
 	kfree(readbuf);
 	put_mtd_device(mtd);
 	if (err)
-		printk(PRINT_PREF "error %d occurred\n", err);
+		pr_info("error %d occurred\n", err);
 	printk(KERN_INFO "=================================================\n");
 	return err;
 }
-- 
1.7.4.1



From shijie8 at gmail.com  Sun Oct 14 23:47:24 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Sun, 14 Oct 2012 23:47:24 -0400
Subject: [PATCH] mtd: use the NAND_STATUS_FAIL to replace the hardcode
Message-ID: <1350272844-21866-1-git-send-email-shijie8@gmail.com>

Use the NAND_STATUS_FAIL to replace the hardcode "0x01",
which make the code more readable.

Signed-off-by: Huang Shijie <shijie8 at gmail.com>
---
 drivers/mtd/nand/nand_base.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d5ece6e..4569174 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 	/* Call wait ready function */
 	status = chip->waitfunc(mtd, chip);
 	/* See if device thinks it succeeded */
-	if (status & 0x01) {
+	if (status & NAND_STATUS_FAIL) {
 		pr_debug("%s: error status = 0x%08x\n",
 					__func__, status);
 		ret = -EIO;
@@ -1004,7 +1004,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	/* Call wait ready function */
 	status = chip->waitfunc(mtd, chip);
 	/* See if device thinks it succeeded */
-	if (status & 0x01) {
+	if (status & NAND_STATUS_FAIL) {
 		pr_debug("%s: error status = 0x%08x\n",
 					__func__, status);
 		ret = -EIO;
-- 
1.7.4.4



From mv at vanka.net  Sun Oct 14 14:30:02 2012
From: mv at vanka.net (Michal Vanka)
Date: Sun, 14 Oct 2012 20:30:02 +0200
Subject: [PATCH] Devicetree support for enc28j60 SPI Ethernet chip
Message-ID: <507B04AA.1050502@vanka.net>

Hi,
the following patch adds generic openfirmware/devicetree support to 
enc28j60 driver.

It also adds support for custom hardware based (FPGA) "interrupt line 
deasserter" for processors with level triggered interrupts
(for example Altera Nios2).

The interrupt line is deasserted by writing 1 to some output register
in the address space (this address is configured also through
devicetree).

Note: The interrupt line in enc28j60 chip can be deasserted by software
by clearing bit INTIE in the EIE register.
However this can't be done in interrupt context as the write goes
through SPI bus.

The patch was tested on custom Altera Nios2 system.

Signed-off-by: Michal Vanka <mv at vanka.net>

diff -uprN 
a/Documentation/devicetree/bindings/net/microchip-enc28j60.txt 
b/Documentation/devicetree/bindings/net/microchip-enc28j60.txt
--- a/Documentation/devicetree/bindings/net/microchip-enc28j60.txt 
1969-12-31 19:00:00.000000000 -0500
+++ b/Documentation/devicetree/bindings/net/microchip-enc28j60.txt 
2011-10-14 13:46:58.000000000 -0400
@@ -0,0 +1,31 @@
+* Microchip enc28j60 Ethernet
+
+Required properties:
+- compatible : Should be "microchip,enc28j60"
+- interrupts : Should contain 1 interrupt.
+- reg : Should be 0
+
+Optional properties:
+- interrupt_deassert_reg : should contain address of additional (FPGA)
+  interrupt deassert hardware for processors with level triggered 
interrupts
+
+
+Example (for enc28j60 under opencores tinyspi controller):
+
+tiny_spi_1: spi at 0x2160 {
+	compatible = "opencores,tiny-spi-1.0", "opencores,tiny-spi-rtlsvn2";
+	reg = < 0x00002160 0x00000020 >;
+	interrupt-parent = < &cpu >;
+	interrupts = < 2 >;
+	clock-frequency = < 100000000 >;
+	baud-width = < 8 >;	/* BAUD_WIDTH type NUMBER */
+	gpios = < &spi1_cs 0 0 >;
+	ethernet: enc28j60 at 0 {
+		compatible = "microchip,enc28j60";
+		spi-max-frequency = < 20000000 >;
+		reg = < 0 >;
+		interrupts = < 4 >;
+		interrupt_deassert_reg = < 0x00003000 >;
+	};			
+}; //end spi at 0x2160 (tiny_spi_1)
+
diff -uprN a/drivers/net/ethernet/microchip/enc28j60.c 
b/drivers/net/ethernet/microchip/enc28j60.c
--- a/drivers/net/ethernet/microchip/enc28j60.c	2011-10-02 
07:31:43.000000000 -0400
+++ b/drivers/net/ethernet/microchip/enc28j60.c	2011-10-14 
13:54:15.000000000 -0400
@@ -32,7 +32,7 @@
  #include "enc28j60_hw.h"

  #define DRV_NAME	"enc28j60"
-#define DRV_VERSION	"1.01"
+#define DRV_VERSION	"1.02"

  #define SPI_OPLEN	1

@@ -73,6 +73,7 @@ struct enc28j60_net {
  	int rxfilter;
  	u32 msg_enable;
  	u8 spi_transfer_buf[SPI_TRANSFER_BUF_LEN];
+	u8 *interrupt_deassert_reg;
  };

  /* use ethtool to change the level for any given device */
@@ -1320,6 +1321,10 @@ static irqreturn_t enc28j60_irq(int irq,
  	 * Remember that we access enc28j60 registers through SPI bus
  	 * via spi_sync() call.
  	 */
+
+	if(priv->interrupt_deassert_reg)
+		writeb(1,priv->interrupt_deassert_reg);
+
  	schedule_work(&priv->irq_work);

  	return IRQ_HANDLED;
@@ -1541,6 +1546,36 @@ static const struct net_device_ops enc28
  	.ndo_validate_addr	= eth_validate_addr,
  };

+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+static int __devinit enc28j60_of_probe(struct spi_device *spi,struct 
enc28j60_net *priv)
+{
+
+	u8 *reg;
+	const __be32 *prop;
+	int len;
+	
+	if (!of_device_is_available(spi->dev.of_node))
+		return -ENODEV;	
+
+	prop = of_get_property(spi->dev.of_node, "interrupt_deassert_reg", &len);
+	
+	if(prop && len>=sizeof(__be32))
+		reg = be32_to_cpup(prop);
+	else
+		return -ENODEV;
+
+	if(!devm_request_mem_region(&spi->dev, reg, 4, DRV_NAME))
+		return -ENOMEM;
+
+	priv->interrupt_deassert_reg = devm_ioremap_nocache(&spi->dev, reg, 4);
+	return 0;	
+}
+#endif
+
  static int __devinit enc28j60_probe(struct spi_device *spi)
  {
  	struct net_device *dev;
@@ -1569,6 +1604,10 @@ static int __devinit enc28j60_probe(stru
  	INIT_WORK(&priv->restart_work, enc28j60_restart_work_handler);
  	dev_set_drvdata(&spi->dev, priv);	/* spi to priv reference */
  	SET_NETDEV_DEV(dev, &spi->dev);
+	priv->interrupt_deassert_reg = 0;
+#ifdef CONFIG_OF
+	enc28j60_of_probe(spi,priv);
+#endif	

  	if (!enc28j60_chipset_init(dev)) {
  		if (netif_msg_probe(priv))
@@ -1631,10 +1670,20 @@ static int __devexit enc28j60_remove(str
  	return 0;
  }

+#ifdef CONFIG_OF
+static const struct of_device_id enc28j60_dt_ids[] = {
+	{ .compatible = "microchip,enc28j60", },
+	{ /* sentinel */ }
+};
+#else
+#define enc28j60_dt_ids NULL
+#endif
+
  static struct spi_driver enc28j60_driver = {
  	.driver = {
  		   .name = DRV_NAME,
  		   .owner = THIS_MODULE,
+		   .of_match_table = enc28j60_dt_ids,
  	 },
  	.probe = enc28j60_probe,
  	.remove = __devexit_p(enc28j60_remove),


From gerg at snapgear.com  Mon Oct 15 00:14:55 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Mon, 15 Oct 2012 14:14:55 +1000
Subject: [PATCH 1/2 RFC v2] mtd/uclinux: support ROM and allow passing
 the base address
In-Reply-To: <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <507B8DBF.2030104@snapgear.com>

Hi Uwe,

On 12/10/12 17:41, Uwe Kleine-K?nig wrote:
> This allows to put the filesystem at a defined address in ROM allowing
> to save more precious RAM.
>
> I think it's save to default to ROM because the intention of using the
                ^^^^
                safe

> uclinux map is to use a romfs and so mtd-ram doesn't give you anything
> that mtd-rom doesn't.
>
> Signed-off-by: Uwe Kleine-K??nig <u.kleine-koenig at pengutronix.de>

Unfortunately email to me goes through an exchange server and openchange,
and it manages to often mangle anything more than 7bit ascii. Not too
much I can do about it, sorry.


> Changed since (implicit) v1:
>
>   - don't make uclinux_ram_map static as pointed out by Mike and Greg.
>
>   drivers/mtd/maps/Kconfig   |    2 +-
>   drivers/mtd/maps/uclinux.c |   28 ++++++++++++++++++++++------
>   2 files changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> index 5ba2458..d945950 100644
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -443,7 +443,7 @@ config MTD_GPIO_ADDR
>
>   config MTD_UCLINUX
>   	bool "Generic uClinux RAM/ROM filesystem support"
> -	depends on MTD_RAM=y && !MMU
> +	depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
>   	help
>   	  Map driver to support image based filesystems for uClinux.
>
> diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
> index c3bb304..f5e8e9a 100644
> --- a/drivers/mtd/maps/uclinux.c
> +++ b/drivers/mtd/maps/uclinux.c
> @@ -24,11 +24,12 @@
>   /****************************************************************************/
>
>   struct map_info uclinux_ram_map = {
> -	.name = "RAM",
> -	.phys = (unsigned long)__bss_stop,
>   	.size = 0,
>   };
>
> +static unsigned long physaddr = -1;
> +module_param(physaddr, ulong, S_IRUGO);
> +
>   static struct mtd_info *uclinux_ram_mtdinfo;
>
>   /****************************************************************************/
> @@ -60,11 +61,17 @@ static int __init uclinux_mtd_init(void)
>   	struct map_info *mapp;
>
>   	mapp = &uclinux_ram_map;
> +
> +	if (physaddr == -1)
> +		mapp->phys = (resource_size_t)__bss_stop;
> +	else
> +		mapp->phys = physaddr;
> +
>   	if (!mapp->size)
>   		mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
>   	mapp->bankwidth = 4;
>
> -	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
> +	printk("uclinux[mtd]: RAM/ROM probe address=0x%x size=0x%x\n",
>   	       	(int) mapp->phys, (int) mapp->size);

Is there any value in saying "RAM/ROM"?
Why don't we just drop those chars altogether.


>
>   	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
> @@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
>
>   	simple_map_init(mapp);
>
> -	mtd = do_map_probe("map_ram", mapp);
> +	mapp->name = "ROM";
> +	mtd = do_map_probe("map_rom", mapp);
> +	if (!mtd) {
> +		/* fall back to ram probing for compatibility reasons */
> +		mapp->name = "RAM";
> +		mtd = do_map_probe("map_ram", mapp);
> +		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
> +			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");

Do we really want this message?
My predominate usage of this code is in RAM mappings. Network
loading kernel+filesystem images on bare boards. Anyone who wants
to know and is looking in the kernel boot messages will see
something like:

     Creating 1 MTD partitions on "RAM":
     0x000000000000-0x0000000d8000 : "ROMfs"

So they will know what type of mapping it was loaded from.


> +	}
> +
>   	if (!mtd) {
> -		printk("uclinux[mtd]: failed to find a mapping?\n");
> +		printk("uclinux[mtd]: failed to find a rom/ram mapping?\n");

Again, is there any point in changing this message?
Adding "rom/ram" doesn't add any value here.

Regards
Greg



>   		iounmap(mapp->virt);
>   		return(-ENXIO);
>   	}
> @@ -115,6 +131,6 @@ module_exit(uclinux_mtd_cleanup);
>
>   MODULE_LICENSE("GPL");
>   MODULE_AUTHOR("Greg Ungerer <gerg at snapgear.com>");
> -MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
> +MODULE_DESCRIPTION("Generic RAM/ROM based MTD for uClinux");
>
>   /****************************************************************************/
>


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From gerg at snapgear.com  Mon Oct 15 00:15:34 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Mon, 15 Oct 2012 14:15:34 +1000
Subject: [PATCH 2/2] mtd/uclinux: add a comment about why uclinux_ram_map
 must not be static
In-Reply-To: <1350027693-19528-2-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-2-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <507B8DE6.6030407@snapgear.com>

On 12/10/12 17:41, Uwe Kleine-K?nig wrote:
> I was (at least) the second person trying to fix a warning by sparse, so
> document in the code why this is a bad idea.
>
> Signed-off-by: Uwe Kleine-K??nig <u.kleine-koenig at pengutronix.de>

Acked-by: Greg Ungerer <gerg at uclinux.org>


> ---
> Hello,
>
> it's a bit exaggerated to claim that sparse is happy now, but at least
> we have one warning less :-)
>
> Uwe
>   drivers/mtd/maps/uclinux.c |    6 ++++++
>   1 file changed, 6 insertions(+)
>
> diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
> index f5e8e9a..18cf6d0 100644
> --- a/drivers/mtd/maps/uclinux.c
> +++ b/drivers/mtd/maps/uclinux.c
> @@ -23,6 +23,12 @@
>
>   /****************************************************************************/
>
> +/*
> + * Blackfin uses uclinux_ram_map during startup, so it must not be static.
> + * Provide a dummy declaration to make sparse happy.
> + */
> +extern struct map_info uclinux_ram_map;
> +
>   struct map_info uclinux_ram_map = {
>   	.size = 0,
>   };
>


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From u.kleine-koenig at pengutronix.de  Mon Oct 15 02:58:55 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Mon, 15 Oct 2012 08:58:55 +0200
Subject: [PATCH 1/2 RFC v2] mtd/uclinux: support ROM and allow passing
 the base address
In-Reply-To: <507B8DBF.2030104@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <507B8DBF.2030104@snapgear.com>
Message-ID: <20121015065855.GG639@pengutronix.de>

Hello,

On Mon, Oct 15, 2012 at 02:14:55PM +1000, Greg Ungerer wrote:
> Hi Uwe,
> 
> On 12/10/12 17:41, Uwe Kleine-K?nig wrote:
> >This allows to put the filesystem at a defined address in ROM allowing
> >to save more precious RAM.
> >
> >I think it's save to default to ROM because the intention of using the
>                ^^^^
>                safe
> 
> >uclinux map is to use a romfs and so mtd-ram doesn't give you anything
> >that mtd-rom doesn't.
> >
> >Signed-off-by: Uwe Kleine-K??nig <u.kleine-koenig at pengutronix.de>
> 
> Unfortunately email to me goes through an exchange server and openchange,
> and it manages to often mangle anything more than 7bit ascii. Not too
> much I can do about it, sorry.
hehe, so openchange is really MS compatible now? :-)
 
> >Changed since (implicit) v1:
> >
> >  - don't make uclinux_ram_map static as pointed out by Mike and Greg.
> >
> >  drivers/mtd/maps/Kconfig   |    2 +-
> >  drivers/mtd/maps/uclinux.c |   28 ++++++++++++++++++++++------
> >  2 files changed, 23 insertions(+), 7 deletions(-)
> >
> >diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> >index 5ba2458..d945950 100644
> >--- a/drivers/mtd/maps/Kconfig
> >+++ b/drivers/mtd/maps/Kconfig
> >@@ -443,7 +443,7 @@ config MTD_GPIO_ADDR
> >
> >  config MTD_UCLINUX
> >  	bool "Generic uClinux RAM/ROM filesystem support"
> >-	depends on MTD_RAM=y && !MMU
> >+	depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
> >  	help
> >  	  Map driver to support image based filesystems for uClinux.
> >
> >diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
> >index c3bb304..f5e8e9a 100644
> >--- a/drivers/mtd/maps/uclinux.c
> >+++ b/drivers/mtd/maps/uclinux.c
> >@@ -24,11 +24,12 @@
> >  /****************************************************************************/
> >
> >  struct map_info uclinux_ram_map = {
> >-	.name = "RAM",
> >-	.phys = (unsigned long)__bss_stop,
> >  	.size = 0,
> >  };
> >
> >+static unsigned long physaddr = -1;
> >+module_param(physaddr, ulong, S_IRUGO);
> >+
> >  static struct mtd_info *uclinux_ram_mtdinfo;
> >
> >  /****************************************************************************/
> >@@ -60,11 +61,17 @@ static int __init uclinux_mtd_init(void)
> >  	struct map_info *mapp;
> >
> >  	mapp = &uclinux_ram_map;
> >+
> >+	if (physaddr == -1)
> >+		mapp->phys = (resource_size_t)__bss_stop;
> >+	else
> >+		mapp->phys = physaddr;
> >+
> >  	if (!mapp->size)
> >  		mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
> >  	mapp->bankwidth = 4;
> >
> >-	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
> >+	printk("uclinux[mtd]: RAM/ROM probe address=0x%x size=0x%x\n",
> >  	       	(int) mapp->phys, (int) mapp->size);
> 
> Is there any value in saying "RAM/ROM"?
> Why don't we just drop those chars altogether.
ok.

> >  	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
> >@@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
> >
> >  	simple_map_init(mapp);
> >
> >-	mtd = do_map_probe("map_ram", mapp);
> >+	mapp->name = "ROM";
> >+	mtd = do_map_probe("map_rom", mapp);
> >+	if (!mtd) {
> >+		/* fall back to ram probing for compatibility reasons */
> >+		mapp->name = "RAM";
> >+		mtd = do_map_probe("map_ram", mapp);
> >+		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
> >+			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
> 
> Do we really want this message?
> My predominate usage of this code is in RAM mappings. Network
> loading kernel+filesystem images on bare boards. Anyone who wants
> to know and is looking in the kernel boot messages will see
> something like:
> 
>     Creating 1 MTD partitions on "RAM":
>     0x000000000000-0x0000000d8000 : "ROMfs"
> 
> So they will know what type of mapping it was loaded from.
I want it because if nobody reports it it might well be possible to drop
map_ram support.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From nicolas.ferre at atmel.com  Mon Oct 15 03:59:08 2012
From: nicolas.ferre at atmel.com (Nicolas Ferre)
Date: Mon, 15 Oct 2012 09:59:08 +0200
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc, gpio
 and ioremap
In-Reply-To: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
References: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <507BC24C.9090006@atmel.com>

On 10/13/2012 02:06 PM, Jean-Christophe PLAGNIOL-VILLARD :
> this will allow to simply the error and remove path
> 
> Cc: linux-mtd at lists.infradead.org
> Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Please also add Josh to the Cc list: he has made a great effort
supporting this driver and I guess that he is interested by this rework...

> ---
>  drivers/mtd/nand/atmel_nand.c |  163 ++++++++++++++---------------------------
>  1 file changed, 54 insertions(+), 109 deletions(-)
> 
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 92623ac..2b43656 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -364,43 +364,33 @@ static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
>  			table_size * sizeof(int16_t);
>  }
>  
> -static void pmecc_data_free(struct atmel_nand_host *host)
> -{
> -	kfree(host->pmecc_partial_syn);
> -	kfree(host->pmecc_si);
> -	kfree(host->pmecc_lmu);
> -	kfree(host->pmecc_smu);
> -	kfree(host->pmecc_mu);
> -	kfree(host->pmecc_dmu);
> -	kfree(host->pmecc_delta);
> -}
> -
>  static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
>  {
>  	const int cap = host->pmecc_corr_cap;
> +	int size;
> +
> +	size = (2 * cap + 1) * sizeof(int16_t);
> +	host->pmecc_partial_syn = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_si = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_lmu = devm_kzalloc(host->dev,
> +			(cap + 1) * sizeof(int16_t), GFP_KERNEL);
> +	host->pmecc_smu = devm_kzalloc(host->dev,
> +			(cap + 2) * (2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
> +	size = (cap + 1) * sizeof(int);
> +	host->pmecc_mu = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_dmu = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_delta = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +
> +	if (!host->pmecc_partial_syn ||
> +		!host->pmecc_si ||
> +		!host->pmecc_lmu ||
> +		!host->pmecc_smu ||
> +		!host->pmecc_mu ||
> +		!host->pmecc_dmu ||
> +		!host->pmecc_delta)
> +		return -ENOMEM;
>  
> -	host->pmecc_partial_syn = kzalloc((2 * cap + 1) * sizeof(int16_t),
> -					GFP_KERNEL);
> -	host->pmecc_si = kzalloc((2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
> -	host->pmecc_lmu = kzalloc((cap + 1) * sizeof(int16_t), GFP_KERNEL);
> -	host->pmecc_smu = kzalloc((cap + 2) * (2 * cap + 1) * sizeof(int16_t),
> -					GFP_KERNEL);
> -	host->pmecc_mu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -	host->pmecc_dmu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -	host->pmecc_delta = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -
> -	if (host->pmecc_partial_syn &&
> -			host->pmecc_si &&
> -			host->pmecc_lmu &&
> -			host->pmecc_smu &&
> -			host->pmecc_mu &&
> -			host->pmecc_dmu &&
> -			host->pmecc_delta)
> -		return 0;
> -
> -	/* error happened */
> -	pmecc_data_free(host);
> -	return -ENOMEM;
> +	return 0;
>  }
>  
>  static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
> @@ -923,27 +913,25 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>  		return 0;
>  	}
>  
> -	host->ecc = ioremap(regs->start, resource_size(regs));
> +	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
>  	if (host->ecc == NULL) {
>  		dev_err(host->dev, "ioremap failed\n");
>  		err_no = -EIO;
> -		goto err_pmecc_ioremap;
> +		goto err;
>  	}
>  
>  	regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
>  	regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3);
>  	if (regs_pmerr && regs_rom) {
> -		host->pmerrloc_base = ioremap(regs_pmerr->start,
> -			resource_size(regs_pmerr));
> -		host->pmecc_rom_base = ioremap(regs_rom->start,
> -			resource_size(regs_rom));
> +		host->pmerrloc_base = devm_request_and_ioremap(&pdev->dev, regs_pmerr);
> +		host->pmecc_rom_base = devm_request_and_ioremap(&pdev->dev, regs_rom);
>  	}
>  
>  	if (!host->pmerrloc_base || !host->pmecc_rom_base) {
>  		dev_err(host->dev,
>  			"Can not get I/O resource for PMECC ERRLOC controller or ROM!\n");
>  		err_no = -EIO;
> -		goto err_pmloc_ioremap;
> +		goto err;
>  	}
>  
>  	/* ECC is calculated for the whole page (1 step) */
> @@ -968,7 +956,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>  		if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
>  			dev_err(host->dev, "No room for ECC bytes\n");
>  			err_no = -EINVAL;
> -			goto err_no_ecc_room;
> +			goto err;
>  		}
>  		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
>  					mtd->oobsize,
> @@ -993,7 +981,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>  	if (err_no) {
>  		dev_err(host->dev,
>  				"Cannot allocate memory for PMECC computation!\n");
> -		goto err_pmecc_data_alloc;
> +		goto err;
>  	}
>  
>  	nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
> @@ -1003,15 +991,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>  
>  	return 0;
>  
> -err_pmecc_data_alloc:
> -err_no_ecc_room:
> -err_pmloc_ioremap:
> -	iounmap(host->ecc);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
> -err_pmecc_ioremap:
> +err:
>  	return err_no;
>  }
>  
> @@ -1315,7 +1295,7 @@ static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
>  		return 0;
>  	}
>  
> -	host->ecc = ioremap(regs->start, resource_size(regs));
> +	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
>  	if (host->ecc == NULL) {
>  		dev_err(host->dev, "ioremap failed\n");
>  		return -EIO;
> @@ -1380,20 +1360,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Allocate memory for the device structure (and zero it) */
> -	host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
> +	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
>  	if (!host) {
>  		printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n");
>  		return -ENOMEM;
>  	}
>  
> -	host->io_phys = (dma_addr_t)mem->start;
> -
> -	host->io_base = ioremap(mem->start, resource_size(mem));
> +	host->io_base = devm_request_and_ioremap(&pdev->dev, mem);
>  	if (host->io_base == NULL) {
>  		printk(KERN_ERR "atmel_nand: ioremap failed\n");
>  		res = -EIO;
>  		goto err_nand_ioremap;
>  	}
> +	host->io_phys = (dma_addr_t)mem->start;
>  
>  	mtd = &host->mtd;
>  	nand_chip = &host->nand_chip;
> @@ -1401,7 +1380,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>  	if (pdev->dev.of_node) {
>  		res = atmel_of_init_port(host, pdev->dev.of_node);
>  		if (res)
> -			goto err_ecc_ioremap;
> +			goto err_nand_ioremap;
>  	} else {
>  		memcpy(&host->board, pdev->dev.platform_data,
>  		       sizeof(struct atmel_nand_data));
> @@ -1420,44 +1399,42 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>  	if (IS_ERR(pinctrl)) {
>  		dev_err(host->dev, "Failed to request pinctrl\n");
>  		res = PTR_ERR(pinctrl);
> -		goto err_ecc_ioremap;
> +		goto err_nand_ioremap;
>  	}
>  
>  	if (gpio_is_valid(host->board.rdy_pin)) {
> -		res = gpio_request(host->board.rdy_pin, "nand_rdy");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.rdy_pin, "nand_rdy");
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request rdy gpio %d\n",
> -				host->board.rdy_pin);
> -			goto err_ecc_ioremap;
> +				"can't request rdy gpio %d\n", host->board.rdy_pin);
> +			goto err_nand_ioremap;
>  		}
>  
>  		res = gpio_direction_input(host->board.rdy_pin);
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request input direction rdy gpio %d\n",
> -				host->board.rdy_pin);
> -			goto err_ecc_ioremap;
> +				"can't request input direction rdy gpio %d\n", host->board.rdy_pin);

Why do you modify the log message presentation: it was okay before?
Moreover, it is not related to the topic of the patch...


> +			goto err_nand_ioremap;
>  		}
>  
>  		nand_chip->dev_ready = atmel_nand_device_ready;
>  	}
>  
>  	if (gpio_is_valid(host->board.enable_pin)) {
> -		res = gpio_request(host->board.enable_pin, "nand_enable");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.enable_pin, "nand_enable");
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request enable gpio %d\n",
> -				host->board.enable_pin);
> -			goto err_ecc_ioremap;
> +				"can't request enable gpio %d\n", host->board.enable_pin);

Ditto.

> +			goto err_nand_ioremap;
>  		}
>  
>  		res = gpio_direction_output(host->board.enable_pin, 1);
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request output direction enable gpio %d\n",
> -				host->board.enable_pin);
> -			goto err_ecc_ioremap;
> +				"can't request output direction enable gpio %d\n", host->board.enable_pin);

Ditto.

> +			goto err_nand_ioremap;
>  		}
>  	}
>  
> @@ -1474,19 +1451,18 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>  	atmel_nand_enable(host);
>  
>  	if (gpio_is_valid(host->board.det_pin)) {
> -		res = gpio_request(host->board.det_pin, "nand_det");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.det_pin, "nand_det");
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request det gpio %d\n",
> -				host->board.det_pin);
> +				"can't request det gpio %d\n", host->board.det_pin);

Ditto.

>  			goto err_no_card;
>  		}
>  
>  		res = gpio_direction_input(host->board.det_pin);
>  		if (res < 0) {
>  			dev_err(&pdev->dev,
> -				"can't request input direction det gpio %d\n",
> -				host->board.det_pin);
> +				"can't request input direction det gpio %d\n", host->board.det_pin);

Ditto.

>  			goto err_no_card;
>  		}
>  
> @@ -1552,16 +1528,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>  		return res;
>  
>  err_scan_tail:
> -	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
> +	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW)
>  		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
> -		pmecc_data_free(host);
> -	}
> -	if (host->ecc)
> -		iounmap(host->ecc);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
>  err_hw_ecc:
>  err_scan_ident:
>  err_no_card:
> @@ -1569,10 +1537,7 @@ err_no_card:
>  	platform_set_drvdata(pdev, NULL);
>  	if (host->dma_chan)
>  		dma_release_channel(host->dma_chan);
> -err_ecc_ioremap:
> -	iounmap(host->io_base);
>  err_nand_ioremap:
> -	kfree(host);
>  	return res;
>  }
>  
> @@ -1592,31 +1557,11 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
>  		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
>  		pmerrloc_writel(host->pmerrloc_base, ELDIS,
>  				PMERRLOC_DISABLE);
> -		pmecc_data_free(host);
>  	}
>  
> -	if (gpio_is_valid(host->board.det_pin))
> -		gpio_free(host->board.det_pin);
> -
> -	if (gpio_is_valid(host->board.enable_pin))
> -		gpio_free(host->board.enable_pin);
> -
> -	if (gpio_is_valid(host->board.rdy_pin))
> -		gpio_free(host->board.rdy_pin);
> -
> -	if (host->ecc)
> -		iounmap(host->ecc);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -
>  	if (host->dma_chan)
>  		dma_release_channel(host->dma_chan);
>  
> -	iounmap(host->io_base);
> -	kfree(host);
> -
>  	return 0;
>  }

Otherwise, looks good.

Bye,
-- 
Nicolas Ferre


From josh.wu at atmel.com  Mon Oct 15 06:43:20 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Mon, 15 Oct 2012 18:43:20 +0800
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc, gpio
 and ioremap
In-Reply-To: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
References: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <507BE8C8.8040901@atmel.com>

Hi, J.C.

On 10/13/2012 8:06 PM, Jean-Christophe PLAGNIOL-VILLARD wrote:
> this will allow to simply the error and remove path
>
> Cc: linux-mtd at lists.infradead.org
> Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> ---
>   drivers/mtd/nand/atmel_nand.c |  163 ++++++++++++++---------------------------
>   1 file changed, 54 insertions(+), 109 deletions(-)
>
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 92623ac..2b43656 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -364,43 +364,33 @@ static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
>   			table_size * sizeof(int16_t);
>   }
>   
> -static void pmecc_data_free(struct atmel_nand_host *host)
> -{
> -	kfree(host->pmecc_partial_syn);
> -	kfree(host->pmecc_si);
> -	kfree(host->pmecc_lmu);
> -	kfree(host->pmecc_smu);
> -	kfree(host->pmecc_mu);
> -	kfree(host->pmecc_dmu);
> -	kfree(host->pmecc_delta);
> -}
> -
>   static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
>   {
>   	const int cap = host->pmecc_corr_cap;
> +	int size;
> +
> +	size = (2 * cap + 1) * sizeof(int16_t);
> +	host->pmecc_partial_syn = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_si = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_lmu = devm_kzalloc(host->dev,
> +			(cap + 1) * sizeof(int16_t), GFP_KERNEL);
> +	host->pmecc_smu = devm_kzalloc(host->dev,
> +			(cap + 2) * (2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
> +	size = (cap + 1) * sizeof(int);
> +	host->pmecc_mu = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_dmu = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +	host->pmecc_delta = devm_kzalloc(host->dev, size, GFP_KERNEL);
> +
> +	if (!host->pmecc_partial_syn ||
> +		!host->pmecc_si ||
> +		!host->pmecc_lmu ||
> +		!host->pmecc_smu ||
> +		!host->pmecc_mu ||
> +		!host->pmecc_dmu ||
> +		!host->pmecc_delta)
> +		return -ENOMEM;
>   
> -	host->pmecc_partial_syn = kzalloc((2 * cap + 1) * sizeof(int16_t),
> -					GFP_KERNEL);
> -	host->pmecc_si = kzalloc((2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
> -	host->pmecc_lmu = kzalloc((cap + 1) * sizeof(int16_t), GFP_KERNEL);
> -	host->pmecc_smu = kzalloc((cap + 2) * (2 * cap + 1) * sizeof(int16_t),
> -					GFP_KERNEL);
> -	host->pmecc_mu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -	host->pmecc_dmu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -	host->pmecc_delta = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
> -
> -	if (host->pmecc_partial_syn &&
> -			host->pmecc_si &&
> -			host->pmecc_lmu &&
> -			host->pmecc_smu &&
> -			host->pmecc_mu &&
> -			host->pmecc_dmu &&
> -			host->pmecc_delta)
> -		return 0;
> -
> -	/* error happened */
> -	pmecc_data_free(host);
> -	return -ENOMEM;
> +	return 0;
>   }
>   
>   static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
> @@ -923,27 +913,25 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>   		return 0;
>   	}
>   
> -	host->ecc = ioremap(regs->start, resource_size(regs));
> +	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
>   	if (host->ecc == NULL) {
>   		dev_err(host->dev, "ioremap failed\n");
>   		err_no = -EIO;
> -		goto err_pmecc_ioremap;
> +		goto err;
>   	}
>   
>   	regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
>   	regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3);
>   	if (regs_pmerr && regs_rom) {
> -		host->pmerrloc_base = ioremap(regs_pmerr->start,
> -			resource_size(regs_pmerr));
> -		host->pmecc_rom_base = ioremap(regs_rom->start,
> -			resource_size(regs_rom));
> +		host->pmerrloc_base = devm_request_and_ioremap(&pdev->dev, regs_pmerr);
> +		host->pmecc_rom_base = devm_request_and_ioremap(&pdev->dev, regs_rom);
>   	}
>   
>   	if (!host->pmerrloc_base || !host->pmecc_rom_base) {
>   		dev_err(host->dev,
>   			"Can not get I/O resource for PMECC ERRLOC controller or ROM!\n");
>   		err_no = -EIO;
> -		goto err_pmloc_ioremap;
> +		goto err;
>   	}
>   
>   	/* ECC is calculated for the whole page (1 step) */
> @@ -968,7 +956,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>   		if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
>   			dev_err(host->dev, "No room for ECC bytes\n");
>   			err_no = -EINVAL;
> -			goto err_no_ecc_room;
> +			goto err;
>   		}
>   		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
>   					mtd->oobsize,
> @@ -993,7 +981,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>   	if (err_no) {
>   		dev_err(host->dev,
>   				"Cannot allocate memory for PMECC computation!\n");
> -		goto err_pmecc_data_alloc;
> +		goto err;
>   	}
>   
>   	nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
> @@ -1003,15 +991,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
>   
>   	return 0;
>   
> -err_pmecc_data_alloc:
> -err_no_ecc_room:
> -err_pmloc_ioremap:
> -	iounmap(host->ecc);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
> -err_pmecc_ioremap:
> +err:
>   	return err_no;
>   }
>   
> @@ -1315,7 +1295,7 @@ static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
>   		return 0;
>   	}
>   
> -	host->ecc = ioremap(regs->start, resource_size(regs));
> +	host->ecc = devm_request_and_ioremap(&pdev->dev, regs);
>   	if (host->ecc == NULL) {
>   		dev_err(host->dev, "ioremap failed\n");
>   		return -EIO;
> @@ -1380,20 +1360,19 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>   	}
>   
>   	/* Allocate memory for the device structure (and zero it) */
> -	host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL);
> +	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
>   	if (!host) {
>   		printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n");
>   		return -ENOMEM;
>   	}
>   
> -	host->io_phys = (dma_addr_t)mem->start;
> -
> -	host->io_base = ioremap(mem->start, resource_size(mem));
> +	host->io_base = devm_request_and_ioremap(&pdev->dev, mem);
>   	if (host->io_base == NULL) {
>   		printk(KERN_ERR "atmel_nand: ioremap failed\n");
>   		res = -EIO;
>   		goto err_nand_ioremap;
>   	}
> +	host->io_phys = (dma_addr_t)mem->start;
>   
>   	mtd = &host->mtd;
>   	nand_chip = &host->nand_chip;
> @@ -1401,7 +1380,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>   	if (pdev->dev.of_node) {
>   		res = atmel_of_init_port(host, pdev->dev.of_node);
>   		if (res)
> -			goto err_ecc_ioremap;
> +			goto err_nand_ioremap;
>   	} else {
>   		memcpy(&host->board, pdev->dev.platform_data,
>   		       sizeof(struct atmel_nand_data));
> @@ -1420,44 +1399,42 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>   	if (IS_ERR(pinctrl)) {
>   		dev_err(host->dev, "Failed to request pinctrl\n");
>   		res = PTR_ERR(pinctrl);

I cannot apply the patch in latest l2-mtd git tree since above line of 
code doesn't committed.
Seems that code is pinctrl related. Am I missing some patches?

Best Regards,
Josh Wu

> -		goto err_ecc_ioremap;
> +		goto err_nand_ioremap;
>   	}
>   
>   	if (gpio_is_valid(host->board.rdy_pin)) {
> -		res = gpio_request(host->board.rdy_pin, "nand_rdy");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.rdy_pin, "nand_rdy");
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request rdy gpio %d\n",
> -				host->board.rdy_pin);
> -			goto err_ecc_ioremap;
> +				"can't request rdy gpio %d\n", host->board.rdy_pin);
> +			goto err_nand_ioremap;
>   		}
>   
>   		res = gpio_direction_input(host->board.rdy_pin);
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request input direction rdy gpio %d\n",
> -				host->board.rdy_pin);
> -			goto err_ecc_ioremap;
> +				"can't request input direction rdy gpio %d\n", host->board.rdy_pin);
> +			goto err_nand_ioremap;
>   		}
>   
>   		nand_chip->dev_ready = atmel_nand_device_ready;
>   	}
>   
>   	if (gpio_is_valid(host->board.enable_pin)) {
> -		res = gpio_request(host->board.enable_pin, "nand_enable");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.enable_pin, "nand_enable");
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request enable gpio %d\n",
> -				host->board.enable_pin);
> -			goto err_ecc_ioremap;
> +				"can't request enable gpio %d\n", host->board.enable_pin);
> +			goto err_nand_ioremap;
>   		}
>   
>   		res = gpio_direction_output(host->board.enable_pin, 1);
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request output direction enable gpio %d\n",
> -				host->board.enable_pin);
> -			goto err_ecc_ioremap;
> +				"can't request output direction enable gpio %d\n", host->board.enable_pin);
> +			goto err_nand_ioremap;
>   		}
>   	}
>   
> @@ -1474,19 +1451,18 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>   	atmel_nand_enable(host);
>   
>   	if (gpio_is_valid(host->board.det_pin)) {
> -		res = gpio_request(host->board.det_pin, "nand_det");
> +		res = devm_gpio_request(&pdev->dev,
> +				host->board.det_pin, "nand_det");
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request det gpio %d\n",
> -				host->board.det_pin);
> +				"can't request det gpio %d\n", host->board.det_pin);
>   			goto err_no_card;
>   		}
>   
>   		res = gpio_direction_input(host->board.det_pin);
>   		if (res < 0) {
>   			dev_err(&pdev->dev,
> -				"can't request input direction det gpio %d\n",
> -				host->board.det_pin);
> +				"can't request input direction det gpio %d\n", host->board.det_pin);
>   			goto err_no_card;
>   		}
>   
> @@ -1552,16 +1528,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
>   		return res;
>   
>   err_scan_tail:
> -	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
> +	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW)
>   		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
> -		pmecc_data_free(host);
> -	}
> -	if (host->ecc)
> -		iounmap(host->ecc);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
>   err_hw_ecc:
>   err_scan_ident:
>   err_no_card:
> @@ -1569,10 +1537,7 @@ err_no_card:
>   	platform_set_drvdata(pdev, NULL);
>   	if (host->dma_chan)
>   		dma_release_channel(host->dma_chan);
> -err_ecc_ioremap:
> -	iounmap(host->io_base);
>   err_nand_ioremap:
> -	kfree(host);
>   	return res;
>   }
>   
> @@ -1592,31 +1557,11 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
>   		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
>   		pmerrloc_writel(host->pmerrloc_base, ELDIS,
>   				PMERRLOC_DISABLE);
> -		pmecc_data_free(host);
>   	}
>   
> -	if (gpio_is_valid(host->board.det_pin))
> -		gpio_free(host->board.det_pin);
> -
> -	if (gpio_is_valid(host->board.enable_pin))
> -		gpio_free(host->board.enable_pin);
> -
> -	if (gpio_is_valid(host->board.rdy_pin))
> -		gpio_free(host->board.rdy_pin);
> -
> -	if (host->ecc)
> -		iounmap(host->ecc);
> -	if (host->pmecc_rom_base)
> -		iounmap(host->pmecc_rom_base);
> -	if (host->pmerrloc_base)
> -		iounmap(host->pmerrloc_base);
> -
>   	if (host->dma_chan)
>   		dma_release_channel(host->dma_chan);
>   
> -	iounmap(host->io_base);
> -	kfree(host);
> -
>   	return 0;
>   }
>   



From dedekind1 at gmail.com  Mon Oct 15 08:47:43 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 15:47:43 +0300
Subject: [PATCH] ARM: nomadik: fixup some FSMC merge problems
In-Reply-To: <1349994182-26116-1-git-send-email-linus.walleij@linaro.org>
References: <1349994182-26116-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <1350305263.4115.3.camel@sauron.fi.intel.com>

On Fri, 2012-10-12 at 00:23 +0200, Linus Walleij wrote:
> Due to a clash between refactoring and due to loss of a header
> file that remained in my working tree the Nomadik stopped
> compiling after switching to the FSMC driver. This patch fixes
> it up.
> 
> Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

Pushed this one to l2-mtd.git as well, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/8838b88e/attachment.sig>

From dedekind1 at gmail.com  Mon Oct 15 09:18:24 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 16:18:24 +0300
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <507794B6.2000107@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
Message-ID: <1350307104.4115.23.camel@sauron.fi.intel.com>

On Fri, 2012-10-12 at 09:25 +0530, Vipin Kumar wrote:
> The buffers provided to the driver are actually user buffers. The reason 
> I say that is because the generic nand test modules eg 
> drivers/mtd/nand/mtd_stresstest.c calls mtd->_read with a user buffer as 
> an argument

I am not sure what does "user" buffers mean, but they are vmalloced()
buffer, not kmalloc()'ed, so they are not physically contiguous.

> This same buffer directly trickles down to the driver
> 
> Artem, should we clearly cast this buffer as a user pointer instead of 
> just a 'uint8_t *'.

They are not "_user", they are really kernel buffers. Or what do you
mean, which exactly type do you suggest?

This stuff is something many people are bringing up for many years
already. Drivers that do DMA do not cope with vmalloc()ed memory well,
and we grew a number of hacks in several drives. I mean, hacks like the
one you are introducing to your driver.

I'd solve the problem by changing the in-kernel mtd users to use
physically-contiguous memory instead. The following are the users I can
think of:

UBI, UBIFS, JFFS2, mtdtests and probably mtdswap.

They use vmalloc() when they need to read/write entire eraseblock, which
is usually 128KiB or 256KiB, and kmalloc() that much may fail if the
memory is fragmented. 

In many cases, it is easy to read/write in smaller chunk, but several
times. E.g., mtdtests could be changed.

In some cases, it is not easy, though.

First thing which comes to mind is that in modern kernels memory
fragmentation is not that big issue as it used to be. So may be
kmalloc() the memory is not that bad nowadays? We have page migration,
memory compaction, etc?

I'd really prefer to just switch to kmalloc() everywhere instead of
adding hacks like this to the drivers. Then if this is a problem for
someone, he can fix it by either switching to smaller buffers (possible
in many places), or by improving memory fragmentation issues on his
system, or by just using CMA.

We can even have an mtd-wide funcion which will try kmalloc(), and if
that fails, fall-back to CMA.


Then we can add a guard check to all mtd function which accept a buffer
and WARN() if it not physically contiguous.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/738aa0ca/attachment.sig>

From plagnioj at jcrosoft.com  Mon Oct 15 09:24:15 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 15 Oct 2012 15:24:15 +0200
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc, gpio
 and ioremap
In-Reply-To: <507BE8C8.8040901@atmel.com>
References: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
 <507BE8C8.8040901@atmel.com>
Message-ID: <20121015132415.GV12801@game.jcrosoft.org>

> >  		goto err_nand_ioremap;
> >  	}
> >+	host->io_phys = (dma_addr_t)mem->start;
> >  	mtd = &host->mtd;
> >  	nand_chip = &host->nand_chip;
> >@@ -1401,7 +1380,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
> >  	if (pdev->dev.of_node) {
> >  		res = atmel_of_init_port(host, pdev->dev.of_node);
> >  		if (res)
> >-			goto err_ecc_ioremap;
> >+			goto err_nand_ioremap;
> >  	} else {
> >  		memcpy(&host->board, pdev->dev.platform_data,
> >  		       sizeof(struct atmel_nand_data));
> >@@ -1420,44 +1399,42 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
> >  	if (IS_ERR(pinctrl)) {
> >  		dev_err(host->dev, "Failed to request pinctrl\n");
> >  		res = PTR_ERR(pinctrl);
> 
> I cannot apply the patch in latest l2-mtd git tree since above line
> of code doesn't committed.
> Seems that code is pinctrl related. Am I missing some patches?

this is base on linux next

and yes with pinctrl

Best Regards,
J.


From dedekind1 at gmail.com  Mon Oct 15 09:28:43 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 16:28:43 +0300
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
In-Reply-To: <OFDA2AD2F6.2BD9C5E0-ONC1257A91.003021EB-C1257A91.003058E4@transmode.se>
References: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>
 <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>
 <OFDA2AD2F6.2BD9C5E0-ONC1257A91.003021EB-C1257A91.003058E4@transmode.se>
Message-ID: <1350307723.5769.1.camel@sauron.fi.intel.com>

On Mon, 2012-10-08 at 10:48 +0200, Joakim Tjernlund wrote:
> > And "be be" in the first comment should probably read "be done".
> 
> Agreed on all above points, thanks.

So would someone send the final patch with the commit message,
Signed-off-by, etc? Should there be Cc: stable at vger.kernel.org?


-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/eed2a768/attachment-0001.sig>

From joakim.tjernlund at transmode.se  Mon Oct 15 09:38:23 2012
From: joakim.tjernlund at transmode.se (Joakim Tjernlund)
Date: Mon, 15 Oct 2012 15:38:23 +0200
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
In-Reply-To: <1350307723.5769.1.camel@sauron.fi.intel.com>
References: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>	
 <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>
 <OFDA2AD2F6.2BD9C5E0-ONC1257A91.003021EB-C1257A91.003058E4@transmode.se>
 <1350307723.5769.1.camel@sauron.fi.intel.com>
Message-ID: <OFB4C05C90.BA76062E-ONC1257A98.004AC00B-C1257A98.004AECCB@transmode.se>

Artem Bityutskiy <dedekind1 at gmail.com> wrote on 2012/10/15 15:28:43:
> 
> On Mon, 2012-10-08 at 10:48 +0200, Joakim Tjernlund wrote:
> > > And "be be" in the first comment should probably read "be done".
> > 
> > Agreed on all above points, thanks.
> 
> So would someone send the final patch with the commit message,
> Signed-off-by, etc? Should there be Cc: stable at vger.kernel.org?

Thomas already did, he fixed it up and sent it to the ML. I acked it.

 Jocke


From Thomas.Betker at rohde-schwarz.com  Mon Oct 15 09:38:50 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Mon, 15 Oct 2012 15:38:50 +0200
Subject: [PATCH] jffs2: Fix lock acquisition order bug in jffs2_write_begin
In-Reply-To: <1350307723.5769.1.camel@sauron.fi.intel.com>
References: <1349429064-10241-1-git-send-email-Joakim.Tjernlund@transmode.se>	
 <OF69AFCA95.D74167D3-ONC1257A8E.003A3DD7-C1257A91.002E54A0@rohde-schwarz.com>
 <OFDA2AD2F6.2BD9C5E0-ONC1257A91.003021EB-C1257A91.003058E4@transmode.se>
 <1350307723.5769.1.camel@sauron.fi.intel.com>
Message-ID: <OF84E7FB15.5972B59F-ONC1257A98.004A2925-C1257A98.004AF802@rohde-schwarz.com>

Hello Artem:

> So would someone send the final patch with the commit message,
> Signed-off-by, etc? Should there be Cc: stable at vger.kernel.org?

I sent a "PATCH RESEND" message to the list, with the same topic; please 
use that one (sorry if I caused a confusion).

Cc: stable at vger.kernel.org makes sense -- can you add it? Does stable 
cover 3.4 as well?

Best regards,
Thomas



From dedekind1 at gmail.com  Mon Oct 15 09:42:36 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 16:42:36 +0300
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <20121005183202.GA11385@obsidianresearch.com>
References: <20121005183202.GA11385@obsidianresearch.com>
Message-ID: <1350308556.5769.5.camel@sauron.fi.intel.com>

On Fri, 2012-10-05 at 12:32 -0600, Jason Gunthorpe wrote:
> -	/* see comments in do_write_oneword() regarding uWriteTimeo. */
> -	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> +	/* see comments in do_write_oneword() regarding uWriteTimeo.
> +	   Note: write_buffer commands take longer so we use a higher
> +	   time. The AMD 29LV256M for instance has a datasheet max
> +	   of 1.2ms for page and 600us for byte */
> +	unsigned long uWriteTimeout = (HZ / 1500) + 2;

What does HZ / 1500 mean? HZ is amount of timer interrupts per second,
which may be 1/100, or 1/1000, or 1/300, depending on the system.

The CFI code seems to assume that HZ is 1/1000, which is wrong. I think
the entire timeout strategy in this file should be cleaned up. You
should use 'jiffies_to_msecs()' / 'msecs_to_jiffies()' helpers instead
of using 'HZ'. And time-outs should be specified in msecs, not in
jiffies. There should be no things like 'HZ/1500'.

Or do I misunderstand something?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/66ca220b/attachment.sig>

From dedekind1 at gmail.com  Mon Oct 15 09:47:24 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 16:47:24 +0300
Subject: MTD in mainline status
In-Reply-To: <50724E5C.1010809@atmel.com>
References: <50724E5C.1010809@atmel.com>
Message-ID: <1350308844.5769.6.camel@sauron.fi.intel.com>

On Mon, 2012-10-08 at 11:54 +0800, Josh Wu wrote:
> Just a little reminder: it would be good time to send out the pull 
> request to mainline for MTD in current merge window :-)

The mtd tree was merged upstream normally this time.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/9edec4f5/attachment.sig>

From dedekind1 at gmail.com  Mon Oct 15 09:48:58 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 16:48:58 +0300
Subject: [PATCH] MTD: atmel_nand: fix compile error when use
 avr32-atstk1006_defconfig
In-Reply-To: <1349678809-12092-1-git-send-email-josh.wu@atmel.com>
References: <1349678809-12092-1-git-send-email-josh.wu@atmel.com>
Message-ID: <1350308938.5769.7.camel@sauron.fi.intel.com>

On Mon, 2012-10-08 at 14:46 +0800, Josh Wu wrote:
> fixed the following compile error when use avr32 config:
> drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
> drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
> 
> Since in ARCH avr32, there is no macro "writel_relaxed" defined. In this patch we use macro "writel" instead.
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>

Why not to provide writel_relaxed() in AVR instead?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/803e0b10/attachment.sig>

From artem.bityutskiy at linux.intel.com  Mon Oct 15 10:00:43 2012
From: artem.bityutskiy at linux.intel.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 17:00:43 +0300
Subject: [PATCH] [RFC] mtd/uclinux: support ROM and allow passing the
 base address
In-Reply-To: <5077B167.40009@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <50739A2A.9070405@snapgear.com> <20121009084418.GH18531@pengutronix.de>
 <5073FE55.2000402@snapgear.com>
 <CAMjpGUe_aTEjGF9q1uraU_ikCif0J-+bSTLkr-X6jEYqjMHOtQ@mail.gmail.com>
 <5077B167.40009@snapgear.com>
Message-ID: <1350309643.5769.12.camel@sauron.fi.intel.com>

On Fri, 2012-10-12 at 15:57 +1000, Greg Ungerer wrote:
> I haven't picked it up. I assumed Artem would, but I have not seen
> any response from him on this yet. 

I did not pick up anything. Also, your patches are now in Linuses tree.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/b452eb73/attachment.sig>

From dedekind1 at gmail.com  Mon Oct 15 11:15:30 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 18:15:30 +0300
Subject: [PATCH] ubi: use list_move_tail instead of list_del/list_add_tail
In-Reply-To: <CAPgLHd_AHHe7=H18K54LvbiS0M7_w1vTMOxwwxgVdRaiXNN-OA@mail.gmail.com>
References: <CAPgLHd_AHHe7=H18K54LvbiS0M7_w1vTMOxwwxgVdRaiXNN-OA@mail.gmail.com>
Message-ID: <1350314130.5769.17.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 14:14 +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> 
> Using list_move_tail() instead of list_del() + list_add_tail().
> 
> dpatch engine is used to auto generate this patch.
> (https://github.com/weiyj/dpatch)
> 
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Pushed to linux-ubi.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/9404880c/attachment.sig>

From vapier.adi at gmail.com  Mon Oct 15 12:06:42 2012
From: vapier.adi at gmail.com (Mike Frysinger)
Date: Mon, 15 Oct 2012 12:06:42 -0400
Subject: [PATCH] Devicetree support for enc28j60 SPI Ethernet chip
In-Reply-To: <507B04AA.1050502@vanka.net>
References: <507B04AA.1050502@vanka.net>
Message-ID: <CAMjpGUd8mjZniGcbKw3jZ0V1kGbnYxoHUJg4jGVrSFtdVTadyQ@mail.gmail.com>

On Sun, Oct 14, 2012 at 2:30 PM, Michal Vanka wrote:
> the following patch adds generic openfirmware/devicetree support to enc28j60
> driver.

this should go to the net list, not the mtd list, since this is a net driver

however, your patch needs a little work.  please send it with `git
send-email` rather than formatting things yourself.

> +       if(priv->interrupt_deassert_reg)
> +               writeb(1,priv->interrupt_deassert_reg);

needs a space after the "if" and after the ",".  please run your patch
through checkpatch.pl before re-submitting.

> +static int __devinit enc28j60_of_probe(struct spi_device *spi,struct

more space issues

> +{
> +
> +       u8 *reg;

kill off that blank line

> +       if(prop && len>=sizeof(__be32))

more space issues

> +       if(!devm_request_mem_region(&spi->dev, reg, 4, DRV_NAME))

here too
-mike


From dwmw2 at infradead.org  Mon Oct 15 12:09:40 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon, 15 Oct 2012 09:09:40 -0700
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350308556.5769.5.camel@sauron.fi.intel.com>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
Message-ID: <1350317380.14124.26.camel@shinybook.infradead.org>

On Mon, 2012-10-15 at 16:42 +0300, Artem Bityutskiy wrote:
> On Fri, 2012-10-05 at 12:32 -0600, Jason Gunthorpe wrote:
> > -	/* see comments in do_write_oneword() regarding uWriteTimeo. */
> > -	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> > +	/* see comments in do_write_oneword() regarding uWriteTimeo.
> > +	   Note: write_buffer commands take longer so we use a higher
> > +	   time. The AMD 29LV256M for instance has a datasheet max
> > +	   of 1.2ms for page and 600us for byte */
> > +	unsigned long uWriteTimeout = (HZ / 1500) + 2;
> 
> What does HZ / 1500 mean? HZ is amount of timer interrupts per second,
> which may be 1/100, or 1/1000, or 1/300, depending on the system.

If HZ is the amount of timer interrupts per second, then HZ/1500 is the
amount of timer interrupts in 1/1500 of a second, aka 666.7?s.?

So it's not *entirely* bogus, but it should certainly be cleaned up to
use the msecs_to_jiffies() helpers... or preferably not use jiffies at
all, perhaps.

-- 
dwmw2

? That's '?s', not 'us', for next time the patch is submitted. Welcome
  to the 21st century.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/6b4cf5ec/attachment.bin>

From computersforpeace at gmail.com  Mon Oct 15 12:27:53 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 15 Oct 2012 09:27:53 -0700
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <1350307104.4115.23.camel@sauron.fi.intel.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
 <1350307104.4115.23.camel@sauron.fi.intel.com>
Message-ID: <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>

On Mon, Oct 15, 2012 at 6:18 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> First thing which comes to mind is that in modern kernels memory
> fragmentation is not that big issue as it used to be. So may be
> kmalloc() the memory is not that bad nowadays? We have page migration,
> memory compaction, etc?
>
> I'd really prefer to just switch to kmalloc() everywhere instead of
> adding hacks like this to the drivers. Then if this is a problem for
> someone, he can fix it by either switching to smaller buffers (possible
> in many places), or by improving memory fragmentation issues on his
> system, or by just using CMA.

I think I can suggest that this is already a problem on real systems.
In bringing up a board on v3.3 kernel, I experienced a kernel memory
allocation error when trying to memdup_user() in eraseblock-size
regions. I believe I would experience more of these if all
eraseblock-sized buffers were kmalloc()'d.

See the commit description for the following commit in mtd-utils.git:

    commit 71c76e74661492b4f68f670514866cfc85f47089
    libmtd: fix mtd_write() issues for large data-only writes

> We can even have an mtd-wide funcion which will try kmalloc(), and if
> that fails, fall-back to CMA.

I would prefer not building a solution that hopes kmalloc() can get a
large contiguous buffer (remember, eraseblock sizes come as large as
2MB these days). A real solution like CMA or scatter-gather seems like
a better idea.

Brian


From jgunthorpe at obsidianresearch.com  Mon Oct 15 12:57:19 2012
From: jgunthorpe at obsidianresearch.com (Jason Gunthorpe)
Date: Mon, 15 Oct 2012 10:57:19 -0600
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350317380.14124.26.camel@shinybook.infradead.org>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
Message-ID: <20121015165719.GB32563@obsidianresearch.com>

On Mon, Oct 15, 2012 at 09:09:40AM -0700, David Woodhouse wrote:

> So it's not *entirely* bogus, but it should certainly be cleaned up to
> use the msecs_to_jiffies() helpers... or preferably not use jiffies at
> all, perhaps.

No doubt this is part of why I've seen failures on my boards, the
timeout is too short by half and rounded wrong :)

A quick grep shows many cases in drivers/mtd that use division of HZ,
what would you like to see done here?

Jason

?? That's '??s', not 'us', for next time the patch is submitted. Welcome
  to the 21st century.

Hmm.. I may need a new terminal and/or mail reader ;)


From dwmw2 at infradead.org  Mon Oct 15 13:31:41 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon, 15 Oct 2012 10:31:41 -0700
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <20121015165719.GB32563@obsidianresearch.com>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
 <20121015165719.GB32563@obsidianresearch.com>
Message-ID: <1350322301.14124.45.camel@shinybook.infradead.org>

On Mon, 2012-10-15 at 10:57 -0600, Jason Gunthorpe wrote:
> On Mon, Oct 15, 2012 at 09:09:40AM -0700, David Woodhouse wrote:
> 
> > So it's not *entirely* bogus, but it should certainly be cleaned up to
> > use the msecs_to_jiffies() helpers... or preferably not use jiffies at
> > all, perhaps.
> 
> No doubt this is part of why I've seen failures on my boards, the
> timeout is too short by half and rounded wrong :)

Yeah, the rounding by +2 is confusing. I'm sure it's wrong, but at least
I can kind of see where it came from.

> A quick grep shows many cases in drivers/mtd that use division of HZ,
> what would you like to see done here?

I'd like someone with infinite amounts of free time to go through and
clean them all up :)

> ?? That's '??s', not 'us', for next time the patch is submitted. Welcome
>   to the 21st century.
> 
> Hmm.. I may need a new terminal and/or mail reader ;)

As I said... welcome to the 21st century. Seriously though, what are you
using that isn't capable of even *preserving* UTF-8 when you reply to
it? That's really quite broken, and has been considered so for a decade
or more already.

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/3224a92b/attachment-0001.bin>

From jgunthorpe at obsidianresearch.com  Mon Oct 15 13:49:07 2012
From: jgunthorpe at obsidianresearch.com (Jason Gunthorpe)
Date: Mon, 15 Oct 2012 11:49:07 -0600
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350322301.14124.45.camel@shinybook.infradead.org>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
 <20121015165719.GB32563@obsidianresearch.com>
 <1350322301.14124.45.camel@shinybook.infradead.org>
Message-ID: <20121015174907.GA529@obsidianresearch.com>

On Mon, Oct 15, 2012 at 10:31:41AM -0700, David Woodhouse wrote:

> > > So it's not *entirely* bogus, but it should certainly be cleaned up to
> > > use the msecs_to_jiffies() helpers... or preferably not use jiffies at
> > > all, perhaps.
> > 
> > No doubt this is part of why I've seen failures on my boards, the
> > timeout is too short by half and rounded wrong :)
> 
> Yeah, the rounding by +2 is confusing. I'm sure it's wrong, but at least
> I can kind of see where it came from.

The rounding by +2? I think even if you used msecs_to_jiffies you'd
need to add a +1 to the result to make the timeout algorithm work
right..

Is there a better way to do these timeouts?
 
> > A quick grep shows many cases in drivers/mtd that use division of HZ,
> > what would you like to see done here?
> 
> I'd like someone with infinite amounts of free time to go through and
> clean them all up :)

lol! Would you accept msecs_to_jiffies conversion for the cfi files?

> > ?? That's '??s', not 'us', for next time the patch is submitted. Welcome
> >   to the 21st century.
> > 
> > Hmm.. I may need a new terminal and/or mail reader ;)
> 
> As I said... welcome to the 21st century. Seriously though, what are you
> using that isn't capable of even *preserving* UTF-8 when you reply to
> it? That's really quite broken, and has been considered so for a decade
> or more already.

I deliberately made it not preserve UTF-8 for this posting, it is just
rxvt, nobody ever put unicode into it.

Jason


From dwmw2 at infradead.org  Mon Oct 15 14:32:53 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon, 15 Oct 2012 11:32:53 -0700
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <20121015174907.GA529@obsidianresearch.com>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
 <20121015165719.GB32563@obsidianresearch.com>
 <1350322301.14124.45.camel@shinybook.infradead.org>
 <20121015174907.GA529@obsidianresearch.com>
Message-ID: <1350325973.14124.49.camel@shinybook.infradead.org>

On Mon, 2012-10-15 at 11:49 -0600, Jason Gunthorpe wrote:
> The rounding by +2? I think even if you used msecs_to_jiffies you'd
> need to add a +1 to the result to make the timeout algorithm work
> right..

Yes, HZ/1500+1 I could understand. That's the number of jiffies that
give you '666?s or more'. The +2 is odd though.

> > I'd like someone with infinite amounts of free time to go through and
> > clean them all up :)
> 
> lol! Would you accept msecs_to_jiffies conversion for the cfi files?

Absolutely. Although I'd like to take a little step back and take a more
thoughtful view of how we *should* be handing these timeouts, rather
than a simple janitor-style conversion of the existing code.

> I deliberately made it not preserve UTF-8 for this posting, it is just
> rxvt, nobody ever put unicode into it.

? rxvt-unicode

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/12449b8c/attachment.bin>

From jacmet at sunsite.dk  Mon Oct 15 14:56:40 2012
From: jacmet at sunsite.dk (Peter Korsgaard)
Date: Mon, 15 Oct 2012 20:56:40 +0200
Subject: [PATCH 1/4] mtd: nand: omap2: Update nerrors using ecc.strength
In-Reply-To: <1349274589-11389-2-git-send-email-avinashphilip@ti.com> (Avinash
 Philip's message of "Wed, 3 Oct 2012 19:59:46 +0530")
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-2-git-send-email-avinashphilip@ti.com>
Message-ID: <87obk3va1j.fsf@macbook.be.48ers.dk>

>>>>> Philip, Avinash <avinashphilip at ti.com> writes:

 > Update number of errors using nand ecc strength.
 > Also add macro definitions BCH8_ERROR_MAX & BCH4_ERROR_MAX

 > Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
 > ---
 > :100644 100644 5b31386... af511a9... M	drivers/mtd/nand/omap2.c
 >  drivers/mtd/nand/omap2.c |   12 ++++++++----
 >  1 files changed, 8 insertions(+), 4 deletions(-)

 > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
 > index 5b31386..af511a9 100644
 > --- a/drivers/mtd/nand/omap2.c
 > +++ b/drivers/mtd/nand/omap2.c
 > @@ -111,6 +111,9 @@
 >  #define	ECCCLEAR			0x100
 >  #define	ECC1				0x1
 
 > +#define BCH8_MAX_ERROR		8	/* upto 8 bit coorectable */
 > +#define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */

First 'correctable' misspelled.

I don't personally think these defines improve readability very much
compared to to just using 4/8, though.

-- 
Bye, Peter Korsgaard


From jacmet at sunsite.dk  Mon Oct 15 14:48:30 2012
From: jacmet at sunsite.dk (Peter Korsgaard)
Date: Mon, 15 Oct 2012 20:48:30 +0200
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <1349274589-11389-4-git-send-email-avinashphilip@ti.com> (Avinash
 Philip's message of "Wed, 3 Oct 2012 19:59:48 +0530")
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
Message-ID: <87vcebvaf5.fsf@macbook.be.48ers.dk>

>>>>> Philip, Avinash <avinashphilip at ti.com> writes:

 > Add support for BCH ECC scheme to gpmc driver and also enabling multi
 > sector read/write. This helps in doing single shot NAND page read and
 > write.

 > ECC engine configurations
 > BCH 4 bit support
 > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
 > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
 > 13 and ecc_size1 as 1.

 > BCH 8 bit support
 > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
 > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
 > 26 and ecc_size1 as 2.

 > Note: For BCH8 ECC bytes set to 14 to make compatible with RBL.

On what device? In the am335x TRM (spruh73f.pdf) figure 26-15 (pg 4273)
the rom code is documented to not use any padding on the ECC bytes
(E.G. oob 2..53):

http://www.ti.com/litv/pdf/spruh73f

I see the driver in the u-boot-am33x tree (ti81xx_nand.c) seems to use
4x14 bytes as well though, so perhaps that's a bug in the documentation
instead?

-- 
Bye, Peter Korsgaard


From jgunthorpe at obsidianresearch.com  Mon Oct 15 15:08:13 2012
From: jgunthorpe at obsidianresearch.com (Jason Gunthorpe)
Date: Mon, 15 Oct 2012 13:08:13 -0600
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350325973.14124.49.camel@shinybook.infradead.org>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
 <20121015165719.GB32563@obsidianresearch.com>
 <1350322301.14124.45.camel@shinybook.infradead.org>
 <20121015174907.GA529@obsidianresearch.com>
 <1350325973.14124.49.camel@shinybook.infradead.org>
Message-ID: <20121015190813.GA7638@obsidianresearch.com>

On Mon, Oct 15, 2012 at 11:32:53AM -0700, David Woodhouse wrote:

> Yes, HZ/1500+1 I could understand. That's the number of jiffies that
> give you '666??s or more'. The +2 is odd though.

Looking more closely I agree, it seems bogus - the use of time_after
takes care of the short first jiffy problem, the real problem I see is
that 1500 was supposed to be ??s, that is close to the datasheet spec
for the flash I have. Fixing that will almost double the timeout on my
systems...

> > > I'd like someone with infinite amounts of free time to go through and
> > > clean them all up :)
> > 
> > lol! Would you accept msecs_to_jiffies conversion for the cfi files?
> 
> Absolutely. Although I'd like to take a little step back and take a more
> thoughtful view of how we *should* be handing these timeouts, rather
> than a simple janitor-style conversion of the existing code.

Okay, well, I'll send a patch in a few days, if there is a better way
than:

 unsigned long uWriteTimeout = usecs_to_jiffies(1500);
 timeo = jiffies + uWriteTimeout;
 if (time_after(jiffies, timeo)) // TIMEOUT

Maybe someone will pipe up?

Jason


From dedekind1 at gmail.com  Mon Oct 15 15:28:19 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Mon, 15 Oct 2012 22:28:19 +0300
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350317380.14124.26.camel@shinybook.infradead.org>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
Message-ID: <1350329299.1509.6.camel@kyv>

On Mon, 2012-10-15 at 09:09 -0700, David Woodhouse wrote:
> On Mon, 2012-10-15 at 16:42 +0300, Artem Bityutskiy wrote:
> > On Fri, 2012-10-05 at 12:32 -0600, Jason Gunthorpe wrote:
> > > -	/* see comments in do_write_oneword() regarding uWriteTimeo. */
> > > -	unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
> > > +	/* see comments in do_write_oneword() regarding uWriteTimeo.
> > > +	   Note: write_buffer commands take longer so we use a higher
> > > +	   time. The AMD 29LV256M for instance has a datasheet max
> > > +	   of 1.2ms for page and 600us for byte */
> > > +	unsigned long uWriteTimeout = (HZ / 1500) + 2;
> > 
> > What does HZ / 1500 mean? HZ is amount of timer interrupts per second,
> > which may be 1/100, or 1/1000, or 1/300, depending on the system.
> 
> If HZ is the amount of timer interrupts per second, then HZ/1500 is the
> amount of timer interrupts in 1/1500 of a second, aka 666.7?s.?

First of all, yes, my e-mail was not very clear, I guess I just wanted
to express that it is not very readable. Also, HZ / 1500 would be 0 for
HZ < 1500, since we are using integer arithmetic.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/82b090e6/attachment.sig>

From jacmet at sunsite.dk  Mon Oct 15 15:40:47 2012
From: jacmet at sunsite.dk (Peter Korsgaard)
Date: Mon, 15 Oct 2012 21:40:47 +0200
Subject: [PATCH 2/4] mtd: devices: elm: Add support for ELM error
 correction
In-Reply-To: <1349274589-11389-3-git-send-email-avinashphilip@ti.com> (Avinash
 Philip's message of "Wed, 3 Oct 2012 19:59:47 +0530")
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-3-git-send-email-avinashphilip@ti.com>
Message-ID: <87hapvv800.fsf@macbook.be.48ers.dk>

>>>>> Philip, Avinash <avinashphilip at ti.com> writes:

 > Platforms containing the ELM module can be used to correct errors
 > reported by BCH 4, 8 & 16 bit ECC scheme. For now only 4 & 8 bit
 > support is added.

This sounds odd to me. What about something like:

The ELM hardware module can be used to speedup BCH 4/8/16 ECC scheme
error correction.

For now only 4 & 8 bit support is added.


 > +++ b/drivers/mtd/devices/Makefile
 > @@ -17,8 +17,10 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 >  obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 >  obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 >  obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
 > +obj-$(CONFIG_MTD_NAND_OMAP2)	+= elm.o

You seem to only use it in 4/4 if CONFIG_MTD_NAND_OMAP_BCH is set, so it
probably makes more sense to use that symbol to not needlessly include
it if it won't be used.


 > +++ b/drivers/mtd/devices/elm.c
 > @@ -0,0 +1,440 @@
 > +/*
 > + * Error Location Module
 > + *
 > + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 > + *
 > + * This program is free software; you can redistribute it and/or modify
 > + * it under the terms of the GNU General Public License as published by
 > + * the Free Software Foundation; either version 2 of the License, or
 > + * (at your option) any later version.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +
 > +#include <linux/platform_device.h>
 > +#include <linux/module.h>
 > +#include <linux/interrupt.h>
 > +#include <linux/io.h>
 > +#include <linux/of.h>
 > +#include <linux/pm_runtime.h>
 > +#include <linux/platform_data/elm.h>
 > +
 > +#define ELM_IRQSTATUS			0x018
 > +#define ELM_IRQENABLE			0x01c
 > +#define ELM_LOCATION_CONFIG		0x020
 > +#define ELM_PAGE_CTRL			0x080
 > +#define ELM_SYNDROME_FRAGMENT_0		0x400
 > +#define ELM_SYNDROME_FRAGMENT_6		0x418
 > +#define ELM_LOCATION_STATUS		0x800
 > +#define ELM_ERROR_LOCATION_0		0x880
 > +
 > +/* ELM Interrupt Status Register */
 > +#define INTR_STATUS_PAGE_VALID		BIT(8)
 > +
 > +/* ELM Interrupt Enable Register */
 > +#define INTR_EN_PAGE_MASK		BIT(8)
 > +
 > +/* ELM Location Configuration Register */
 > +#define ECC_BCH_LEVEL_MASK		0x3
 > +
 > +/* ELM syndrome */
 > +#define ELM_SYNDROME_VALID		BIT(16)
 > +
 > +/* ELM_LOCATION_STATUS Register */
 > +#define ECC_CORRECTABLE_MASK		BIT(8)
 > +#define ECC_NB_ERRORS_MASK		0x1f
 > +
 > +/* ELM_ERROR_LOCATION_0-15 Registers */
 > +#define ECC_ERROR_LOCATION_MASK		0x1fff
 > +
 > +#define ELM_ECC_SIZE			0x7ff
 > +
 > +#define SYNDROME_FRAGMENT_REG_SIZE	0x40
 > +#define ERROR_LOCATION_SIZE		0x100
 > +#define MAX_BCH_ELM_ERROR		16
 > +#define ELM_FRAGMENT_REG		7
 > +
 > +typedef u32 syn_t[ELM_FRAGMENT_REG];
 > +typedef u32 elm_error_t[MAX_BCH_ELM_ERROR];
 > +
 > +struct elm_info {
 > +	struct device *dev;
 > +	void __iomem *elm_base;
 > +	struct completion elm_completion;
 > +	struct list_head list;
 > +	enum bch_ecc bch_type;
 > +};
 > +
 > +static LIST_HEAD(elm_devices);
 > +
 > +static void elm_write_reg(void *offset, u32 val)
 > +{
 > +	writel(val, offset);
 > +}
 > +
 > +static u32 elm_read_reg(void *offset)
 > +{
 > +	return readl(offset);
 > +}

As written these read/write wrappers don't add anything. How about
passing struct elm_info and offset as an integer so you can drop
elm_base from all call sites, E.G.:

static void elm_write_reg(struct elm_info *info, int offset, u32 val)
{
        writel(val, info->elm_base + offset);
}


 > +
 > +/**
 > + * elm_config - Configure ELM module
 > + * @info:	elm info
 > + */
 > +static void elm_config(struct elm_info *info)
 > +{
 > +	u32 reg_val;
 > +
 > +	reg_val = (info->bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
 > +	elm_write_reg(info->elm_base + ELM_LOCATION_CONFIG, reg_val);
 > +}
 > +
 > +/**
 > + * elm_configure_page_mode - Enable/Disable page mode
 > + * @info:	elm info
 > + * @index:	index number of syndrome fragment vector
 > + * @enable:	enable/disable flag for page mode
 > + *
 > + * Enable page mode for syndrome fragment index
 > + */
 > +static void elm_configure_page_mode(struct elm_info *info, int index,
 > +		bool enable)
 > +{
 > +	u32 reg_val;
 > +
 > +	reg_val = elm_read_reg(info->elm_base + ELM_PAGE_CTRL);
 > +	if (enable)
 > +		reg_val |= BIT(index);	/* enable page mode */
 > +	else
 > +		reg_val &= ~BIT(index);	/* disable page mode */
 > +
 > +	elm_write_reg(info->elm_base + ELM_PAGE_CTRL, reg_val);
 > +}
 > +
 > +static void rearrange_bch4(u8 *syndrome)
 > +{
 > +	/*
 > +	 * BCH4 has 52 bit used for ecc, but OOB stored with
 > +	 * nibble 0 appended, removes appended 0 nibble
 > +	 */
 > +	u64 *dst = (u64 *)syndrome;
 > +	*dst >>= 4;
 > +}
 > +
 > +/**
 > + * elm_reverse_eccdata - Reverse ecc data
 > + * @info:	elm info
 > + * @ecc_data:	buffer for calculated ecc
 > + * @syndrome:	buffer for syndrome polynomial
 > + *
 > + * ecc_data has to be reversed for syndrome vector
 > + */
 > +static void elm_reverse_eccdata(struct elm_info *info, u8 *ecc_data,
 > +		u8 *syndrome)
 > +{
 > +	int i;
 > +	int bch_size = info->bch_type ? BCH8_ECC_OOB_BYTES : BCH4_SIZE;
 > +
 > +	for (i = 0; i < bch_size; i++)
 > +		syndrome[bch_size - 1 - i] = ecc_data[i];
 > +
 > +	/*
 > +	 * syndrome polynomial to be rearranged for BCH 4 ecc scheme as 52
 > +	 * bits being used and 4 bits being appended in syndrome vector
 > +	 */
 > +	if (info->bch_type == BCH4_ECC)
 > +		rearrange_bch4(syndrome);
 > +}
 > +
 > +/**
 > + * elm_load_syndrome - Load ELM syndrome reg
 > + * @info:	elm info
 > + * @index:	syndrome fragment index
 > + * @syndrome:	Syndrome polynomial
 > + *
 > + * Load syndrome fragment registers with syndrome polynomial
 > + */
 > +static void elm_load_syndrome(struct elm_info *info, int index, u8 *syndrome)
 > +{
 > +	int i;
 > +	int max = info->bch_type ? BCH8_SYNDROME_SIZE : BCH4_SYNDROME_SIZE;
 > +	void *syn_frag_base = info->elm_base + ELM_SYNDROME_FRAGMENT_0;
 > +	syn_t *syn_fragment;
 > +	u32 reg_val;
 > +
 > +	elm_configure_page_mode(info, index, true);
 > +	syn_fragment = syn_frag_base + SYNDROME_FRAGMENT_REG_SIZE * index;
 > +
 > +	for (i = 0; i < max; i++) {
 > +		reg_val = syndrome[0] | syndrome[1] << 8 | syndrome[2] << 16 |
 > +			syndrome[3] << 24;
 > +		elm_write_reg(*syn_fragment + i, reg_val);
 > +		/* Update syndrome polynomial pointer */
 > +		syndrome += 4;
 > +	}
 > +}
 > +
 > +/**
 > + * elm_start_processing - start elm syndrome processing
 > + * @info:	elm info
 > + * @err_vec:	elm error vectors
 > + *
 > + * Set syndrome valid bit for syndrome fragment registers for which
 > + * elm syndrome fragment registers are loaded. This enables elm module
 > + * to start processing syndrome vectors.
 > + */
 > +static void elm_start_processing(struct elm_info *info,
 > +		struct elm_errorvec *err_vec)
 > +{
 > +	int i;
 > +	void *offset;
 > +	u32 reg_val;
 > +
 > +	/*
 > +	 * Set syndrome vector valid so that ELM module will process it for
 > +	 * vectors error is reported
 > +	 */
 > +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
 > +		if (err_vec[i].error_reported) {
 > +			offset = info->elm_base + ELM_SYNDROME_FRAGMENT_6 + i *
 > +				SYNDROME_FRAGMENT_REG_SIZE;
 > +			reg_val = elm_read_reg(offset);
 > +			reg_val |= ELM_SYNDROME_VALID;
 > +			elm_write_reg(offset, reg_val);
 > +		}
 > +	}
 > +}
 > +
 > +/**
 > + * elm_error_correction - locate correctable error position
 > + * @info:	elm info
 > + * @err_vec:	elm error vectors
 > + *
 > + * On completion of processing by elm module, error location status
 > + * register updated with correctable/uncorrectable error information.
 > + * In case of correctable errors, number of errors located from
 > + * elm location status register & read the these many positions from
 > + * elm error location register.
 > + */
 > +static void elm_error_correction(struct elm_info *info,
 > +		struct elm_errorvec *err_vec)
 > +{
 > +	int i, j, errors = 0;
 > +	void *err_loc_base = info->elm_base + ELM_ERROR_LOCATION_0;
 > +	elm_error_t *err_loc;
 > +	void *offset;
 > +	u32 reg_val;
 > +
 > +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
 > +		/* check error reported */
 > +		if (err_vec[i].error_reported) {
 > +			offset = info->elm_base + ELM_LOCATION_STATUS +
 > +				i * ERROR_LOCATION_SIZE;
 > +			reg_val = elm_read_reg(offset);
 > +			/* check correctable error or not */
 > +			if (reg_val & ECC_CORRECTABLE_MASK) {
 > +				err_loc = err_loc_base +
 > +					i * ERROR_LOCATION_SIZE;
 > +				/* read count of correctable errors */
 > +				err_vec[i].error_count = reg_val &
 > +					ECC_NB_ERRORS_MASK;
 > +
 > +				/* update the error locations in error vector */
 > +				for (j = 0; j < err_vec[i].error_count; j++) {
 > +
 > +					reg_val = elm_read_reg(*err_loc + j);
 > +					err_vec[i].error_loc[j] = reg_val &
 > +						ECC_ERROR_LOCATION_MASK;
 > +				}
 > +
 > +				errors += err_vec[i].error_count;
 > +			} else {
 > +				err_vec[i].error_uncorrectable++;
 > +			}
 > +
 > +			/* clearing interrupts for processed error vectors */
 > +			elm_write_reg(info->elm_base + ELM_IRQSTATUS, BIT(i));
 > +
 > +			/* disable page mode */
 > +			elm_configure_page_mode(info, i, false);
 > +		}
 > +	}
 > +
 > +	return;
 > +}
 > +
 > +/**
 > + * elm_decode_bch_error_page - Locate error position
 > + * @info:	elm info
 > + * @ecc_calc:	calculated ECC bytes from GPMC
 > + * @err_vec:	elm error vectors
 > + *
 > + * Called with one or greater reported and is vectors with error reported
 > + * is updated in err_vec[].error_reported
 > + */
 > +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
 > +		struct elm_errorvec *err_vec)
 > +{
 > +	int i;
 > +	u8 syndrome[BCH_MAX_ECC_BYTES_PER_SECTOR] = {0}, *syn_p;


Why do you need to keep the entire syndrome around? You seem to only use
it between elm_reverse_eccdata() and elm_load_syndrome(), so it could as
well be BCH8_ECC_OOB_BYTES long (or rather a multiple of sizeof(u32).

It would also be good to do the shuffeling directly in elm_load_syndrome
so you don't need the extra copy.


 > +	struct elm_info *info = dev_get_drvdata(dev);
 > +	u32 reg_val;
 > +
 > +	/* enable page mode interrupt */
 > +	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
 > +	elm_write_reg(info->elm_base + ELM_IRQSTATUS,
 > +			reg_val & INTR_STATUS_PAGE_VALID);
 > +	elm_write_reg(info->elm_base + ELM_IRQENABLE, INTR_EN_PAGE_MASK);
 > +
 > +	syn_p = syndrome;
 > +	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
 > +		if (err_vec[i].error_reported) {
 > +			elm_reverse_eccdata(info, ecc_calc, syn_p);
 > +			elm_load_syndrome(info, i, syn_p);
 > +		}
 > +
 > +		ecc_calc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
 > +		syn_p += OOB_SECTOR_SIZE;
 > +	}
 > +
 > +	elm_start_processing(info, err_vec);
 > +
 > +	/*
 > +	 * In case of error reported, wait for ELM module to finish
 > +	 * locating error correction
 > +	 */
 > +	wait_for_completion(&info->elm_completion);
 > +
 > +	/* disable page mode interrupt */
 > +	reg_val = elm_read_reg(info->elm_base + ELM_IRQENABLE);
 > +	elm_write_reg(info->elm_base + ELM_IRQENABLE,
 > +			reg_val & ~INTR_EN_PAGE_MASK);
 > +	elm_error_correction(info, err_vec);
 > +}
 > +EXPORT_SYMBOL(elm_decode_bch_error_page);
 > +
 > +static irqreturn_t elm_isr(int this_irq, void *dev_id)
 > +{
 > +	u32 reg_val;
 > +	struct elm_info *info = dev_id;
 > +
 > +	reg_val = elm_read_reg(info->elm_base + ELM_IRQSTATUS);
 > +
 > +	/* all error vectors processed */
 > +	if (reg_val & INTR_STATUS_PAGE_VALID) {
 > +		elm_write_reg(info->elm_base + ELM_IRQSTATUS,
 > +				reg_val & INTR_STATUS_PAGE_VALID);
 > +		complete(&info->elm_completion);
 > +		return IRQ_HANDLED;
 > +	}
 > +
 > +	return IRQ_NONE;
 > +}
 > +
 > +struct device *elm_request(enum bch_ecc bch_type)
 > +{
 > +	struct elm_info *info;
 > +
 > +	list_for_each_entry(info, &elm_devices, list) {
 > +		if (info && info->dev) {
 > +				info->bch_type = bch_type;
 > +				elm_config(info);
 > +				return info->dev;
 > +		}
 > +	}
 > +
 > +	return NULL;
 > +}
 > +EXPORT_SYMBOL(elm_request);
 > +
 > +static int __devinit elm_probe(struct platform_device *pdev)
 > +{
 > +	int ret = 0;
 > +	struct resource *res, *irq;
 > +	struct elm_info *info;
 > +
 > +	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 > +	if (!info) {
 > +		dev_err(&pdev->dev, "failed to allocate memory\n");
 > +		return -ENOMEM;
 > +	}
 > +
 > +	info->dev = &pdev->dev;
 > +
 > +	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 > +	if (!irq) {
 > +		dev_err(&pdev->dev, "no irq resource defined\n");
 > +		return -ENODEV;
 > +	}
 > +
 > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 > +	if (!res) {
 > +		dev_err(&pdev->dev, "no memory resource defined\n");
 > +		return -ENODEV;
 > +	}
 > +
 > +
 > +	info->elm_base = devm_request_and_ioremap(&pdev->dev, res);
 > +	if (!info->elm_base)
 > +		return -EADDRNOTAVAIL;
 > +
 > +
 > +	ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0,
 > +			pdev->name, info);
 > +	if (ret) {
 > +		dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start);
 > +		return ret;
 > +	}
 > +
 > +	pm_runtime_enable(&pdev->dev);
 > +	if (pm_runtime_get_sync(&pdev->dev)) {
 > +		ret = -EINVAL;
 > +		pm_runtime_disable(&pdev->dev);
 > +		dev_err(&pdev->dev, "can't enable clock\n");
 > +		return ret;
 > +	}
 > +
 > +	init_completion(&info->elm_completion);
 > +	INIT_LIST_HEAD(&info->list);
 > +	list_add(&info->list, &elm_devices);
 > +	platform_set_drvdata(pdev, info);
 > +	return ret;
 > +}
 > +
 > +static int __devexit elm_remove(struct platform_device *pdev)
 > +{
 > +	pm_runtime_put_sync(&pdev->dev);
 > +	pm_runtime_disable(&pdev->dev);
 > +	platform_set_drvdata(pdev, NULL);
 > +	return 0;
 > +}
 > +
 > +
 > +#ifdef CONFIG_OF
 > +static const struct of_device_id elm_of_match[] = {
 > +	{ .compatible = "ti,elm" },
 > +	{},
 > +};
 > +MODULE_DEVICE_TABLE(of, elm_of_match);
 > +#endif
 > +
 > +static struct platform_driver elm_driver = {
 > +	.driver		= {
 > +		.name	= "elm",
 > +		.of_match_table = of_match_ptr(elm_of_match),
 > +		.owner	= THIS_MODULE,
 > +	},
 > +	.probe		= elm_probe,
 > +	.remove		= __devexit_p(elm_remove),
 > +};
 > +
 > +module_platform_driver(elm_driver);
 > +
 > +MODULE_DESCRIPTION("ELM driver for BCH error correction");
 > +MODULE_AUTHOR("Texas Instruments");
 > +MODULE_ALIAS("platform: elm");
 > +MODULE_LICENSE("GPL v2");
 > diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
 > new file mode 100644
 > index 0000000..eb53163
 > --- /dev/null
 > +++ b/include/linux/platform_data/elm.h
 > @@ -0,0 +1,60 @@
 > +/*
 > + * BCH Error Location Module
 > + *
 > + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 > + *
 > + * This program is free software; you can redistribute it and/or modify
 > + * it under the terms of the GNU General Public License as published by
 > + * the Free Software Foundation; either version 2 of the License, or
 > + * (at your option) any later version.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +
 > +#ifndef __ELM_H
 > +#define __ELM_H
 > +
 > +enum bch_ecc {
 > +	BCH4_ECC = 0,
 > +	BCH8_ECC,
 > +	BCH16_ECC,

It probably makes more sense to not provide the enum value for BCH16 as
you don't support it.


 > +};
 > +
 > +/* ELM support 8 error syndrome process */
 > +#define ERROR_VECTOR_MAX		8
 > +#define OOB_SECTOR_SIZE			16
 > +
 > +#define BCH_MAX_ECC_BYTES_PER_SECTOR	(OOB_SECTOR_SIZE * ERROR_VECTOR_MAX)
 > +
 > +#define BCH8_ECC_OOB_BYTES		13
 > +/* RBL requires 14 byte even though BCH8 uses only 13 byte */
 > +#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
 > +#define BCH4_SIZE			7
 > +
 > +#define	BCH8_SYNDROME_SIZE		4	/* 13 bytes of ecc */
 > +#define	BCH4_SYNDROME_SIZE		2	/* 7 bytes of ecc */
 > +
 > +/**
 > + * struct elm_errorvec - error vector for elm
 > + * @error_reported:		set true for vectors error is reported
 > + *
 > + * @error_count:		number of correctable errors in the sector
 > + * @error_uncorrectable:	number of uncorrectable errors
 > + * @error_loc:			buffer for error location
 > + *
 > + */
 > +struct elm_errorvec {
 > +	bool error_reported;
 > +	int error_count;
 > +	int error_uncorrectable;
 > +	int error_loc[ERROR_VECTOR_MAX];
 > +};
 > +
 > +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
 > +		struct elm_errorvec *err_vec);
 > +struct device *elm_request(enum bch_ecc bch_type);
 > +#endif /* __ELM_H */
 > -- 
 > 1.7.0.4


 > ______________________________________________________
 > Linux MTD discussion mailing list
 > http://lists.infradead.org/mailman/listinfo/linux-mtd/


-- 
Bye, Peter Korsgaard


From linus.walleij at linaro.org  Mon Oct 15 15:51:59 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 15 Oct 2012 21:51:59 +0200
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
 <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
Message-ID: <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>

On Mon, Oct 15, 2012 at 6:27 PM, Brian Norris
<computersforpeace at gmail.com> wrote:

> I would prefer not building a solution that hopes kmalloc() can get a
> large contiguous buffer (remember, eraseblock sizes come as large as
> 2MB these days). A real solution like CMA or scatter-gather seems like
> a better idea.

+1 on that, and as I think I illustrated the MMC subsystem is using
the block layer helpers to form scatter-gather lists for it's requests.
I don't see why the MTD subsystem need to be very different?

Yours,
Linus Walleij


From dwmw2 at infradead.org  Mon Oct 15 16:00:33 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon, 15 Oct 2012 13:00:33 -0700
Subject: [PATCH] [MTD] Adjust the NOR CFI flash timeouts to round better
In-Reply-To: <1350329299.1509.6.camel@kyv>
References: <20121005183202.GA11385@obsidianresearch.com>
 <1350308556.5769.5.camel@sauron.fi.intel.com>
 <1350317380.14124.26.camel@shinybook.infradead.org>
 <1350329299.1509.6.camel@kyv>
Message-ID: <1350331233.31862.1.camel@shinybook.infradead.org>

On Mon, 2012-10-15 at 22:28 +0300, Artem Bityutskiy wrote:
>  Also, HZ / 1500 would be 0 for HZ < 1500, since we are using integer
> arithmetic.

Hence the +1. One of them, at least.

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121015/dcdb6088/attachment.bin>

From elezegarcia at gmail.com  Mon Oct 15 17:28:42 2012
From: elezegarcia at gmail.com (Ezequiel Garcia)
Date: Mon, 15 Oct 2012 18:28:42 -0300
Subject: Unstable bits CEWG project
Message-ID: <CALF0-+XMSfxrXDM0GiEfu0jtDHKv7O0hFPtsZ2=LGUcGz-ctVQ@mail.gmail.com>

Hello all,

I'm considering to propose myself as a candidate for the CEWG funded
"Unstable bits" project [1].

I'd like to know if anyone has considered the posibility of adding
power-cut emulation to nandsim driver;
or if this is just a stupid idea.

Thanks,
Ezequiel.

[1] http://elinux.org/Start_working_on_the_%22unstable_bits%22_issue_to_make_UBIFS_more_robust


From ricard.wanderlof at axis.com  Mon Oct 15 18:22:48 2012
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Tue, 16 Oct 2012 00:22:48 +0200
Subject: Unstable bits CEWG project
In-Reply-To: <CALF0-+XMSfxrXDM0GiEfu0jtDHKv7O0hFPtsZ2=LGUcGz-ctVQ@mail.gmail.com>
References: <CALF0-+XMSfxrXDM0GiEfu0jtDHKv7O0hFPtsZ2=LGUcGz-ctVQ@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1210160017370.24739@lnxricardw.se.axis.com>


On Mon, 15 Oct 2012, Ezequiel Garcia wrote:

> I'm considering to propose myself as a candidate for the CEWG funded
> "Unstable bits" project [1].
>
> I'd like to know if anyone has considered the posibility of adding 
> power-cut emulation to nandsim driver; or if this is just a stupid idea.

I think the idea is good. My only doubts would be how well-defined the 
'unstable bits' behavior in real chips is, in order to be able to model it 
to the required accuracy (i.e. so that the resulting work in the software 
will be viable in a real-life situation ) in nandsim. Although most likely 
even with a fairly basic model quite an improvement could be made in the 
way it is handled.

/Ricard
-- 
Ricard Wolf Wanderl?f                           ricardw(at)axis.com
Axis Communications AB, Lund, Sweden            www.axis.com
Phone +46 46 272 2016                           Fax +46 46 13 61 30


From gerg at snapgear.com  Mon Oct 15 21:13:05 2012
From: gerg at snapgear.com (Greg Ungerer)
Date: Tue, 16 Oct 2012 11:13:05 +1000
Subject: [PATCH 1/2 RFC v2] mtd/uclinux: support ROM and allow passing
 the base address
In-Reply-To: <20121015065855.GG639@pengutronix.de>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <507B8DBF.2030104@snapgear.com> <20121015065855.GG639@pengutronix.de>
Message-ID: <507CB4A1.4080609@snapgear.com>

Hi Uwe,

On 15/10/12 16:58, Uwe Kleine-K?nig wrote:
> On Mon, Oct 15, 2012 at 02:14:55PM +1000, Greg Ungerer wrote:
>>>   	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
>>> @@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
>>>
>>>   	simple_map_init(mapp);
>>>
>>> -	mtd = do_map_probe("map_ram", mapp);
>>> +	mapp->name = "ROM";
>>> +	mtd = do_map_probe("map_rom", mapp);
>>> +	if (!mtd) {
>>> +		/* fall back to ram probing for compatibility reasons */
>>> +		mapp->name = "RAM";
>>> +		mtd = do_map_probe("map_ram", mapp);
>>> +		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
>>> +			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
>>
>> Do we really want this message?
>> My predominate usage of this code is in RAM mappings. Network
>> loading kernel+filesystem images on bare boards. Anyone who wants
>> to know and is looking in the kernel boot messages will see
>> something like:
>>
>>      Creating 1 MTD partitions on "RAM":
>>      0x000000000000-0x0000000d8000 : "ROMfs"
>>
>> So they will know what type of mapping it was loaded from.
> I want it because if nobody reports it it might well be possible to drop
> map_ram support.

I am not sure I follow. The message is only printed if both ROM and
RAM mappings are enabled. Many of the configs I use only have RAM
mappings enabled.

Regards
Greg

  
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


From josh.wu at atmel.com  Tue Oct 16 02:48:03 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 16 Oct 2012 14:48:03 +0800
Subject: [PATCH] MTD: atmel_nand: fix compile error when use
 avr32-atstk1006_defconfig
In-Reply-To: <1350308938.5769.7.camel@sauron.fi.intel.com>
References: <1349678809-12092-1-git-send-email-josh.wu@atmel.com>
 <1350308938.5769.7.camel@sauron.fi.intel.com>
Message-ID: <507D0323.6010207@atmel.com>

On 10/15/2012 9:48 PM, Artem Bityutskiy wrote:
> On Mon, 2012-10-08 at 14:46 +0800, Josh Wu wrote:
>> fixed the following compile error when use avr32 config:
>> drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
>> drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
>>
>> Since in ARCH avr32, there is no macro "writel_relaxed" defined. In this patch we use macro "writel" instead.
>>
>> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> Why not to provide writel_relaxed() in AVR instead?
>
OK, I can send another patch to add writel_relaxed() in AVR. Since I 
don't have any AVR board in my hand, I need someone test it. thank you.

Best Regards,
Josh Wu


From dedekind1 at gmail.com  Tue Oct 16 02:55:52 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 16 Oct 2012 09:55:52 +0300
Subject: Unstable bits CEWG project
In-Reply-To: <CALF0-+XMSfxrXDM0GiEfu0jtDHKv7O0hFPtsZ2=LGUcGz-ctVQ@mail.gmail.com>
References: <CALF0-+XMSfxrXDM0GiEfu0jtDHKv7O0hFPtsZ2=LGUcGz-ctVQ@mail.gmail.com>
Message-ID: <1350370552.5769.31.camel@sauron.fi.intel.com>

On Mon, 2012-10-15 at 18:28 -0300, Ezequiel Garcia wrote:
> Hello all,
> 
> I'm considering to propose myself as a candidate for the CEWG funded
> "Unstable bits" project [1].
> 
> I'd like to know if anyone has considered the posibility of adding
> power-cut emulation to nandsim driver;
> or if this is just a stupid idea.

I'd suggest to add this in UBI instead.

1. nandsim is quite unreadable already and difficult to deal with
2. UBI is cleaner and all the I/O goes through functions in the io.c
   file.
3. By having it in UBI it is possible to force p-c emulation in
   interesting places, like when we are updating the volume table,
   or recovering from a failed write, or torturing a PEB, or writing
   EC/VID headers, or doing something fastmap-related.

   If you do this in nandsim, you will get 99% of power cuts when
   writing data, so you will mostly test this, and very rarely cover
   other places, unless you run for days.

   We passes through this when developing UBIFS, and this is why we
   put the power-cut emulation to UBIFS. I guess nowadays you can move
   it down to UBI.

Also, FYI, we have the integck test which supports emulated power-cut
testing for UBIFS.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121016/da2c6aba/attachment-0001.sig>

From u.kleine-koenig at pengutronix.de  Tue Oct 16 02:56:11 2012
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Tue, 16 Oct 2012 08:56:11 +0200
Subject: [PATCH 1/2 RFC v2] mtd/uclinux: support ROM and allow passing
 the base address
In-Reply-To: <507CB4A1.4080609@snapgear.com>
References: <1349709952-4332-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1350027693-19528-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <507B8DBF.2030104@snapgear.com>
 <20121015065855.GG639@pengutronix.de>
 <507CB4A1.4080609@snapgear.com>
Message-ID: <20121016065611.GP639@pengutronix.de>

Hello Greg,

On Tue, Oct 16, 2012 at 11:13:05AM +1000, Greg Ungerer wrote:
> On 15/10/12 16:58, Uwe Kleine-K?nig wrote:
> >On Mon, Oct 15, 2012 at 02:14:55PM +1000, Greg Ungerer wrote:
> >>>  	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
> >>>@@ -76,9 +83,18 @@ static int __init uclinux_mtd_init(void)
> >>>
> >>>  	simple_map_init(mapp);
> >>>
> >>>-	mtd = do_map_probe("map_ram", mapp);
> >>>+	mapp->name = "ROM";
> >>>+	mtd = do_map_probe("map_rom", mapp);
> >>>+	if (!mtd) {
> >>>+		/* fall back to ram probing for compatibility reasons */
> >>>+		mapp->name = "RAM";
> >>>+		mtd = do_map_probe("map_ram", mapp);
> >>>+		if (mtd && IS_ENABLED(CONFIG_MTD_ROM))
> >>>+			pr_err("Failed to map rom, but ram succeeded. Please report this issue!\n");
> >>
> >>Do we really want this message?
> >>My predominate usage of this code is in RAM mappings. Network
> >>loading kernel+filesystem images on bare boards. Anyone who wants
> >>to know and is looking in the kernel boot messages will see
> >>something like:
> >>
> >>     Creating 1 MTD partitions on "RAM":
> >>     0x000000000000-0x0000000d8000 : "ROMfs"
> >>
> >>So they will know what type of mapping it was loaded from.
> >I want it because if nobody reports it it might well be possible to drop
> >map_ram support.
> 
> I am not sure I follow. The message is only printed if both ROM and
> RAM mappings are enabled. Many of the configs I use only have RAM
> mappings enabled.
Yeah, in this case it doesn't help. I also thought about adding a
warning for !IS_ENABLED(CONFIG_MTD_ROM). But this seemed too harsh, so I
dropped the idea.

Still, the theory is that MTD_ROM should be enough for the uclinux map.
If it's not it's at least not silently fixed up and we might get a
report about what was wrong with my assumption.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From dedekind1 at gmail.com  Tue Oct 16 03:11:51 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 16 Oct 2012 10:11:51 +0300
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com> <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
Message-ID: <1350371511.5769.43.camel@sauron.fi.intel.com>

On Mon, 2012-10-15 at 09:27 -0700, Brian Norris wrote:
> > I'd really prefer to just switch to kmalloc() everywhere instead of
> > adding hacks like this to the drivers. Then if this is a problem for
> > someone, he can fix it by either switching to smaller buffers (possible
> > in many places), or by improving memory fragmentation issues on his
> > system, or by just using CMA.
> 
> I think I can suggest that this is already a problem on real systems.
> In bringing up a board on v3.3 kernel, I experienced a kernel memory
> allocation error when trying to memdup_user() in eraseblock-size
> regions. I believe I would experience more of these if all
> eraseblock-sized buffers were kmalloc()'d.
> 
> See the commit description for the following commit in mtd-utils.git:
> 
>     commit 71c76e74661492b4f68f670514866cfc85f47089
>     libmtd: fix mtd_write() issues for large data-only writes

Well, this is another work-around. The better way to fix this would be
to change kernel's 'mtdchar_write_ioctl()' to be iterative and avoid
calling 'memdup_user(len)' for arbitrary 'len' passed from user-space.

> I would prefer not building a solution that hopes kmalloc() can get a
> large contiguous buffer (remember, eraseblock sizes come as large as
> 2MB these days). A real solution like CMA or scatter-gather seems like
> a better idea.

Me too. But this does not happen. People bring this up for years. Of
course it is easier to hack drivers, and very understandable. So what
I would like to do is somehow force people to fix this issue.

So I thought about something like introducing an mtd_alloc() which
would:
   a. Try doing CMA allocation: dma_alloc_from_contiguous()
   b. If it fails, use kmalloc().

This function would probably need a cookie which it returns and which
the mtd_free() function would use to call either kfree() or
dma_release_from_contiguous()...

If both fail - bad luck. Go look at the code and switch to S-G lists
instead of allocating contiguous regions. As I said, in many places it
is easy to do, and there are few places when you would need to spend a
bit more time.

How does this sound to you?

-- 
Best Regards,
Artem Bityutskiy


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121016/04d3c8f5/attachment.sig>

From dedekind1 at gmail.com  Tue Oct 16 03:14:45 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 16 Oct 2012 10:14:45 +0300
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com> <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
Message-ID: <1350371685.5769.45.camel@sauron.fi.intel.com>

On Mon, 2012-10-15 at 21:51 +0200, Linus Walleij wrote:
> On Mon, Oct 15, 2012 at 6:27 PM, Brian Norris
> <computersforpeace at gmail.com> wrote:
> 
> > I would prefer not building a solution that hopes kmalloc() can get a
> > large contiguous buffer (remember, eraseblock sizes come as large as
> > 2MB these days). A real solution like CMA or scatter-gather seems like
> > a better idea.
> 
> +1 on that, and as I think I illustrated the MMC subsystem is using
> the block layer helpers to form scatter-gather lists for it's requests.
> I don't see why the MTD subsystem need to be very different?

This is good idea, the problem is that it is a bit more work than
hacking the driver, so most people prefer the latter. By removing all
kmalloc()'s I basically wish to force people to go this way.

What are the SC functions names you refer?

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121016/e67d78eb/attachment.sig>

From josh.wu at atmel.com  Tue Oct 16 03:19:27 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 16 Oct 2012 15:19:27 +0800
Subject: [PATCH] avr32: fix build error in atstk1006_defconfig
Message-ID: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>

fixed the following compile error when use avr32 atstk1006_defconfig:
  drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
  drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'

which was introduced by commit 1c7b874d33b463 ("mtd: at91: atmel_nand: add Programmable Multibit ECC controller support").
The PMECC for nand flash code uses writel_relaxed(). But in avr32, there is no macro "writel_relaxed" defined. This patch add writex_relaxed macro definitions.

Signed-off-by: Josh Wu <josh.wu at atmel.com>
---
 arch/avr32/include/asm/io.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
index cf60d0a..fc6483f 100644
--- a/arch/avr32/include/asm/io.h
+++ b/arch/avr32/include/asm/io.h
@@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32)
 #define readw_be			__raw_readw
 #define readl_be			__raw_readl
 
+#define writeb_relaxed			writeb
+#define writew_relaxed			writew
+#define writel_relaxed			writel
+
 #define writeb_be			__raw_writeb
 #define writew_be			__raw_writew
 #define writel_be			__raw_writel
-- 
1.7.9.5



From egtvedt at samfundet.no  Tue Oct 16 05:17:40 2012
From: egtvedt at samfundet.no (Hans-Christian Egtvedt)
Date: Tue, 16 Oct 2012 11:17:40 +0200
Subject: [PATCH] avr32: fix build error in atstk1006_defconfig
In-Reply-To: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
References: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
Message-ID: <20121016091740.GA6243@samfundet.no>

Around Tue 16 Oct 2012 15:19:27 +0800 or thereabout, Josh Wu wrote:
> fixed the following compile error when use avr32 atstk1006_defconfig:
>   drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
>   drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
> 
> which was introduced by commit 1c7b874d33b463 ("mtd: at91: atmel_nand: add Programmable Multibit ECC controller support").
> The PMECC for nand flash code uses writel_relaxed(). But in avr32, there is no macro "writel_relaxed" defined. This patch add writex_relaxed macro definitions.
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> ---
>  arch/avr32/include/asm/io.h |    4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
> index cf60d0a..fc6483f 100644
> --- a/arch/avr32/include/asm/io.h
> +++ b/arch/avr32/include/asm/io.h
> @@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32)
>  #define readw_be			__raw_readw
>  #define readl_be			__raw_readl
>  
> +#define writeb_relaxed			writeb
> +#define writew_relaxed			writew
> +#define writel_relaxed			writel
> +

I'm wondering if they should be something similar to SH arch:

#define writeb_relaxed(v,c) ((void)__raw_writeb((__force u8)ioswabb(v),c))

What is the intention behind the macro? Which restriction is relaxed?

>  #define writeb_be			__raw_writeb
>  #define writew_be			__raw_writew
>  #define writel_be			__raw_writel

-- 
mvh
Hans-Christian Egtvedt


From linus.walleij at linaro.org  Tue Oct 16 06:05:12 2012
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 16 Oct 2012 12:05:12 +0200
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <1350371685.5769.45.camel@sauron.fi.intel.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
 <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
 <1350371685.5769.45.camel@sauron.fi.intel.com>
Message-ID: <CACRpkdY2=PLS_MT1h_nQJj+2ju26yXtt-aXSi=t9uUQ5+WJasA@mail.gmail.com>

On Tue, Oct 16, 2012 at 9:14 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> On Mon, 2012-10-15 at 21:51 +0200, Linus Walleij wrote:
>> On Mon, Oct 15, 2012 at 6:27 PM, Brian Norris
>> <computersforpeace at gmail.com> wrote:
>>
>> > I would prefer not building a solution that hopes kmalloc() can get a
>> > large contiguous buffer (remember, eraseblock sizes come as large as
>> > 2MB these days). A real solution like CMA or scatter-gather seems like
>> > a better idea.
>>
>> +1 on that, and as I think I illustrated the MMC subsystem is using
>> the block layer helpers to form scatter-gather lists for it's requests.
>> I don't see why the MTD subsystem need to be very different?
>
> This is good idea, the problem is that it is a bit more work than
> hacking the driver, so most people prefer the latter. By removing all
> kmalloc()'s I basically wish to force people to go this way.
>
> What are the SC functions names you refer?

I'm mainly thinking of blk_rq_map_sg()
from block/blk-merge.c

Yours,
Linus Walleij


From josh.wu at atmel.com  Tue Oct 16 06:30:50 2012
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 16 Oct 2012 18:30:50 +0800
Subject: [PATCH] avr32: fix build error in atstk1006_defconfig
In-Reply-To: <20121016091740.GA6243@samfundet.no>
References: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
 <20121016091740.GA6243@samfundet.no>
Message-ID: <507D375A.3040200@atmel.com>

On 10/16/2012 5:17 PM, Hans-Christian Egtvedt wrote:
> Around Tue 16 Oct 2012 15:19:27 +0800 or thereabout, Josh Wu wrote:
>> fixed the following compile error when use avr32 atstk1006_defconfig:
>>    drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
>>    drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
>>
>> which was introduced by commit 1c7b874d33b463 ("mtd: at91: atmel_nand: add Programmable Multibit ECC controller support").
>> The PMECC for nand flash code uses writel_relaxed(). But in avr32, there is no macro "writel_relaxed" defined. This patch add writex_relaxed macro definitions.
>>
>> Signed-off-by: Josh Wu <josh.wu at atmel.com>
>> ---
>>   arch/avr32/include/asm/io.h |    4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
>> index cf60d0a..fc6483f 100644
>> --- a/arch/avr32/include/asm/io.h
>> +++ b/arch/avr32/include/asm/io.h
>> @@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32)
>>   #define readw_be			__raw_readw
>>   #define readl_be			__raw_readl
>>   
>> +#define writeb_relaxed			writeb
>> +#define writew_relaxed			writew
>> +#define writel_relaxed			writel
>> +
> I'm wondering if they should be something similar to SH arch:
>
> #define writeb_relaxed(v,c) ((void)__raw_writeb((__force u8)ioswabb(v),c))
>
> What is the intention behind the macro? Which restriction is relaxed?

According to my understanding, the xxx_relaxed() is that I/O function 
without any memory barriers. for Multi-cpu, the execute order are less 
limited.
So the relaxed write function should be more effective than non-relaxed one.

But for single cpu, relaxed function should work same as non-relaxed 
function.
Please correct me if I'm understand in a wrong way.

Best Regards,
Josh Wu

>
>>   #define writeb_be			__raw_writeb
>>   #define writew_be			__raw_writew
>>   #define writel_be			__raw_writel



From andreas.devel at googlemail.com  Tue Oct 16 07:30:22 2012
From: andreas.devel at googlemail.com (=?ISO-8859-1?Q?Andreas_Bie=DFmann?=)
Date: Tue, 16 Oct 2012 13:30:22 +0200
Subject: [PATCH] avr32: fix build error in atstk1006_defconfig
In-Reply-To: <20121016091740.GA6243@samfundet.no>
References: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
 <20121016091740.GA6243@samfundet.no>
Message-ID: <507D454E.6060101@gmail.com>

On 16.10.2012 11:17, Hans-Christian Egtvedt wrote:
> Around Tue 16 Oct 2012 15:19:27 +0800 or thereabout, Josh Wu wrote:
>> fixed the following compile error when use avr32 atstk1006_defconfig:
>>   drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
>>   drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
>>
>> which was introduced by commit 1c7b874d33b463 ("mtd: at91: atmel_nand: add Programmable Multibit ECC controller support").
>> The PMECC for nand flash code uses writel_relaxed(). But in avr32, there is no macro "writel_relaxed" defined. This patch add writex_relaxed macro definitions.
>>
>> Signed-off-by: Josh Wu <josh.wu at atmel.com>
>> ---
>>  arch/avr32/include/asm/io.h |    4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
>> index cf60d0a..fc6483f 100644
>> --- a/arch/avr32/include/asm/io.h
>> +++ b/arch/avr32/include/asm/io.h
>> @@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32)
>>  #define readw_be			__raw_readw
>>  #define readl_be			__raw_readl
>>  
>> +#define writeb_relaxed			writeb
>> +#define writew_relaxed			writew
>> +#define writel_relaxed			writel
>> +
> 
> I'm wondering if they should be something similar to SH arch:
> 
> #define writeb_relaxed(v,c) ((void)__raw_writeb((__force u8)ioswabb(v),c))

I think it is OK to just use the writeX here. These are in fact an
inlined function built out of a macro. The inlined function does nearly
what you have written down here and in contrast to the ARM version omits
the memory barrier.
The main difference between __raw_ access and the writeX/readX access
for AVR32 is this little __swizzle_addr_. It takes the configuration of
SMC (8/16/32 bit access) into account which would be omitted when we
switch to __raw_ accessors here. This would be a major change if one
used the writeX/readX accessors before and switched the SMC to something
different than 32 Bit access.

Best regards

Andreas Bie?mann


From marcus.prebble at axis.com  Tue Oct 16 07:51:01 2012
From: marcus.prebble at axis.com (Marcus Prebble)
Date: Tue, 16 Oct 2012 13:51:01 +0200
Subject: [PATCH] mtd: mkfs.ubifs: Improve error handling of is_contained()
Message-ID: <1350388261.25368.92.camel@lnxprebble2.se.axis.com>

mtd: mtd-utils/mkfs.ubifs: Improve error handling of is_contained()

The is_contained() function returns -1 if an error occurs when
canonicalizing the output file path/root directory. This resulted in the
confusing error message 'Error: The output file cannot be in the UBIFS
root' when specifying a non-existent directory for the output.
This patch changes the error handling to display a different error
message for the case when is_contained() returns -1.
Additionally it frees all memory allocated by is_contained().

Signed-off-by: Marcus Prebble <marcus.prebble at axis.com>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mkfs.ubifs-is-contained-err-handling.patch
Type: text/x-patch
Size: 2115 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121016/3891c13f/attachment.bin>

From havard at skinnemoen.net  Tue Oct 16 14:04:44 2012
From: havard at skinnemoen.net (=?ISO-8859-1?Q?H=E5vard_Skinnemoen?=)
Date: Tue, 16 Oct 2012 11:04:44 -0700
Subject: [PATCH] avr32: fix build error in atstk1006_defconfig
In-Reply-To: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
References: <1350371967-8914-1-git-send-email-josh.wu@atmel.com>
Message-ID: <CACiLriQ1fTbGs7eCK5eeF=99um=EQaj-vefjEnvDS0bwWa5m=w@mail.gmail.com>

On Tue, Oct 16, 2012 at 12:19 AM, Josh Wu <josh.wu at atmel.com> wrote:
> fixed the following compile error when use avr32 atstk1006_defconfig:
>   drivers/mtd/nand/atmel_nand.c: In function 'pmecc_err_location':
>   drivers/mtd/nand/atmel_nand.c:639: error: implicit declaration of function 'writel_relaxed'
>
> which was introduced by commit 1c7b874d33b463 ("mtd: at91: atmel_nand: add Programmable Multibit ECC controller support").
> The PMECC for nand flash code uses writel_relaxed(). But in avr32, there is no macro "writel_relaxed" defined. This patch add writex_relaxed macro definitions.
>
> Signed-off-by: Josh Wu <josh.wu at atmel.com>

Acked-by: Havard Skinnemoen <havard at skinnemoen.net>

I think it's OK to just forward to write[bwl] -- the relaxed variants
merely provide fewer ordering guarantees than the non-relaxed
variants. The worst that could happen is a small performance hit (and
on AVR32, even that is highly unlikely).

Havard


From tony at atomide.com  Tue Oct 16 14:06:01 2012
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 16 Oct 2012 11:06:01 -0700
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <20121010163840.GA13585@parrot.com>
References: <cover.1349672877.git.afzal@ti.com>
 <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>
 <20121010163840.GA13585@parrot.com>
Message-ID: <20121016180600.GA15569@atomide.com>

* Ivan Djelic <ivan.djelic at parrot.com> [121010 09:40]:
> 
> I ran several mtd regression tests on a Beagle Board on your gpmc-czimage-v2 tag.
> All BCH error correcting tests passed successfully.
> 
> I occasionally had weird read errors though, especially when reading blank pages:
> the omap driver returned 512-byte sectors containing something like:
> 
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff
> 30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ff30ffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> 
> instead of:
> 
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
> 
> I was able to reproduce the problem also on l2-mtd tip, albeit less often.
> The problem seems to occur quite randomly, it may be a hardware issue on
> my board...

Things like this typically happen in the GPMC timings are not correct.
Maybe add #define DEBUG to top of gpmc.c and compare the timings
before and after Afzal's patches? 

> Anyway, the ECC handling part looks OK to me.

Regards,

Tony


From margaret-richmnd at inbox.com  Tue Oct 16 16:08:07 2012
From: margaret-richmnd at inbox.com (First Trust)
Date: Tue, 16 Oct 2012 22:08:07 +0200
Subject: Does your business/project need a loan
Message-ID: <20121016200008.413D04A0AF1@mail.gard1x.com>

RE: PROJECT FUNDING.

Does your business/project need a FAST EASY injection of capital at reasonable rates? Do it right the first time with our financing solutions specialists.

At First Trust Capital Group Plc brokerage firm, we have access to a combined International pool of nearly Half a Trillion in available Liquidity and if you have the right project, we have the right funding. We obtain financial commitments for loans, project funding, proof of funds, bank guarantees, letters of credit, standby letters of credit, collateral enhancements, credit enhancements, and funds for charities and non-profit organisations from domestic and international lending institutions which we would have approved for individuals, businesses, governments, corporations, and organisations.

These days everybody seems to have a project in need of funding but very few actually possess great intentions and innovative ideas. We only accept projects that we feel confident we can get funded and applications are obtained, reviewed and chosen selectively through this Invitation Only Proposal.

We invite you to take this opportunity of an unbeatable fast easy program and if we accept your project, it will be because we think it has merit and stands a good chance of funding. You will need to ensure you have all the necessary documentation (Business Plan, Executive Summary and what have you) to support your application. Once your application and supporting material is submitted, you will be contacted for any clarifications or questions that will assist us in providing you the best financing the market has to offer.

It is our primary objective to work with you and for you in a spirit of cooperation and direct communication to make this painless and a ?no surprises? and ?no delays? experience!

You are advised to act now and submit your application for Commitment today however choosing not to act is a choice in itself but can cost you and your project dearly. Remember fortune smiles on those who act at the right place, right time and right now. We value quality over quantity and time is always of the essence.

For more information about this opportunity of funding, please call during office hours or send a fax or email.
We will be happy to serve you.

Thank you.
Sincerely,
Margaret Richmond (Ms),
First Trust Capital Group Plc,
40, Bank Street, Poplar, London,
E14 5DS, United Kingdom.

Please consider the environment before printing this email.
******************* DISCLAIMER *******************
P.S. This is strictly on the guidelines of CAN-SPAM act of 2003. We have clearly mentioned the source mail-id of this mail,also clearly mentioned the subject lines and they are in no way misleading in any form. We have found your mail address through our own efforts on the web search and not through any un-authentic way. If you find this mail unsolicited, please reply with "Remove" in the subject line and we will take care that you do not receive any further mail from us.
This message contains confidential information and is intended only for the recipient. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately if you have received this e-mail by mistake and delete this e-mail from your system.


From vincenzo.aliberti at gmail.com  Tue Oct 16 17:24:44 2012
From: vincenzo.aliberti at gmail.com (Vincenzo Aliberti)
Date: Tue, 16 Oct 2012 23:24:44 +0200
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <1349954577.12014.13.camel@sauron.fi.intel.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
 <1349954577.12014.13.camel@sauron.fi.intel.com>
Message-ID: <507DD09C.6050600@gmail.com>

On 10/11/2012 01:20 PM, Artem Bityutskiy wrote:> On Thu, 2012-10-04 at 23:17 +0200, Vincenzo Aliberti wrote:
>> +menu "LPDDR2_NVM memory drivers"
>> +	depends on MTD!=n
> 
> Just 'depends on MTD'
> 

Done


>> +# linux/drivers/mtd/lpddr2_nvm/Makefile
> 
> Why did you decide to create a separate directory for this one?
> I think you should just put it to 'drivers/mtd/lpddr' instead.
> 

Now both drivers are in the same folder as per your suggestion


On 10/11/2012 01:22 PM, Artem Bityutskiy wrote:
> On Thu, 2012-10-04 at 23:17 +0200, Vincenzo Aliberti wrote:
>> Dear All,
>>     continuing Micron support activity on PCM memories you can find here-below a 
>> patch containing MTD driver for LPDDR2-NVM memories as demoed during Q2 Linaro 
>> Connect in Hong Kong.
>>
>> Let me thank TI Panda open source team for support on platform enablement 
>> activity and Arnd for his first feedback on driver implementation
> 
> include/mtd/mtd-abi.h file does not longer exist, please re-base your
> driver. Could you please also feed it to the checkpatch.pl tool and fix
> style issues?
> 

The only Warning is
WARNING: line over 80 characters
#605: FILE: include/uapi/mtd/mtd-abi.h:112:
+#define MTD_CAP_PCM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)

But in the file include/uapi/mtd/mtd-abi.h there is already the raw:
#define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)


>> +		pr_alert(
>> +		"lpddr2_nvm_probe: Failed to allocate memory for map\n");
> 
> Just join this into 1 line. It is OK to have lines longer than 80
> sybmols if you print a string.
> 
> Do this for all other similar places please.
> 

Done


Considering the number of changes you can find here-below the whole patch: I have 
successfully compiled it with 3.7-rc1


Regards.
	Vincenzo Aliberti

Signed-off-by: Vincenzo Aliberti <vincenzo.aliberti at gmail.com>
---
 drivers/mtd/lpddr/Kconfig      |   12 +-
 drivers/mtd/lpddr/Makefile     |    1 +
 drivers/mtd/lpddr/lpddr2_nvm.c |  542 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/mtd/mtd-abi.h     |    1 +
 4 files changed, 554 insertions(+), 2 deletions(-)
 create mode 100644 drivers/mtd/lpddr/lpddr2_nvm.c

diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig
index 265f969..468f06d 100644
--- a/drivers/mtd/lpddr/Kconfig
+++ b/drivers/mtd/lpddr/Kconfig
@@ -1,5 +1,5 @@
-menu "LPDDR flash memory drivers"
-	depends on MTD!=n
+menu "LPDDR & LPDDR2 PCM memory drivers"
+	depends on MTD
 
 config MTD_LPDDR
 	tristate "Support for LPDDR flash chips"
@@ -17,4 +17,12 @@ config MTD_QINFO_PROBE
 	    Window QINFO interface, permits software to be used for entire
 	    families of devices. This serves similar purpose of CFI on legacy
 	    Flash products
+
+config MTD_LPDDR2_NVM
+	depends on MTD
+	tristate "Support for LPDDR2-NVM flash chips"
+	help
+	  This option enables support of PCM memories with a LPDDR2-NVM
+	  (Low power double data rate 2) interface.
+
 endmenu
diff --git a/drivers/mtd/lpddr/Makefile b/drivers/mtd/lpddr/Makefile
index da48e46..881d440 100644
--- a/drivers/mtd/lpddr/Makefile
+++ b/drivers/mtd/lpddr/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_MTD_QINFO_PROBE)	+= qinfo_probe.o
 obj-$(CONFIG_MTD_LPDDR)	+= lpddr_cmds.o
+obj-$(CONFIG_MTD_LPDDR2_NVM) += lpddr2_nvm.o
diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c
new file mode 100644
index 0000000..8e74287
--- /dev/null
+++ b/drivers/mtd/lpddr/lpddr2_nvm.c
@@ -0,0 +1,542 @@
+/*
+ * LPDDR2-NVM MTD driver. This module provides read, write, erase, lock/unlock
+ * support for LPDDR2-NVM PCM memories
+ *
+ * Copyright ? 2012 Micron Technology, Inc.
+ *
+ * Vincenzo Aliberti <vincenzo.aliberti at gmail.com>
+ * Domenico Manna <domenico.manna at gmail.com>
+ * Many thanks to Andrea Vigilante for initial enabling
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+
+/* Parameters */
+#define ERASE_BLOCKSIZE			(0x00020000/2)	/* in Word */
+#define WRITE_BUFFSIZE			(0x00000400/2)	/* in Word */
+#define OW_BASE_ADDRESS			0x00000000	/* OW offset */
+
+/* PFOW symbols address offset */
+#define PFOW_QUERY_STRING_P		(0x0000/2)	/* in Word */
+#define PFOW_QUERY_STRING_F		(0x0002/2)	/* in Word */
+#define PFOW_QUERY_STRING_O		(0x0004/2)	/* in Word */
+#define PFOW_QUERY_STRING_W		(0x0006/2)	/* in Word */
+
+/* OW registers address */
+#define CMD_CODE_OFS			(0x0080/2)	/* in Word */
+#define CMD_DATA_OFS			(0x0084/2)	/* in Word */
+#define CMD_ADD_L_OFS			(0x0088/2)	/* in Word */
+#define CMD_ADD_H_OFS			(0x008A/2)	/* in Word */
+#define MPR_L_OFS			(0x0090/2)	/* in Word */
+#define MPR_H_OFS			(0x0092/2)	/* in Word */
+#define CMD_EXEC_OFS			(0x00C0/2)	/* in Word */
+#define STATUS_REG_OFS			(0x00CC/2)	/* in Word */
+#define PRG_BUFFER_OFS			(0x0010/2)	/* in Word */
+
+/* Datamask */
+#define MR_CFGMASK			0x8000
+#define SR_OK_DATAMASK			0x0080
+
+/* LPDDR2-NVM Commands */
+#define LPDDR2_NVM_LOCK			0x0061
+#define LPDDR2_NVM_UNLOCK		0x0062
+#define LPDDR2_NVM_SW_PROGRAM		0x0041
+#define LPDDR2_NVM_SW_OVERWRITE		0x0042
+#define LPDDR2_NVM_BUF_PROGRAM		0x00E9
+#define LPDDR2_NVM_BUF_OVERWRITE	0x00EA
+#define LPDDR2_NVM_ERASE		0x0020
+
+/*
+ * Internal Type Definitions
+ * pcm_int_data contains memory controller details:
+ * @reg_data : LPDDR2_MODE_REG_DATA register address after remapping
+ * @reg_cfg  : LPDDR2_MODE_REG_CFG register address after remapping
+ * &bus_width: memory bus-width (eg: x16 2 Bytes, x32 4 Bytes)
+ */
+struct pcm_int_data {
+	void __iomem *reg_data;
+	void __iomem *reg_cfg;
+	int bus_width;
+};
+
+static DEFINE_MUTEX(lpdd2_nvm_mutex);
+
+static inline map_word build_map_word(u_long myword)
+{
+	map_word val = { {0} };
+	val.x[0] = myword;
+	return val;
+}
+
+static inline u_int build_mr_cfgmaks(u_int bus_width)
+{
+	u_int val = MR_CFGMASK;
+
+	if (bus_width == 0x0004)		/* x32 device */
+		val = val<<16;
+
+	return val;
+}
+
+static inline u_int build_sr_ok_datamask(u_int bus_width)
+{
+	u_int val = SR_OK_DATAMASK;
+
+	if (bus_width == 0x0004)		/* x32 device */
+		val = (val<<16)+val;
+
+	return val;
+}
+
+/*
+ * Enable lpddr2-nvm Overlay Window
+ */
+static inline void ow_enable(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+
+	writel_relaxed(build_mr_cfgmaks(pcm_data->bus_width) | 0x18,
+		pcm_data->reg_cfg);
+	writel_relaxed(0x01, pcm_data->reg_data);
+}
+
+/*
+ * Disable lpddr2-nvm Overlay Window
+ */
+static inline void ow_disable(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+
+	writel_relaxed(build_mr_cfgmaks(pcm_data->bus_width) | 0x18,
+		pcm_data->reg_cfg);
+	writel_relaxed(0x02, pcm_data->reg_data);
+}
+
+/*
+ * Execute lpddr2-nvm operations
+ */
+static int lpddr2_nvm_do_op(struct map_info *map, u_long cmd_code,
+	u_long cmd_data, u_long cmd_add, u_long cmd_mpr, u_char *buf)
+{
+	map_word add_l = { {0} }, add_h = { {0} }, mpr_l = { {0} },
+		mpr_h = { {0} }, data_l = { {0} }, cmd = { {0} },
+		exec_cmd = { {0} }, sr;
+	map_word data_h = { {0} };	/* only for 2x x16 devices stacked */
+	u_long i, status_reg, prg_buff_ofs;
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	u_int sr_ok_datamask = build_sr_ok_datamask(pcm_data->bus_width);
+
+	/* Builds low and high words for OW Control Registers */
+	add_l.x[0]	= cmd_add&0x0000FFFF;
+	add_h.x[0]	= (cmd_add>>16)&0x0000FFFF;
+	mpr_l.x[0]	= cmd_mpr&0x0000FFFF;
+	mpr_h.x[0]	= (cmd_mpr>>16)&0x0000FFFF;
+	cmd.x[0]	= cmd_code&0x0000FFFF;
+	exec_cmd.x[0]	= 0x0001;
+	data_l.x[0]	= cmd_data&0x0000FFFF;
+	data_h.x[0]	= (cmd_data>>16)&0x0000FFFF; /* only for 2x x16 */
+
+	/* Set Overlay Window Control Registers */
+	map_write(map, cmd, map->pfow_base+CMD_CODE_OFS*pcm_data->bus_width);
+	map_write(map, data_l, map->pfow_base+CMD_DATA_OFS*pcm_data->bus_width);
+	map_write(map, add_l, map->pfow_base+CMD_ADD_L_OFS*pcm_data->bus_width);
+	map_write(map, add_h, map->pfow_base+CMD_ADD_H_OFS*pcm_data->bus_width);
+	map_write(map, mpr_l, map->pfow_base+MPR_L_OFS*pcm_data->bus_width);
+	map_write(map, mpr_h, map->pfow_base+MPR_H_OFS*pcm_data->bus_width);
+	if (pcm_data->bus_width == 0x0004) {	/* 2x16 devices stacked */
+		map_write(map, cmd, map->pfow_base +
+			CMD_CODE_OFS*pcm_data->bus_width + 2);
+		map_write(map, data_h, map->pfow_base +
+			CMD_DATA_OFS*pcm_data->bus_width + 2);
+		map_write(map, add_l, map->pfow_base +
+			CMD_ADD_L_OFS*pcm_data->bus_width + 2);
+		map_write(map, add_h, map->pfow_base +
+			CMD_ADD_H_OFS*pcm_data->bus_width + 2);
+		map_write(map, mpr_l, map->pfow_base +
+			MPR_L_OFS*pcm_data->bus_width + 2);
+		map_write(map, mpr_h, map->pfow_base +
+			MPR_H_OFS*pcm_data->bus_width + 2);
+	}
+
+	/* Fill Program Buffer */
+	if ((cmd_code == LPDDR2_NVM_BUF_PROGRAM) ||
+		(cmd_code == LPDDR2_NVM_BUF_OVERWRITE)) {
+		prg_buff_ofs = (map_read(map, map->pfow_base +
+			PRG_BUFFER_OFS*pcm_data->bus_width)).x[0];
+		for (i = 0; i < cmd_mpr; i++) {
+			map_write(map, build_map_word(buf[i]), map->pfow_base +
+			prg_buff_ofs + i);
+		}
+	}
+
+	/* Command Execute */
+	map_write(map, exec_cmd, map->pfow_base+CMD_EXEC_OFS*
+		pcm_data->bus_width);
+	if (pcm_data->bus_width == 0x0004)	/* 2x16 devices stacked */
+		map_write(map, exec_cmd, map->pfow_base +
+			CMD_EXEC_OFS*pcm_data->bus_width + 2);
+
+	/* Status Register Check */
+	do {
+		sr = map_read(map, map->pfow_base +
+			STATUS_REG_OFS*pcm_data->bus_width);
+		status_reg = sr.x[0];
+		if (pcm_data->bus_width == 0x0004) {/* 2x16 devices stacked */
+			sr = map_read(map, map->pfow_base +
+				STATUS_REG_OFS*pcm_data->bus_width + 2);
+			status_reg += sr.x[0]<<16;
+		}
+	} while ((status_reg&sr_ok_datamask) != sr_ok_datamask);
+
+	return (((status_reg&sr_ok_datamask) == sr_ok_datamask) ? 0 : -EIO);
+}
+
+/*
+ * Execute lpddr2-nvm operations @ block level
+ */
+static int lpddr2_nvm_do_block_op(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len, u_char block_op)
+{
+	struct map_info *map = mtd->priv;
+	u_long add, end_add;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	add = start_add;
+	end_add = add + len;
+
+	if ((add > mtd->size) || (end_add > mtd->size)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	do {
+		ret = lpddr2_nvm_do_op(map, block_op, 0x00, add, add, NULL);
+		if (ret)
+			goto out;
+		add += mtd->erasesize;
+	} while (add < end_add);
+
+out:
+	ow_disable(map);
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * verify presence of PFOW string
+ */
+static int lpddr2_nvm_pfow_present(struct map_info *map)
+{
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	map_word pfow_val[4];
+	unsigned int found = 1;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	/* Load string from array */
+	pfow_val[0] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_P *
+			pcm_data->bus_width);
+	pfow_val[1] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_F *
+			pcm_data->bus_width);
+	pfow_val[2] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_O *
+			pcm_data->bus_width);
+	pfow_val[3] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_W *
+			pcm_data->bus_width);
+
+	/* Verify the string loaded vs expected */
+	if (!map_word_equal(map, build_map_word('P'), pfow_val[0]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('F'), pfow_val[1]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('O'), pfow_val[2]))
+		found = 0;
+	if (!map_word_equal(map, build_map_word('W'), pfow_val[3]))
+		found = 0;
+
+	ow_disable(map);
+
+	mutex_unlock(&lpdd2_nvm_mutex);
+
+	return found;
+}
+
+/*
+ * lpddr2_nvm driver read method
+ */
+static int lpddr2_nvm_read(struct mtd_info *mtd, loff_t start_add,
+				size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	*retlen = len;
+
+	if ((start_add + len) > mtd->size) {
+		pr_alert("lpddr2_nvm: read out of memory range\n");
+		*retlen = 0;
+		ret = -EINVAL;
+		goto out;
+	}
+
+	map_copy_from(map, buf, start_add, *retlen);
+
+out:
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver write method
+ */
+static int lpddr2_nvm_write(struct mtd_info *mtd, loff_t start_add,
+				size_t len, size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct pcm_int_data *pcm_data = map->fldrv_priv;
+	u_long add, current_len, tot_len, target_len, my_data;
+	u_char *write_buf = (u_char *)buf;
+	int ret = 0;
+
+	mutex_lock(&lpdd2_nvm_mutex);
+
+	ow_enable(map);
+
+	/* Set start value for the variables */
+	add = start_add;
+	target_len = len;
+	tot_len = 0;
+
+	if ((start_add + len) > mtd->size) {
+		pr_alert("lpddr2_nvm: write out of memory range\n");
+		*retlen = 0;
+		ret = -EINVAL;
+		goto out;
+	}
+
+	while (tot_len < target_len) {
+		if (!(IS_ALIGNED(add, mtd->writesize))) { /* do sw program */
+			my_data = write_buf[tot_len];
+			my_data += (write_buf[tot_len+1])<<8;
+			if (pcm_data->bus_width == 0x0004) {/* 2x16 devices */
+				my_data += (write_buf[tot_len+2])<<16;
+				my_data += (write_buf[tot_len+3])<<24;
+			}
+			ret = lpddr2_nvm_do_op(map, LPDDR2_NVM_SW_OVERWRITE,
+				my_data, add, 0x00, NULL);
+			if (ret)
+				goto out;
+
+			add += pcm_data->bus_width;
+			tot_len += pcm_data->bus_width;
+		} else {		/* do buffer program */
+			current_len = min(target_len - tot_len,
+				(u_long) mtd->writesize);
+			ret = lpddr2_nvm_do_op(map, LPDDR2_NVM_BUF_OVERWRITE,
+				0x00, add, current_len, write_buf + tot_len);
+			if (ret)
+				goto out;
+
+			add += current_len;
+			tot_len += current_len;
+		}
+	}
+
+out:
+	*retlen = tot_len;
+	ow_disable(map);
+	mutex_unlock(&lpdd2_nvm_mutex);
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver erase method
+ */
+static int lpddr2_nvm_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	int ret = lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
+		LPDDR2_NVM_ERASE);
+	if (!ret) {
+		instr->state = MTD_ERASE_DONE;
+		mtd_erase_callback(instr);
+	}
+
+	return ret;
+}
+
+/*
+ * lpddr2_nvm driver unlock method
+ */
+static int lpddr2_nvm_unlock(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len)
+{
+	return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_UNLOCK);
+}
+
+/*
+ * lpddr2_nvm driver lock method
+ */
+static int lpddr2_nvm_lock(struct mtd_info *mtd, loff_t start_add,
+	uint64_t len)
+{
+	return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_LOCK);
+}
+
+/*
+ * lpddr2_nvm driver probe method
+ */
+static int lpddr2_nvm_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct map_info *lpddr2_nvm_map;
+	struct mtd_info *lpddr2_nvm_mtd;
+	struct resource *address_range = platform_get_resource(pdev,
+						IORESOURCE_MEM, 0);
+	struct resource *control_regs = platform_get_resource(pdev,
+						IORESOURCE_MEM, 1);
+	struct resource *buswidth = platform_get_resource(pdev,
+						IORESOURCE_BUS, 0);
+	struct pcm_int_data *pcm_data;
+
+	/* Allocate memory control_regs data structures */
+	pcm_data = kzalloc(sizeof(*pcm_data), GFP_KERNEL);
+	if (!control_regs) {
+		pr_alert("lpddr2_nvm_probe: Failed to allocate memory for int_data\n");
+		ret = 1;
+		goto out;
+	}
+	pcm_data->reg_data =	(void *) control_regs->start;
+	pcm_data->reg_cfg =	(void *) control_regs->end;
+	pcm_data->bus_width =	(int) buswidth->start;
+
+	/* Allocate memory for map_info & mtd_info data structures */
+	lpddr2_nvm_map = kzalloc(sizeof(*lpddr2_nvm_map), GFP_KERNEL);
+	if (!lpddr2_nvm_map) {
+		pr_alert("lpddr2_nvm_probe: Failed to allocate memory for map\n");
+		ret = 1;
+		goto out;
+	}
+
+	lpddr2_nvm_mtd = kzalloc(sizeof(*lpddr2_nvm_mtd), GFP_KERNEL);
+	if (!lpddr2_nvm_mtd) {
+		pr_alert("lpddr2_nvm_probe: Failed to allocate memory for mtd\n");
+		ret = 1;
+		goto out;
+	}
+
+	/* Reserve lpddr2_nvm address range */
+	if (request_mem_region(address_range->start, (address_range->end -
+		address_range->start + 1), "lpddr2_nvm") == NULL) {
+		pr_alert("lpddr2_nvm_probe: Unable to reserve memory address %#010x\n",
+		address_range->start);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* Populate map_info data structure */
+	*lpddr2_nvm_map = (struct map_info) {
+		.virt		= ioremap_nocache(address_range->start,
+				(address_range->end-address_range->start+1)),
+		.name		= pdev->dev.init_name,
+		.phys		= address_range->start,
+		.size		= address_range->end - address_range->start + 1,
+		.bankwidth	= pcm_data->bus_width/2,
+		.pfow_base	= OW_BASE_ADDRESS,
+		.fldrv_priv	= pcm_data,
+	};
+
+	simple_map_init(lpddr2_nvm_map);	/* fill with default methods */
+
+	/* Populate mtd_info data structure */
+	*lpddr2_nvm_mtd = (struct mtd_info) {
+		.name		= pdev->dev.init_name,
+		.type		= MTD_RAM,
+		.priv		= lpddr2_nvm_map,
+		.size		= address_range->end - address_range->start + 1,
+		.erasesize	= ERASE_BLOCKSIZE * pcm_data->bus_width,
+		.writesize	= 1,
+		.writebufsize	= WRITE_BUFFSIZE * pcm_data->bus_width,
+		.flags		= (MTD_CAP_PCM | MTD_POWERUP_LOCK),
+		._read		= lpddr2_nvm_read,
+		._read_oob	= NULL,
+		._write		= lpddr2_nvm_write,
+		._write_oob	= NULL,
+		._erase		= lpddr2_nvm_erase,
+		._unlock	= lpddr2_nvm_unlock,
+		._lock		= lpddr2_nvm_lock,
+		._sync		= NULL,
+		._suspend	= NULL,
+		._resume	= NULL,
+		._block_isbad	= NULL,
+		._block_markbad	= NULL,
+	};
+
+	/* Verify the presence of the device looking for PFOW string */
+	if (lpddr2_nvm_pfow_present(lpddr2_nvm_map)) {
+		pr_alert("lpddr2_nvm_probe: device recognized\n");
+		/* Register the mtd_partition structure */
+		if (mtd_add_partition(lpddr2_nvm_mtd, "my_pcm", 0x10000000,
+			0x00)){
+			pr_alert("lpddr2_nvm_probe: Failed to add mtd partition\n");
+			ret = 1;
+			goto out;
+		}
+		ret = 0;
+	} else {
+		pr_alert("%s: PFOW string not found at address %#010lx\n",
+			lpddr2_nvm_map->name, lpddr2_nvm_map->pfow_base);
+		ret = 1;
+	}
+
+out:
+	return ret;
+}
+
+/* Initialize platform_driver data structure for lpddr2_nvm */
+static struct platform_driver lpddr2_nvm_drv = {
+	.driver		= {
+		.name	= "lpddr2_nvm",
+	},
+	.probe		= lpddr2_nvm_probe,
+	.remove		= NULL,
+	.suspend	= NULL,
+	.resume		= NULL,
+};
+
+module_platform_driver(lpddr2_nvm_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vincenzo Aliberti <vincenzo.aliberti at gmail.com>");
+MODULE_DESCRIPTION("MTD driver for LPDDR2-NVM PCM memories");
+
diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index 36eace0..33f3036 100644
--- a/include/uapi/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
@@ -109,6 +109,7 @@ struct mtd_write_req {
 #define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 #define MTD_CAP_NORFLASH	(MTD_WRITEABLE | MTD_BIT_WRITEABLE)
 #define MTD_CAP_NANDFLASH	(MTD_WRITEABLE)
+#define MTD_CAP_PCM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 
 /* Obsolete ECC byte placement modes (used with obsolete MEMGETOOBSEL) */
 #define MTD_NANDECC_OFF		0	// Switch off ECC (Not recommended)
-- 
1.7.9.5




From x0148406 at ti.com  Wed Oct 17 01:29:47 2012
From: x0148406 at ti.com (Afzal Mohammed)
Date: Wed, 17 Oct 2012 10:59:47 +0530
Subject: [PATCH v2 00/14] OMAP-GPMC related cleanup for common zImage
In-Reply-To: <20121016180600.GA15569@atomide.com>
References: <cover.1349672877.git.afzal@ti.com>
 <C8443D0743D26F4388EA172BF4E2A7A93E9F7B0A@DBDE01.ent.ti.com>
 <20121010163840.GA13585@parrot.com> <20121016180600.GA15569@atomide.com>
Message-ID: <507E424B.8040706@ti.com>

Hi Ivan,

On Tuesday 16 October 2012 11:36 PM, Tony Lindgren wrote:
> * Ivan Djelic<ivan.djelic at parrot.com>  [121010 09:40]:

>> I ran several mtd regression tests on a Beagle Board on your gpmc-czimage-v2 tag.
>> All BCH error correcting tests passed successfully.

>> I occasionally had weird read errors though, especially when reading blank pages:
>> the omap driver returned 512-byte sectors containing something like:

>> I was able to reproduce the problem also on l2-mtd tip, albeit less often.
>> The problem seems to occur quite randomly, it may be a hardware issue on
>> my board...

> Things like this typically happen in the GPMC timings are not correct.
> Maybe add #define DEBUG to top of gpmc.c and compare the timings
> before and after Afzal's patches?

Latest series for gpmc related cleanup for common zImage removed
dependency on minor timing cleanups (this series was dependent on
on another series that did minor timing cleanups).

A pull request for the new series on gpmc cleanup for common zImage
that does not contain timing related changes and without dependency
on timing related changes has been sent to Tony (forwarded to you now).
He has pulled those changes onto l-o in
"omap-for-v3.8/cleanup-headers-gpmc"

As there are no changes w.r.t timing's in the new series, behaviour
should be same as without.

>> Anyway, the ECC handling part looks OK to me.

Regards
Afzal


From shc_work at mail.ru  Wed Oct 17 02:08:27 2012
From: shc_work at mail.ru (Alexander Shiyan)
Date: Wed, 17 Oct 2012 10:08:27 +0400
Subject: [PATCH] mtd: gpio-nand: Ability to use driver for configurations
 without RDY-pin
Message-ID: <1350454107-3754-1-git-send-email-shc_work@mail.ru>

In some configurations of "gpio-nand" RDY-pin may be not connected.
This patch allow to use driver for these configurations. In this case
we are assume that device always ready.

Signed-off-by: Alexander Shiyan <shc_work at mail.ru>
---
 drivers/mtd/nand/gpio.c |   22 +++++++++++++++-------
 1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c
index bc73bc5..b1653bf 100644
--- a/drivers/mtd/nand/gpio.c
+++ b/drivers/mtd/nand/gpio.c
@@ -134,7 +134,11 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
 static int gpio_nand_devready(struct mtd_info *mtd)
 {
 	struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
-	return gpio_get_value(gpiomtd->plat.gpio_rdy);
+
+	if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+		return gpio_get_value(gpiomtd->plat.gpio_rdy);
+
+	return 1;
 }
 
 #ifdef CONFIG_OF
@@ -252,7 +256,8 @@ static int __devexit gpio_nand_remove(struct platform_device *dev)
 	gpio_free(gpiomtd->plat.gpio_nce);
 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 		gpio_free(gpiomtd->plat.gpio_nwp);
-	gpio_free(gpiomtd->plat.gpio_rdy);
+	if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+		gpio_free(gpiomtd->plat.gpio_rdy);
 
 	kfree(gpiomtd);
 
@@ -336,10 +341,12 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
 	if (ret)
 		goto err_cle;
 	gpio_direction_output(gpiomtd->plat.gpio_cle, 0);
-	ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
-	if (ret)
-		goto err_rdy;
-	gpio_direction_input(gpiomtd->plat.gpio_rdy);
+	if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) {
+		ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
+		if (ret)
+			goto err_rdy;
+		gpio_direction_input(gpiomtd->plat.gpio_rdy);
+	}
 
 
 	this->IO_ADDR_W  = this->IO_ADDR_R;
@@ -386,7 +393,8 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
 err_wp:
 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
 		gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
-	gpio_free(gpiomtd->plat.gpio_rdy);
+	if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
+		gpio_free(gpiomtd->plat.gpio_rdy);
 err_rdy:
 	gpio_free(gpiomtd->plat.gpio_cle);
 err_cle:
-- 
1.7.3.4



From dedekind1 at gmail.com  Wed Oct 17 07:23:50 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 14:23:50 +0300
Subject: [PATCH v2 0/2] Add DMA and device tree support to the flash
 controller FLCTL
In-Reply-To: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
Message-ID: <1350473030.5769.137.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 11:58 +0200, Bastian Hecht wrote:
> changelog v2: 	- cosmetic fixes in patch 1
> 		- added dmas and dma-names field in patch 2

Hi, I used to be able to compile MTD stuff for mackerel board with the
defconfig attached, but now it fails with 3.7-rc1 with as error:

/tmp/cc2Nr7AN.s: Error: bad immediate value for 8-bit offset (1024)

It fails for dogc4.c, but if I disable DOCG4, it fails for other drivers
with a similar error.

I've tried (arm) gcc 4.6.3 and the latest Linaro 4.7 build.

Any idea? I did not dig this, is this a known issue? Could you try to
reproduce this in your setup?


CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_PID_NS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_SH7372=y
CONFIG_MACH_MACKEREL=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
CONFIG_FORCE_MAX_ZONEORDER=15
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
CONFIG_KEXEC=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM_RUNTIME=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_AFS_PARTS=m
CONFIG_MTD_AR7_PARTS=m
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_SM_FTL=m
CONFIG_MTD_OOPS=y
CONFIG_MTD_SWAP=m
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_ROM=y
CONFIG_MTD_ABSENT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_IMPA7=m
CONFIG_MTD_GPIO_ADDR=y
CONFIG_MTD_PLATRAM=y
CONFIG_MTD_LATCH_ADDR=m
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_M25P80=y
# CONFIG_M25PXX_USE_FAST_READ is not set
CONFIG_MTD_SST25L=y
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=m
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_DOC2000=m
CONFIG_MTD_DOC2001=m
CONFIG_MTD_DOC2001PLUS=y
CONFIG_MTD_DOCG3=m
CONFIG_MTD_DOCPROBE_ADVANCED=y
CONFIG_MTD_NAND_ECC_SMC=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_DENALI=m
CONFIG_MTD_NAND_DENALI_DT=m
CONFIG_MTD_NAND_GPIO=m
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_NAND_DOCG4=m
CONFIG_MTD_NAND_NANDSIM=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_NAND_SH_FLCTL=y
CONFIG_MTD_ONENAND=y
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=m
CONFIG_MTD_ONENAND_SIM=y
CONFIG_MTD_LPDDR=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_FASTMAP=y
# CONFIG_BLK_DEV is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_SPI=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
# CONFIG_JFFS2_ZLIB is not set
CONFIG_JFFS2_LZO=y
# CONFIG_JFFS2_RTIME is not set
CONFIG_JFFS2_RUBIN=y
CONFIG_UBIFS_FS=m
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_ARM_UNWIND is not set
CONFIG_KEYS=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ANSI_CPRNG=y
# CONFIG_CRYPTO_HW is not set

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_PID_NS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_SH7372=y
CONFIG_MACH_MACKEREL=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
CONFIG_FORCE_MAX_ZONEORDER=15
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
CONFIG_KEXEC=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM_RUNTIME=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_AFS_PARTS=m
CONFIG_MTD_AR7_PARTS=m
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_SM_FTL=m
CONFIG_MTD_OOPS=y
CONFIG_MTD_SWAP=m
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_ROM=y
CONFIG_MTD_ABSENT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_IMPA7=m
CONFIG_MTD_GPIO_ADDR=y
CONFIG_MTD_PLATRAM=y
CONFIG_MTD_LATCH_ADDR=m
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_M25P80=y
# CONFIG_M25PXX_USE_FAST_READ is not set
CONFIG_MTD_SST25L=y
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=m
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_DOC2000=m
CONFIG_MTD_DOC2001=m
CONFIG_MTD_DOC2001PLUS=y
CONFIG_MTD_DOCG3=m
CONFIG_MTD_DOCPROBE_ADVANCED=y
CONFIG_MTD_NAND_ECC_SMC=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_DENALI=m
CONFIG_MTD_NAND_DENALI_DT=m
CONFIG_MTD_NAND_GPIO=m
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_NAND_DOCG4=m
CONFIG_MTD_NAND_NANDSIM=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_NAND_SH_FLCTL=y
CONFIG_MTD_ONENAND=y
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=m
CONFIG_MTD_ONENAND_SIM=y
CONFIG_MTD_LPDDR=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_FASTMAP=y
# CONFIG_BLK_DEV is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_SPI=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
# CONFIG_JFFS2_ZLIB is not set
CONFIG_JFFS2_LZO=y
# CONFIG_JFFS2_RTIME is not set
CONFIG_JFFS2_RUBIN=y
CONFIG_UBIFS_FS=m
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_ARM_UNWIND is not set
CONFIG_KEYS=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ANSI_CPRNG=y
# CONFIG_CRYPTO_HW is not set
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/2fcc1b34/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:30:25 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:30:25 +0300
Subject: [PATCH 01/11] fsmc/nand:FIX: Change the type for regs to void
 __iomem *
In-Reply-To: <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <c30a9228d4bff7dbedd5d011f84c79c324736452.1349778820.git.vipin.kumar@st.com>
Message-ID: <1350477025.5769.138.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Pushed this one to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/4621e9f2/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:31:49 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:31:49 +0300
Subject: [PATCH 03/11] fsmc/nand: Support multiple banks connected to
 controller
In-Reply-To: <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <9748ce2483f539fb32279b8ea9df065cfdbe8ab1.1349778820.git.vipin.kumar@st.com>
Message-ID: <1350477109.5769.141.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
> Support up to max_banks number of banks in fsmc driver.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

I tried to apply this, but it does not apply cleanly to l2-mtd.git,
which is based on 3.7-rc1.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/8034920f/attachment-0001.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:42:22 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:42:22 +0300
Subject: [PATCH RESEND] jffs2: Fix lock acquisition order bug in
 jffs2_write_begin
In-Reply-To: <507476E7.8030705@freenet.de>
References: <507321E6.1050609@freenet.de> <507476E7.8030705@freenet.de>
Message-ID: <1350477742.5769.144.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 21:11 +0200, Thomas Betker wrote:
> jffs2_write_begin() first acquires the page lock, then f->sem. This causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first acquires f->sem, then the page lock:

This patch does not apply to l2-mtd.git, which is based on 3.7-rc1.

$:~/git/l2-mtd$ git apply --check ~/tmp/thomas.mbox
error: patch failed: fs/jffs2/file.c:138
error: fs/jffs2/file.c: patch does not apply

Could you please wrap commit message lines to 80 characters when you
re-send?

Also, would you please add Cc: stable at vger.kernel.org [vX.Y+], where
vX.Y is the starting version for which this patch is relevant, e.g.,
v3.0.

Thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/36039697/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:47:46 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:47:46 +0300
Subject: [PATCH 06/11] fsmc/nand: Modify the wait to uninterruptible
In-Reply-To: <3dcb002d0ad03dde9a91e8128dbaa320b8a264a9.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <3dcb002d0ad03dde9a91e8128dbaa320b8a264a9.1349778821.git.vipin.kumar@st.com>
Message-ID: <1350478066.5769.149.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
> Interruptible wait caused trouble in fsmc hardware state machine if the
> application was killed abruptly. To make fsmc operation safe turn wait in to
> un-interruptible.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Pushed this one to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/59249ec7/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:47:42 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:47:42 +0300
Subject: [PATCH 11/11] nand: Increase the ecc placement locations to 640
In-Reply-To: <67e0aae3b23f37feb30789f5c6cb342b5684911a.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <67e0aae3b23f37feb30789f5c6cb342b5684911a.1349778821.git.vipin.kumar@st.com>
Message-ID: <1350478062.5769.147.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
> Few devices like H27UBG8T2CTR have a writesize/oobsize of 8KB/640B.
> This means that the maximum oobsize has gone up to 640 bytes and consequently
> the maximum ecc placement locations have also gone up to 640.
> 
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>

Pushed this one to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/508f73cf/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 08:48:36 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 15:48:36 +0300
Subject: [PATCH 00/11] mtd/nand: fsmc driver updates
In-Reply-To: <cover.1349778820.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
Message-ID: <1350478116.5769.150.camel@sauron.fi.intel.com>

On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
> This patch-set contains several fixes and a few enhancements in fsmc driver.
> Modifications include

OK, picked some patches from your series, some do not apply. Please,
send v2 against the l2-mtd.git tree:

git://git.infradead.org/users/dedekind/l2-mtd.git

Thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/d73a2a7b/attachment.sig>

From hechtb at googlemail.com  Wed Oct 17 09:05:09 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Wed, 17 Oct 2012 15:05:09 +0200
Subject: [PATCH v2 0/2] Add DMA and device tree support to the flash
 controller FLCTL
In-Reply-To: <1350473030.5769.137.camel@sauron.fi.intel.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
 <1350473030.5769.137.camel@sauron.fi.intel.com>
Message-ID: <CABYn4szACuH3LQ193VJj6E=J4q4Ye4E4O6cUgjB8jmQK6RRmpA@mail.gmail.com>

Hi Artem,

> Hi, I used to be able to compile MTD stuff for mackerel board with the
> defconfig attached, but now it fails with 3.7-rc1 with as error:
>
> /tmp/cc2Nr7AN.s: Error: bad immediate value for 8-bit offset (1024)
>
> It fails for dogc4.c, but if I disable DOCG4, it fails for other drivers
> with a similar error.
>
> I've tried (arm) gcc 4.6.3 and the latest Linaro 4.7 build.
>
> Any idea? I did not dig this, is this a known issue? Could you try to
> reproduce this in your setup?
>

I can reproduce the error with the following output:
/tmp/ccYAbker.s: Assembler messages:
/tmp/ccYAbker.s: Error: bad immediate value for 8-bit offset (2048)
make[3]: *** [drivers/mtd/nand/docg4.o] Error 1

The compiler version is: gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
I usually use: gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202) and
can compile things without problems.

I found some old bug reports (from 2005) on the same issue with arm gcc.

Do we want to send a bug report? I've read in the gnu gcc docs about
reporting and they want the minimal set of data to reproduce this bug.
Hmmmm....

The command line used (with --save-temps added as they want it) is:
arm-linux-gnueabi-gcc -Wp,-MD,drivers/mtd/nand/.docg4.o.d  -nostdinc
-isystem /usr/lib/gcc/arm-linux-gnueabi/4.6/include
-I$KERNEL_DIR/arch/arm/include -Iarch/arm/include/generated  -Iinclude
-I$KERNEL_DIR/arch/arm/include/uapi -Iarch/arm/include/generated/uapi
-I$KERNEL_DIR/include/uapi -Iinclude/generated/uapi -include
$KERNEL_DIR/include/linux/kconfig.h -D__KERNEL__ -mlittle-endian
-Iarch/arm/mach-shmobile/include -Wall -Wundef -Wstrict-prototypes
-Wno-trigraphs -fno-strict-aliasing -fno-common
-Werror-implicit-function-declaration -Wno-format-security
-fno-delete-null-pointer-checks -O2 -marm -fno-dwarf2-cfi-asm
-fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=aapcs-linux
-mno-thumb-interwork -D__LINUX_ARM_ARCH__=7 -march=armv7-a
-msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector
-Wno-unused-but-set-variable -fno-omit-frame-pointer
-fno-optimize-sibling-calls -Wdeclaration-after-statement
-Wno-pointer-sign -fno-strict-overflow -fconserve-stack  -DMODULE
-D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(docg4)"
-D"KBUILD_MODNAME=KBUILD_STR(docg4)" --save-temps -c -o
drivers/mtd/nand/docg4.o drivers/mtd/nand/docg4.c

This generates docg4.i.

The only way for them to reproduce it would be getting the kernel as a
whole with the .config, no?

cheers,

 Bastian


From dedekind1 at gmail.com  Wed Oct 17 09:09:29 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 16:09:29 +0300
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <507DD09C.6050600@gmail.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
 <1349954577.12014.13.camel@sauron.fi.intel.com>
 <507DD09C.6050600@gmail.com>
Message-ID: <1350479369.5769.153.camel@sauron.fi.intel.com>

On Tue, 2012-10-16 at 23:24 +0200, Vincenzo Aliberti wrote:
> The only Warning is
> WARNING: line over 80 characters
> #605: FILE: include/uapi/mtd/mtd-abi.h:112:
> +#define MTD_CAP_PCM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
> 
> But in the file include/uapi/mtd/mtd-abi.h there is already the raw:
> #define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)

You can ignore this warning.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/8e2432c2/attachment.sig>

From dedekind1 at gmail.com  Wed Oct 17 09:12:09 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 16:12:09 +0300
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <201210111355.33836.marex@denx.de>
References: <201210050345.49507.marex@denx.de>
 <1349954707.12014.14.camel@sauron.fi.intel.com>
 <201210111355.33836.marex@denx.de>
Message-ID: <1350479529.5769.155.camel@sauron.fi.intel.com>

On Thu, 2012-10-11 at 13:55 +0200, Marek Vasut wrote:
> Dear Artem Bityutskiy,
> 
> > On Fri, 2012-10-05 at 03:45 +0200, Marek Vasut wrote:
> > > Hello guys,
> > > 
> > > I tried integck from mtd-utils 1.5.0 on GPMI NAND driver since I suspect
> > > it still has issues with UBI. See the outcome for yourself, log
> > > attached. Any suggestions would be very appreciated.
> > > 
> > > :~/mtd-utils-1.5.0/tests/fs-tests/integrity# ./integck /media
> > 
> > Wait, you have power-cut emulation enabled, did you deliberately enable
> > it via UBIFS debugfs files?
> 
> I enabled this:
> echo 1 > /sys/kernel/debug/ubifs/tst_recovery

Then this is expected behavior. You can run integck with -p, then it
will be aware for the power-cut emulation and will continue running.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/d7a6698b/attachment-0001.sig>

From dedekind1 at gmail.com  Wed Oct 17 09:13:56 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 16:13:56 +0300
Subject: [PATCH 3.6.0-] mtd/spear_smi: use module_platform_driver macro
In-Reply-To: <1349894399-9715-1-git-send-email-srinivas.kandagatla@st.com>
References: <1349894399-9715-1-git-send-email-srinivas.kandagatla@st.com>
Message-ID: <1350479636.5769.156.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 19:39 +0100, Srinivas KANDAGATLA wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla at st.com>
> 
> This patch removes some code duplication by using
> module_platform_driver.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at st.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/b4f820b9/attachment.sig>

From marex at denx.de  Wed Oct 17 09:16:55 2012
From: marex at denx.de (Marek Vasut)
Date: Wed, 17 Oct 2012 15:16:55 +0200
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <1350479529.5769.155.camel@sauron.fi.intel.com>
References: <201210050345.49507.marex@denx.de>
 <201210111355.33836.marex@denx.de>
 <1350479529.5769.155.camel@sauron.fi.intel.com>
Message-ID: <201210171516.55693.marex@denx.de>

Dear Artem Bityutskiy,

> On Thu, 2012-10-11 at 13:55 +0200, Marek Vasut wrote:
> > Dear Artem Bityutskiy,
> > 
> > > On Fri, 2012-10-05 at 03:45 +0200, Marek Vasut wrote:
> > > > Hello guys,
> > > > 
> > > > I tried integck from mtd-utils 1.5.0 on GPMI NAND driver since I
> > > > suspect it still has issues with UBI. See the outcome for yourself,
> > > > log attached. Any suggestions would be very appreciated.
> > > > 
> > > > :~/mtd-utils-1.5.0/tests/fs-tests/integrity# ./integck /media
> > > 
> > > Wait, you have power-cut emulation enabled, did you deliberately enable
> > > it via UBIFS debugfs files?
> > 
> > I enabled this:
> > echo 1 > /sys/kernel/debug/ubifs/tst_recovery
> 
> Then this is expected behavior. You can run integck with -p, then it
> will be aware for the power-cut emulation and will continue running.

Ok, I'll re-check. Though I suspect this problem disappeared with the recently 
applied UBI patches.

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Wed Oct 17 09:21:52 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 17 Oct 2012 16:21:52 +0300
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <201210171516.55693.marex@denx.de>
References: <201210050345.49507.marex@denx.de>
 <201210111355.33836.marex@denx.de>
 <1350479529.5769.155.camel@sauron.fi.intel.com>
 <201210171516.55693.marex@denx.de>
Message-ID: <1350480112.5769.160.camel@sauron.fi.intel.com>

On Wed, 2012-10-17 at 15:16 +0200, Marek Vasut wrote:
> Ok, I'll re-check. Though I suspect this problem disappeared with the
> recently 
> applied UBI patches.

No, you ask UBIFS to emulate a power cut, so it switched to R/O mode at
a random point. It printed scary error messages, which are normal
because an I/O operation failed. Then integck reported you the error and
stopped.

All expected.

If you use -p integck option you will just make integck _not_ fail when
the file-system suddenly becomes R/O, integck will just unmount it,
mount back, remove all its data, and start over. Then you'll get another
emulated power cut, and so on.

Ideally this should never stop. The idea is to test that UBIFS can mount
the file-system in case of a power cut.

If there is a problem, integck should die.

To just stress-test your driver you do not need power-cut emulation.
 
-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121017/262b0d52/attachment.sig>

From elezegarcia at gmail.com  Wed Oct 17 14:28:57 2012
From: elezegarcia at gmail.com (Ezequiel Garcia)
Date: Wed, 17 Oct 2012 15:28:57 -0300
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <1350480112.5769.160.camel@sauron.fi.intel.com>
References: <201210050345.49507.marex@denx.de>
 <201210111355.33836.marex@denx.de>
 <1350479529.5769.155.camel@sauron.fi.intel.com>
 <201210171516.55693.marex@denx.de>
 <1350480112.5769.160.camel@sauron.fi.intel.com>
Message-ID: <CALF0-+W0SqnxBVaTHjpjTzdw-fJoQ1qHBY8u3-rMcZ6wwc7z3w@mail.gmail.com>

On Wed, Oct 17, 2012 at 10:21 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> On Wed, 2012-10-17 at 15:16 +0200, Marek Vasut wrote:
>> Ok, I'll re-check. Though I suspect this problem disappeared with the
>> recently
>> applied UBI patches.
>
> No, you ask UBIFS to emulate a power cut, so it switched to R/O mode at
> a random point. It printed scary error messages, which are normal
> because an I/O operation failed. Then integck reported you the error and
> stopped.
>
> All expected.
>
> If you use -p integck option you will just make integck _not_ fail when
> the file-system suddenly becomes R/O, integck will just unmount it,
> mount back, remove all its data, and start over. Then you'll get another
> emulated power cut, and so on.
>
> Ideally this should never stop. The idea is to test that UBIFS can mount
> the file-system in case of a power cut.
>
> If there is a problem, integck should die.
>
> To just stress-test your driver you do not need power-cut emulation.
>

Is this expected behavior documented somewhere?

Thanks!

    Ezequiel


From thomas.betker at freenet.de  Wed Oct 17 16:59:30 2012
From: thomas.betker at freenet.de (Thomas Betker)
Date: Wed, 17 Oct 2012 22:59:30 +0200
Subject: [PATCH v3] jffs2: Fix lock acquisition order bug in jffs2_write_begin
Message-ID: <20779914.XYDRY924qZ@linux-fiwg>

jffs2_write_begin() first acquires the page lock, then f->sem. This 
causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first 
acquires f->sem, then the page lock:

jffs2_garbage_collect_live
    mutex_lock(&f->sem)                         (A)
    jffs2_garbage_collect_dnode
        jffs2_gc_fetch_page
            read_cache_page_async
                do_read_cache_page
                    lock_page(page)             (B)

jffs2_write_begin
    grab_cache_page_write_begin
        find_lock_page
            lock_page(page)                     (B)
    mutex_lock(&f->sem)                         (A)

We fix this by restructuring jffs2_write_begin() to take f->sem before 
the page lock. However, we make sure that f->sem is not held when 
calling jffs2_reserve_space(), as this is not permitted by the locking 
rules.

The deadlock above was observed multiple times on an SoC with a dual 
ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred 
when using scp to copy files from a host system to the ARM target 
system. The fix was heavily tested on the same target system.

Cc: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
Cc: stable at vger.kernel.org [v3.4+],
Signed-off-by: Thomas Betker <thomas.betker at rohde-schwarz.com>

diff -Naur linux-3.4.11-orig/fs/jffs2/file.c linux-3.4.11/fs/jffs2/file.c
--- linux-3.4.11-orig/fs/jffs2/file.c	2012-09-14 22:18:55.000000000 +0000
+++ linux-3.4.11/fs/jffs2/file.c	2012-10-05 09:01:10.000000000 +0000
@@ -138,33 +138,39 @@
 	struct page *pg;
 	struct inode *inode = mapping->host;
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+	struct jffs2_raw_inode ri;
+	uint32_t alloc_len = 0;
 	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 	uint32_t pageofs = index << PAGE_CACHE_SHIFT;
 	int ret = 0;
 
+	jffs2_dbg(1, "%s()\n", __func__);
+
+	if (pageofs > inode->i_size) {
+		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+		if (ret)
+			return ret;
+	}
+
+	mutex_lock(&f->sem);
 	pg = grab_cache_page_write_begin(mapping, index, flags);
-	if (!pg)
+	if (!pg) {
+		if (alloc_len)
+			jffs2_complete_reservation(c);
+		mutex_unlock(&f->sem);
 		return -ENOMEM;
+	}
 	*pagep = pg;
 
-	jffs2_dbg(1, "%s()\n", __func__);
-
-	if (pageofs > inode->i_size) {
+	if (alloc_len) {
 		/* Make new hole frag from old EOF to new page */
-		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-		struct jffs2_raw_inode ri;
 		struct jffs2_full_dnode *fn;
-		uint32_t alloc_len;
 
 		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs);
 
-		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-		if (ret)
-			goto out_page;
-
-		mutex_lock(&f->sem);
 		memset(&ri, 0, sizeof(ri));
 
 		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -191,7 +197,6 @@
 		if (IS_ERR(fn)) {
 			ret = PTR_ERR(fn);
 			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -206,12 +211,10 @@
 			jffs2_mark_node_obsolete(c, fn->raw);
 			jffs2_free_full_dnode(fn);
 			jffs2_complete_reservation(c);
-			mutex_unlock(&f->sem);
 			goto out_page;
 		}
 		jffs2_complete_reservation(c);
 		inode->i_size = pageofs;
-		mutex_unlock(&f->sem);
 	}
 
 	/*
@@ -220,18 +223,18 @@
 	 * case of a short-copy.
 	 */
 	if (!PageUptodate(pg)) {
-		mutex_lock(&f->sem);
 		ret = jffs2_do_readpage_nolock(inode, pg);
-		mutex_unlock(&f->sem);
 		if (ret)
 			goto out_page;
 	}
+	mutex_unlock(&f->sem);
 	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
 	return ret;
 
 out_page:
 	unlock_page(pg);
 	page_cache_release(pg);
+	mutex_unlock(&f->sem);
 	return ret;
 }
 



From thomas.betker at freenet.de  Wed Oct 17 17:22:34 2012
From: thomas.betker at freenet.de (Thomas Betker)
Date: Wed, 17 Oct 2012 23:22:34 +0200
Subject: [PATCH RESEND] jffs2: Fix lock acquisition order bug in
 jffs2_write_begin
In-Reply-To: <1350477742.5769.144.camel@sauron.fi.intel.com>
References: <507321E6.1050609@freenet.de> <507476E7.8030705@freenet.de>
 <1350477742.5769.144.camel@sauron.fi.intel.com>
Message-ID: <507F219A.4000700@freenet.de>

Hello Artem,

I have mailed theupdated patch to the list as "[PATCH v3] ...".

> This patch does not apply to l2-mtd.git, which is based on 3.7-rc1.
>
> $:~/git/l2-mtd$ git apply --check ~/tmp/thomas.mbox
> error: patch failed: fs/jffs2/file.c:138
> error: fs/jffs2/file.c: patch does not apply

Fixed, using another mailer ...

> Could you please wrap commit message lines to 80 characters when you
> re-send?

Fixed -- sorry, this should not have happened.

> Also, would you please add Cc: stable at vger.kernel.org [vX.Y+], where
> vX.Y is the starting version for which this patch is relevant, e.g.,
> v3.0.

Fixed, using [v3.4+]. (The patch may also be relevant for earlier kernel versions, but I don't have the means to test them.)

Thanks,
Thomas



From vipin.kumar at st.com  Thu Oct 18 00:13:44 2012
From: vipin.kumar at st.com (Vipin Kumar)
Date: Thu, 18 Oct 2012 09:43:44 +0530
Subject: [PATCH 00/11] mtd/nand: fsmc driver updates
In-Reply-To: <1350478116.5769.150.camel@sauron.fi.intel.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <1350478116.5769.150.camel@sauron.fi.intel.com>
Message-ID: <507F81F8.9030107@st.com>

On 10/17/2012 6:18 PM, Artem Bityutskiy wrote:
> On Tue, 2012-10-09 at 16:14 +0530, Vipin Kumar wrote:
>> This patch-set contains several fixes and a few enhancements in fsmc driver.
>> Modifications include
>
> OK, picked some patches from your series, some do not apply. Please,
> send v2 against the l2-mtd.git tree:
>
> git://git.infradead.org/users/dedekind/l2-mtd.git
>

Sure, I would do that soon. Thanks

-Vipin


From b32955 at freescale.com  Thu Oct 18 01:32:15 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 13:32:15 +0800
Subject: [PATCH] dma: add new DMA control commands
Message-ID: <1350538335-29026-1-git-send-email-b32955@freescale.com>

From: Huang Shijie <shijie8 at gmail.com>

[1] Why add these new DMA control commands?
    In mx6q, the gpmi-nand driver is the only user of the APBH-DMA. The dma clock
    is enabled when we have successfully requested a DMA channel. So even when
    the gpmi-nand driver does not work, the dma clock(apbh-dma) still runs
    in high speed (198MHz). To save some power, it is better to disable the dma
    clock when the dma device, such as gpmi-nand, is not working anymore.
    When the dma device becomes work again, enable the dma clock again.

[2] add new DMA control commands: DMA_START/DMA_END
    DMA_START: do some preprations to start the DMA engine, such as enable the
               necessary clocks.
    DMA_END: do some works to end the DMA engine, such as disable the
               necessary clocks.

[3] This patch does not change any logic in i2c-mxs driver and mxs-pcm driver.
    But for gpmi-nand driver, we will enable the the clock only when we select
    the nand chip, and want to do some real jobs with the nand chip.
    For mxs-mmc driver, disable the dma clock in the suspend; and enable the
    dma clock in the resume.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 drivers/dma/mxs-dma.c                  |   17 +++++++++++++++++
 drivers/i2c/busses/i2c-mxs.c           |   10 +++++++++-
 drivers/mmc/host/mxs-mmc.c             |   19 ++++++++++++++++---
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |   10 ++++++++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |   10 ++++++----
 include/linux/dmaengine.h              |    6 ++++++
 sound/soc/mxs/mxs-pcm.c                |   12 ++++++++++++
 7 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 9f02e79..89286f4 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -384,6 +384,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
 	/* the descriptor is ready */
 	async_tx_ack(&mxs_chan->desc);
 
+	clk_disable_unprepare(mxs_dma->clk);
+
 	return 0;
 
 err_clk:
@@ -399,6 +401,14 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
 {
 	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
 	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+	int ret;
+
+	ret = clk_prepare_enable(mxs_dma->clk);
+	if (ret) {
+		dev_err(mxs_dma->dma_device.dev,
+			"failed in enabling the dma clock\n");
+		return;
+	}
 
 	mxs_dma_disable_chan(mxs_chan);
 
@@ -597,9 +607,13 @@ static int mxs_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 		unsigned long arg)
 {
 	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
+	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
 	int ret = 0;
 
 	switch (cmd) {
+	case DMA_START:
+		ret = clk_prepare_enable(mxs_dma->clk);
+		break;
 	case DMA_TERMINATE_ALL:
 		mxs_dma_reset_chan(mxs_chan);
 		mxs_dma_disable_chan(mxs_chan);
@@ -610,6 +624,9 @@ static int mxs_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 	case DMA_RESUME:
 		mxs_dma_resume_chan(mxs_chan);
 		break;
+	case DMA_END:
+		clk_disable_unprepare(mxs_dma->clk);
+		break;
 	default:
 		ret = -ENOSYS;
 	}
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 1f58197..da1e881 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -643,6 +643,12 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
 			dev_err(dev, "Failed to request dma\n");
 			return -ENODEV;
 		}
+		err = dmaengine_device_control(i2c->dmach, DMA_START, 0);
+		if (err) {
+			dma_release_channel(i2c->dmach);
+			dev_err(dev, "Failed to start dma\n");
+			return err;
+		}
 	}
 
 	platform_set_drvdata(pdev, i2c);
@@ -680,8 +686,10 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
 	if (ret)
 		return -EBUSY;
 
-	if (i2c->dmach)
+	if (i2c->dmach) {
+		dmaengine_device_control(i2c->dmach, DMA_END, 0);
 		dma_release_channel(i2c->dmach);
+	}
 
 	writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
 
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 80d1e6d..aa91830 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -676,6 +676,9 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 			"%s: failed to request dma\n", __func__);
 		goto out_clk_put;
 	}
+	ret = dmaengine_device_control(ssp->dmach, DMA_START, 0);
+	if (ret)
+		goto out_free_dma;
 
 	/* set mmc core parameters */
 	mmc->ops = &mxs_mmc_ops;
@@ -717,18 +720,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 	ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
 			       DRIVER_NAME, host);
 	if (ret)
-		goto out_free_dma;
+		goto out_end_free_dma;
 
 	spin_lock_init(&host->lock);
 
 	ret = mmc_add_host(mmc);
 	if (ret)
-		goto out_free_dma;
+		goto out_end_free_dma;
 
 	dev_info(mmc_dev(host->mmc), "initialized\n");
 
 	return 0;
 
+out_end_free_dma:
+	dmaengine_device_control(ssp->dmach, DMA_END, 0);
 out_free_dma:
 	if (ssp->dmach)
 		dma_release_channel(ssp->dmach);
@@ -750,8 +755,10 @@ static int mxs_mmc_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	if (ssp->dmach)
+	if (ssp->dmach) {
+		dmaengine_device_control(ssp->dmach, DMA_END, 0);
 		dma_release_channel(ssp->dmach);
+	}
 
 	clk_disable_unprepare(ssp->clk);
 	clk_put(ssp->clk);
@@ -772,6 +779,7 @@ static int mxs_mmc_suspend(struct device *dev)
 	ret = mmc_suspend_host(mmc);
 
 	clk_disable_unprepare(ssp->clk);
+	dmaengine_device_control(ssp->dmach, DMA_END, 0);
 
 	return ret;
 }
@@ -784,8 +792,13 @@ static int mxs_mmc_resume(struct device *dev)
 	int ret = 0;
 
 	clk_prepare_enable(ssp->clk);
+	ret = dmaengine_device_control(ssp->dmach, DMA_START, 0);
+	if (ret)
+		return ret;
 
 	ret = mmc_resume_host(mmc);
+	if (ret)
+		dmaengine_device_control(ssp->dmach, DMA_END, 0);
 
 	return ret;
 }
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 3502acc..20ed3f3 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -958,6 +958,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
 	uint32_t       reg;
 	unsigned int   dll_wait_time_in_us;
 	struct gpmi_nfc_hardware_timing  hw;
+	struct dma_chan *channel = get_dma_chan(this);
 	int ret;
 
 	/* Enable the clock. */
@@ -967,6 +968,12 @@ void gpmi_begin(struct gpmi_nand_data *this)
 		goto err_out;
 	}
 
+	ret = dmaengine_device_control(channel, DMA_START, 0);
+	if (ret) {
+		gpmi_disable_clk(this);
+		goto err_out;
+	}
+
 	/* Only initialize the timing once */
 	if (this->flags & GPMI_TIMING_INIT_OK)
 		return;
@@ -1035,7 +1042,10 @@ err_out:
 
 void gpmi_end(struct gpmi_nand_data *this)
 {
+	struct dma_chan *channel = get_dma_chan(this);
+
 	gpmi_disable_clk(this);
+	dmaengine_device_control(channel, DMA_END, 0);
 }
 
 /* Clears a BCH interrupt. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index e2c56fc..5694d03 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -815,12 +815,14 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
 	struct nand_chip *chip = mtd->priv;
 	struct gpmi_nand_data *this = chip->priv;
 
-	if ((this->current_chip < 0) && (chipnr >= 0))
+	if ((this->current_chip < 0) && (chipnr >= 0)) {
+		/* set the current_chip before we call gpmi_begin(). */
+		this->current_chip = chipnr;
 		gpmi_begin(this);
-	else if ((this->current_chip >= 0) && (chipnr < 0))
+	} else if ((this->current_chip >= 0) && (chipnr < 0)) {
 		gpmi_end(this);
-
-	this->current_chip = chipnr;
+		this->current_chip = chipnr;
+	}
 }
 
 static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index d3201e4..79f864a 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -199,6 +199,8 @@ enum dma_ctrl_flags {
 /**
  * enum dma_ctrl_cmd - DMA operations that can optionally be exercised
  * on a running channel.
+ * @DMA_START: do some preprations to start the DMA engine, such as enable the
+ * necessary clocks.
  * @DMA_TERMINATE_ALL: terminate all ongoing transfers
  * @DMA_PAUSE: pause ongoing transfers
  * @DMA_RESUME: resume paused transfer
@@ -209,13 +211,17 @@ enum dma_ctrl_flags {
  * command.
  * @FSLDMA_EXTERNAL_START: this command will put the Freescale DMA controller
  * into external start mode.
+ * @DMA_END: do some works to end the DMA engine, such as disable the
+ * necessary clocks.
  */
 enum dma_ctrl_cmd {
+	DMA_START,
 	DMA_TERMINATE_ALL,
 	DMA_PAUSE,
 	DMA_RESUME,
 	DMA_SLAVE_CONFIG,
 	FSLDMA_EXTERNAL_START,
+	DMA_END,
 };
 
 /**
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index f82d766..cfcc30f 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -92,6 +92,7 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct mxs_pcm_dma_data *pcm_dma_data;
+	struct dma_chan *chan;
 	int ret;
 
 	pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
@@ -107,6 +108,14 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
 		return ret;
 	}
 
+	chan = snd_dmaengine_pcm_get_chan(substream);
+	ret = dmaengine_device_control(chan, DMA_START, (unsigned long)0);
+	if (ret) {
+		snd_dmaengine_pcm_close(substream);
+		kfree(pcm_dma_data);
+		return ret;
+	}
+
 	snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
 
 	snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
@@ -117,7 +126,10 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
 static int snd_mxs_close(struct snd_pcm_substream *substream)
 {
 	struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
+	struct dma_chan *chan;
 
+	chan = snd_dmaengine_pcm_get_chan(substream);
+	dmaengine_device_control(chan, DMA_END, 0);
 	snd_dmaengine_pcm_close(substream);
 	kfree(pcm_dma_data);
 
-- 
1.7.0.4




From vinod.koul at linux.intel.com  Thu Oct 18 02:18:31 2012
From: vinod.koul at linux.intel.com (Vinod Koul)
Date: Thu, 18 Oct 2012 11:48:31 +0530
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <1350538335-29026-1-git-send-email-b32955@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
Message-ID: <1350541111.5263.3.camel@vkoul-udesk3>

On Thu, 2012-10-18 at 13:32 +0800, Huang Shijie wrote:
> From: Huang Shijie <shijie8 at gmail.com>
> 
> [1] Why add these new DMA control commands?
>     In mx6q, the gpmi-nand driver is the only user of the APBH-DMA. The dma clock
>     is enabled when we have successfully requested a DMA channel. So even when
>     the gpmi-nand driver does not work, the dma clock(apbh-dma) still runs
>     in high speed (198MHz). To save some power, it is better to disable the dma
>     clock when the dma device, such as gpmi-nand, is not working anymore.
>     When the dma device becomes work again, enable the dma clock again.
> 
> [2] add new DMA control commands: DMA_START/DMA_END
>     DMA_START: do some preprations to start the DMA engine, such as enable the
>                necessary clocks.
>     DMA_END: do some works to end the DMA engine, such as disable the
>                necessary clocks.
> 
> [3] This patch does not change any logic in i2c-mxs driver and mxs-pcm driver.
>     But for gpmi-nand driver, we will enable the the clock only when we select
>     the nand chip, and want to do some real jobs with the nand chip.
>     For mxs-mmc driver, disable the dma clock in the suspend; and enable the
>     dma clock in the resume.
> 
Why cant you do start (prepare clock etc) when you submit the descriptor
to dmaengine. Can be done in tx_submit callback.
Similarly remove the clock when dma transaction gets completed.

I don't think we need a new API for this, it needs to be handled by
driver on its own.

> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  drivers/dma/mxs-dma.c                  |   17 +++++++++++++++++
>  drivers/i2c/busses/i2c-mxs.c           |   10 +++++++++-
>  drivers/mmc/host/mxs-mmc.c             |   19 ++++++++++++++++---
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |   10 ++++++++++
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |   10 ++++++----
>  include/linux/dmaengine.h              |    6 ++++++
>  sound/soc/mxs/mxs-pcm.c                |   12 ++++++++++++
>  7 files changed, 76 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
> index 9f02e79..89286f4 100644
> --- a/drivers/dma/mxs-dma.c
> +++ b/drivers/dma/mxs-dma.c
> @@ -384,6 +384,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
>  	/* the descriptor is ready */
>  	async_tx_ack(&mxs_chan->desc);
>  
> +	clk_disable_unprepare(mxs_dma->clk);
> +
>  	return 0;
>  
>  err_clk:
> @@ -399,6 +401,14 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
>  {
>  	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
>  	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
> +	int ret;
> +
> +	ret = clk_prepare_enable(mxs_dma->clk);
> +	if (ret) {
> +		dev_err(mxs_dma->dma_device.dev,
> +			"failed in enabling the dma clock\n");
> +		return;
> +	}
>  
>  	mxs_dma_disable_chan(mxs_chan);
>  
> @@ -597,9 +607,13 @@ static int mxs_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
>  		unsigned long arg)
>  {
>  	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
> +	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
>  	int ret = 0;
>  
>  	switch (cmd) {
> +	case DMA_START:
> +		ret = clk_prepare_enable(mxs_dma->clk);
> +		break;
>  	case DMA_TERMINATE_ALL:
>  		mxs_dma_reset_chan(mxs_chan);
>  		mxs_dma_disable_chan(mxs_chan);
> @@ -610,6 +624,9 @@ static int mxs_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
>  	case DMA_RESUME:
>  		mxs_dma_resume_chan(mxs_chan);
>  		break;
> +	case DMA_END:
> +		clk_disable_unprepare(mxs_dma->clk);
> +		break;
>  	default:
>  		ret = -ENOSYS;
>  	}
> diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
> index 1f58197..da1e881 100644
> --- a/drivers/i2c/busses/i2c-mxs.c
> +++ b/drivers/i2c/busses/i2c-mxs.c
> @@ -643,6 +643,12 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
>  			dev_err(dev, "Failed to request dma\n");
>  			return -ENODEV;
>  		}
> +		err = dmaengine_device_control(i2c->dmach, DMA_START, 0);
> +		if (err) {
> +			dma_release_channel(i2c->dmach);
> +			dev_err(dev, "Failed to start dma\n");
> +			return err;
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, i2c);
> @@ -680,8 +686,10 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
>  	if (ret)
>  		return -EBUSY;
>  
> -	if (i2c->dmach)
> +	if (i2c->dmach) {
> +		dmaengine_device_control(i2c->dmach, DMA_END, 0);
>  		dma_release_channel(i2c->dmach);
> +	}
>  
>  	writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
>  
> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index 80d1e6d..aa91830 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -676,6 +676,9 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  			"%s: failed to request dma\n", __func__);
>  		goto out_clk_put;
>  	}
> +	ret = dmaengine_device_control(ssp->dmach, DMA_START, 0);
> +	if (ret)
> +		goto out_free_dma;
>  
>  	/* set mmc core parameters */
>  	mmc->ops = &mxs_mmc_ops;
> @@ -717,18 +720,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  	ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
>  			       DRIVER_NAME, host);
>  	if (ret)
> -		goto out_free_dma;
> +		goto out_end_free_dma;
>  
>  	spin_lock_init(&host->lock);
>  
>  	ret = mmc_add_host(mmc);
>  	if (ret)
> -		goto out_free_dma;
> +		goto out_end_free_dma;
>  
>  	dev_info(mmc_dev(host->mmc), "initialized\n");
>  
>  	return 0;
>  
> +out_end_free_dma:
> +	dmaengine_device_control(ssp->dmach, DMA_END, 0);
>  out_free_dma:
>  	if (ssp->dmach)
>  		dma_release_channel(ssp->dmach);
> @@ -750,8 +755,10 @@ static int mxs_mmc_remove(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, NULL);
>  
> -	if (ssp->dmach)
> +	if (ssp->dmach) {
> +		dmaengine_device_control(ssp->dmach, DMA_END, 0);
>  		dma_release_channel(ssp->dmach);
> +	}
>  
>  	clk_disable_unprepare(ssp->clk);
>  	clk_put(ssp->clk);
> @@ -772,6 +779,7 @@ static int mxs_mmc_suspend(struct device *dev)
>  	ret = mmc_suspend_host(mmc);
>  
>  	clk_disable_unprepare(ssp->clk);
> +	dmaengine_device_control(ssp->dmach, DMA_END, 0);
>  
>  	return ret;
>  }
> @@ -784,8 +792,13 @@ static int mxs_mmc_resume(struct device *dev)
>  	int ret = 0;
>  
>  	clk_prepare_enable(ssp->clk);
> +	ret = dmaengine_device_control(ssp->dmach, DMA_START, 0);
> +	if (ret)
> +		return ret;
>  
>  	ret = mmc_resume_host(mmc);
> +	if (ret)
> +		dmaengine_device_control(ssp->dmach, DMA_END, 0);
>  
>  	return ret;
>  }
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> index 3502acc..20ed3f3 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> @@ -958,6 +958,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
>  	uint32_t       reg;
>  	unsigned int   dll_wait_time_in_us;
>  	struct gpmi_nfc_hardware_timing  hw;
> +	struct dma_chan *channel = get_dma_chan(this);
>  	int ret;
>  
>  	/* Enable the clock. */
> @@ -967,6 +968,12 @@ void gpmi_begin(struct gpmi_nand_data *this)
>  		goto err_out;
>  	}
>  
> +	ret = dmaengine_device_control(channel, DMA_START, 0);
> +	if (ret) {
> +		gpmi_disable_clk(this);
> +		goto err_out;
> +	}
> +
>  	/* Only initialize the timing once */
>  	if (this->flags & GPMI_TIMING_INIT_OK)
>  		return;
> @@ -1035,7 +1042,10 @@ err_out:
>  
>  void gpmi_end(struct gpmi_nand_data *this)
>  {
> +	struct dma_chan *channel = get_dma_chan(this);
> +
>  	gpmi_disable_clk(this);
> +	dmaengine_device_control(channel, DMA_END, 0);
>  }
>  
>  /* Clears a BCH interrupt. */
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index e2c56fc..5694d03 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -815,12 +815,14 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
>  	struct nand_chip *chip = mtd->priv;
>  	struct gpmi_nand_data *this = chip->priv;
>  
> -	if ((this->current_chip < 0) && (chipnr >= 0))
> +	if ((this->current_chip < 0) && (chipnr >= 0)) {
> +		/* set the current_chip before we call gpmi_begin(). */
> +		this->current_chip = chipnr;
>  		gpmi_begin(this);
> -	else if ((this->current_chip >= 0) && (chipnr < 0))
> +	} else if ((this->current_chip >= 0) && (chipnr < 0)) {
>  		gpmi_end(this);
> -
> -	this->current_chip = chipnr;
> +		this->current_chip = chipnr;
> +	}
>  }
>  
>  static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index d3201e4..79f864a 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -199,6 +199,8 @@ enum dma_ctrl_flags {
>  /**
>   * enum dma_ctrl_cmd - DMA operations that can optionally be exercised
>   * on a running channel.
> + * @DMA_START: do some preprations to start the DMA engine, such as enable the
> + * necessary clocks.
>   * @DMA_TERMINATE_ALL: terminate all ongoing transfers
>   * @DMA_PAUSE: pause ongoing transfers
>   * @DMA_RESUME: resume paused transfer
> @@ -209,13 +211,17 @@ enum dma_ctrl_flags {
>   * command.
>   * @FSLDMA_EXTERNAL_START: this command will put the Freescale DMA controller
>   * into external start mode.
> + * @DMA_END: do some works to end the DMA engine, such as disable the
> + * necessary clocks.
>   */
>  enum dma_ctrl_cmd {
> +	DMA_START,
>  	DMA_TERMINATE_ALL,
>  	DMA_PAUSE,
>  	DMA_RESUME,
>  	DMA_SLAVE_CONFIG,
>  	FSLDMA_EXTERNAL_START,
> +	DMA_END,
>  };
>  
>  /**
> diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
> index f82d766..cfcc30f 100644
> --- a/sound/soc/mxs/mxs-pcm.c
> +++ b/sound/soc/mxs/mxs-pcm.c
> @@ -92,6 +92,7 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
>  {
>  	struct snd_soc_pcm_runtime *rtd = substream->private_data;
>  	struct mxs_pcm_dma_data *pcm_dma_data;
> +	struct dma_chan *chan;
>  	int ret;
>  
>  	pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
> @@ -107,6 +108,14 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
>  		return ret;
>  	}
>  
> +	chan = snd_dmaengine_pcm_get_chan(substream);
> +	ret = dmaengine_device_control(chan, DMA_START, (unsigned long)0);
> +	if (ret) {
> +		snd_dmaengine_pcm_close(substream);
> +		kfree(pcm_dma_data);
> +		return ret;
> +	}
> +
>  	snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
>  
>  	snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
> @@ -117,7 +126,10 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
>  static int snd_mxs_close(struct snd_pcm_substream *substream)
>  {
>  	struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
> +	struct dma_chan *chan;
>  
> +	chan = snd_dmaengine_pcm_get_chan(substream);
> +	dmaengine_device_control(chan, DMA_END, 0);
>  	snd_dmaengine_pcm_close(substream);
>  	kfree(pcm_dma_data);
>  


-- 
~Vinod



From computersforpeace at gmail.com  Thu Oct 18 02:36:46 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 17 Oct 2012 23:36:46 -0700
Subject: [PATCH 11/11] nand: Increase the ecc placement locations to 640
In-Reply-To: <67e0aae3b23f37feb30789f5c6cb342b5684911a.1349778821.git.vipin.kumar@st.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <67e0aae3b23f37feb30789f5c6cb342b5684911a.1349778821.git.vipin.kumar@st.com>
Message-ID: <CAN8TOE_FcjZs3=Q+36S68D9xKmk_m2j+UxqoJSu+p_fgo4cG6Q@mail.gmail.com>

On Tue, Oct 9, 2012 at 3:44 AM, Vipin Kumar <vipin.kumar at st.com> wrote:
> Few devices like H27UBG8T2CTR have a writesize/oobsize of 8KB/640B.
> This means that the maximum oobsize has gone up to 640 bytes and consequently
> the maximum ecc placement locations have also gone up to 640.

We really need to change the nand_ecclayout struct sometime. Each one
takes something like 4+4?640+4+32?8 = 2824 bytes now, and we have 4 of
them statically declared in nand_base.c. And most drivers just declare
their own anyway. (fsl_{elbc,ifc}_nand.c have 4 and 5 of them each)

I've thought about dynamically allocating and/or changing its layout
so that we can do eccpos ranges, similar to the oobfree entries. But
this gets harder, with the old ioctl(ECCGETLAYOUT) still hanging
around, a few platform uses of nand_ecclayout, and probably some other
complications.

Anyway, this comes off as basically a complaint, while in fact, I
wanted to see if anyone else agreed and/or had any suggestions. Or,
maybe somebody could convince me not to care...

Brian


From b32955 at freescale.com  Thu Oct 18 02:45:41 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 14:45:41 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <1350541111.5263.3.camel@vkoul-udesk3>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3>
Message-ID: <507FA595.4020507@freescale.com>

? 2012?10?18? 14:18, Vinod Koul ??:
> Why cant you do start (prepare clock etc) when you submit the descriptor
> to dmaengine. Can be done in tx_submit callback.
> Similarly remove the clock when dma transaction gets completed.
I ever thought this method too.

But it will become low efficient in the following case:

   Assuming the gpmi-nand driver has to read out 1024 pages in one 
_SINGLE_ read operation.
The gpmi-nand will submit the descriptor to dmaengine per page. So with 
your method,
the system will repeat the enable/disable dma clock 1024 time. At every 
enable/disable dma clock,
the system has to enable the clock chain and it's parents ...

But with this patch, we only need to enable/disable dma clock one time, 
just at we select the nand chip.

thanks
Huang Shijie






From marex at denx.de  Thu Oct 18 03:14:58 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 18 Oct 2012 09:14:58 +0200
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FA595.4020507@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3> <507FA595.4020507@freescale.com>
Message-ID: <201210180914.58527.marex@denx.de>

Dear Huang Shijie,

Why such massive CC ?

> ? 2012?10?18? 14:18, Vinod Koul ??:
> > Why cant you do start (prepare clock etc) when you submit the descriptor
> > to dmaengine. Can be done in tx_submit callback.
> > Similarly remove the clock when dma transaction gets completed.
> 
> I ever thought this method too.
> 
> But it will become low efficient in the following case:
> 
>    Assuming the gpmi-nand driver has to read out 1024 pages in one
> _SINGLE_ read operation.
> The gpmi-nand will submit the descriptor to dmaengine per page.

It will? Then GPMI NAND is flat our broken ... again.

> So with
> your method,
> the system will repeat the enable/disable dma clock 1024 time.

Yes, it is the driver that's wrong.

> At every
> enable/disable dma clock,
> the system has to enable the clock chain and it's parents ...
> 
> But with this patch, we only need to enable/disable dma clock one time,
> just at we select the nand chip.

You are fixing a driver problem at a framework level, wrong.

So, check how the MXS SPI driver handles descriptor chaining. Indeed, the 
Sigmatel screwed the DMA stuff good. But if you analyze the SPI driver, you'll 
notice a few important points that might come handy when you fix the GPMI NAND 
driver properly.

The direction to take here is:
1) Implement DMA chaining into the GPMI NAND driver
2) You might need to do one PIO transfer to reconfigure the IP registers between 
each segment of the DMA chain (just as MXS SPI does it)
3) You might run out of DMA descriptors when doing too long chains -- so you 
might need to fix that part of the mxs DMA driver.

> thanks
> Huang Shijie

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Thu Oct 18 03:43:17 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 10:43:17 +0300
Subject: GPMI NAND crashes with UBIFS
In-Reply-To: <CALF0-+W0SqnxBVaTHjpjTzdw-fJoQ1qHBY8u3-rMcZ6wwc7z3w@mail.gmail.com>
References: <201210050345.49507.marex@denx.de>
 <201210111355.33836.marex@denx.de>
 <1350479529.5769.155.camel@sauron.fi.intel.com>
 <201210171516.55693.marex@denx.de>
 <1350480112.5769.160.camel@sauron.fi.intel.com>
 <CALF0-+W0SqnxBVaTHjpjTzdw-fJoQ1qHBY8u3-rMcZ6wwc7z3w@mail.gmail.com>
Message-ID: <1350546197.5769.297.camel@sauron.fi.intel.com>

On Wed, 2012-10-17 at 15:28 -0300, Ezequiel Garcia wrote:
> On Wed, Oct 17, 2012 at 10:21 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> > On Wed, 2012-10-17 at 15:16 +0200, Marek Vasut wrote:
> >> Ok, I'll re-check. Though I suspect this problem disappeared with the
> >> recently
> >> applied UBI patches.
> >
> > No, you ask UBIFS to emulate a power cut, so it switched to R/O mode at
> > a random point. It printed scary error messages, which are normal
> > because an I/O operation failed. Then integck reported you the error and
> > stopped.
> >
> > All expected.
> >
> > If you use -p integck option you will just make integck _not_ fail when
> > the file-system suddenly becomes R/O, integck will just unmount it,
> > mount back, remove all its data, and start over. Then you'll get another
> > emulated power cut, and so on.
> >
> > Ideally this should never stop. The idea is to test that UBIFS can mount
> > the file-system in case of a power cut.
> >
> > If there is a problem, integck should die.
> >
> > To just stress-test your driver you do not need power-cut emulation.
> >
> 
> Is this expected behavior documented somewhere?

Sorry, no. I do not mind if someone sends a patch for mtd-www.git with
some docs WRT power-cut emulation stuff.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/83c113bd/attachment-0001.sig>

From b32955 at freescale.com  Thu Oct 18 03:49:41 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 15:49:41 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <201210180914.58527.marex@denx.de>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3> <507FA595.4020507@freescale.com>
 <201210180914.58527.marex@denx.de>
Message-ID: <507FB495.7050104@freescale.com>

? 2012?10?18? 15:14, Marek Vasut ??:
> Dear Huang Shijie,
>
> Why such massive CC ?
>
>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>> to dmaengine. Can be done in tx_submit callback.
>>> Similarly remove the clock when dma transaction gets completed.
>> I ever thought this method too.
>>
>> But it will become low efficient in the following case:
>>
>>     Assuming the gpmi-nand driver has to read out 1024 pages in one
>> _SINGLE_ read operation.
>> The gpmi-nand will submit the descriptor to dmaengine per page.
> It will? Then GPMI NAND is flat our broken ... again.
yes.

Please read the NAND chip spec about the comand READ PAGE(00h-30h) and 
the code
nand_do_read_ops(). The nand chip limits us only read one page out one time.
So the driver will submit the descriptor to dmaengine per page.



>> So with
>> your method,
>> the system will repeat the enable/disable dma clock 1024 time.
> Yes, it is the driver that's wrong.
not the driver.
>> At every
>> enable/disable dma clock,
>> the system has to enable the clock chain and it's parents ...
>>
>> But with this patch, we only need to enable/disable dma clock one time,
>> just at we select the nand chip.
> You are fixing a driver problem at a framework level, wrong.
>
> So, check how the MXS SPI driver handles descriptor chaining. Indeed, the
> Sigmatel screwed the DMA stuff good. But if you analyze the SPI driver, you'll
> notice a few important points that might come handy when you fix the GPMI NAND
> driver properly.
>
> The direction to take here is:
> 1) Implement DMA chaining into the GPMI NAND driver
How can i implement the DMA chain if the nand chip READ-PAGE command 
gives us the one page limit?

thanks
Huang Shijie


> 2) You might need to do one PIO transfer to reconfigure the IP registers between
> each segment of the DMA chain (just as MXS SPI does it)
> 3) You might run out of DMA descriptors when doing too long chains -- so you
> might need to fix that part of the mxs DMA driver.




From marex at denx.de  Thu Oct 18 04:16:06 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 18 Oct 2012 10:16:06 +0200
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FB495.7050104@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210180914.58527.marex@denx.de> <507FB495.7050104@freescale.com>
Message-ID: <201210181016.06782.marex@denx.de>

Dear Huang Shijie,

> ? 2012?10?18? 15:14, Marek Vasut ??:
> > Dear Huang Shijie,
> > 
> > Why such massive CC ?
> > 
> >> ? 2012?10?18? 14:18, Vinod Koul ??:
> >>> Why cant you do start (prepare clock etc) when you submit the
> >>> descriptor to dmaengine. Can be done in tx_submit callback.
> >>> Similarly remove the clock when dma transaction gets completed.
> >> 
> >> I ever thought this method too.
> >> 
> >> But it will become low efficient in the following case:
> >>     Assuming the gpmi-nand driver has to read out 1024 pages in one
> >> 
> >> _SINGLE_ read operation.
> >> The gpmi-nand will submit the descriptor to dmaengine per page.
> > 
> > It will? Then GPMI NAND is flat our broken ... again.
> 
> yes.
> 
> Please read the NAND chip spec about the comand READ PAGE(00h-30h) and
> the code
> nand_do_read_ops(). The nand chip limits us only read one page out one
> time. So the driver will submit the descriptor to dmaengine per page.

So we can't stream data from the chip? About time to adjust the MTD framework to 
allow that. Maybe implement a command queue?

> >> So with
> >> your method,
> >> the system will repeat the enable/disable dma clock 1024 time.
> > 
> > Yes, it is the driver that's wrong.
> 
> not the driver.
> 
> >> At every
> >> enable/disable dma clock,
> >> the system has to enable the clock chain and it's parents ...
> >> 
> >> But with this patch, we only need to enable/disable dma clock one time,
> >> just at we select the nand chip.
> > 
> > You are fixing a driver problem at a framework level, wrong.
> > 
> > So, check how the MXS SPI driver handles descriptor chaining. Indeed, the
> > Sigmatel screwed the DMA stuff good. But if you analyze the SPI driver,
> > you'll notice a few important points that might come handy when you fix
> > the GPMI NAND driver properly.
> > 
> > The direction to take here is:
> > 1) Implement DMA chaining into the GPMI NAND driver
> 
> How can i implement the DMA chain if the nand chip READ-PAGE command
> gives us the one page limit?

This smells like a time to extend the MTD api ?

> thanks
> Huang Shijie
> 
> > 2) You might need to do one PIO transfer to reconfigure the IP registers
> > between each segment of the DMA chain (just as MXS SPI does it)
> > 3) You might run out of DMA descriptors when doing too long chains -- so
> > you might need to fix that part of the mxs DMA driver.

Best regards,
Marek Vasut


From b32955 at freescale.com  Thu Oct 18 04:29:37 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 16:29:37 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <201210181016.06782.marex@denx.de>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210180914.58527.marex@denx.de> <507FB495.7050104@freescale.com>
 <201210181016.06782.marex@denx.de>
Message-ID: <507FBDF1.5050602@freescale.com>

? 2012?10?18? 16:16, Marek Vasut ??:
> So we can't stream data from the chip? About time to adjust the MTD framework to
> allow that. Maybe implement a command queue?
>

to Artem & David:
    is this possible to stream the data out with a command queue?

thanks
Huang Shijie



From b32955 at freescale.com  Thu Oct 18 04:49:20 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 16:49:20 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <201210181016.06782.marex@denx.de>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210180914.58527.marex@denx.de> <507FB495.7050104@freescale.com>
 <201210181016.06782.marex@denx.de>
Message-ID: <507FC290.10205@freescale.com>

? 2012?10?18? 16:16, Marek Vasut ??:
> So we can't stream data from the chip? About time to adjust the MTD framework to
> allow that. Maybe implement a command queue?
>
IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to 
check the busy status
which means we have to stop in the middle, so we can not chain the all 
the read-pages DMA commands.

thanks
Huang Shijie




From marex at denx.de  Thu Oct 18 04:49:21 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 18 Oct 2012 10:49:21 +0200
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FC290.10205@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210181016.06782.marex@denx.de> <507FC290.10205@freescale.com>
Message-ID: <201210181049.21556.marex@denx.de>

Dear Huang Shijie,

> ? 2012?10?18? 16:16, Marek Vasut ??:
> > So we can't stream data from the chip? About time to adjust the MTD
> > framework to allow that. Maybe implement a command queue?
> 
> IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to
> check the busy status
> which means we have to stop in the middle, so we can not chain the all
> the read-pages DMA commands.

Can the DMA not branch?

> thanks
> Huang Shijie

Best regards,
Marek Vasut


From linux at arm.linux.org.uk  Thu Oct 18 04:52:08 2012
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 18 Oct 2012 09:52:08 +0100
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FA595.4020507@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3> <507FA595.4020507@freescale.com>
Message-ID: <20121018085208.GR21164@n2100.arm.linux.org.uk>

On Thu, Oct 18, 2012 at 02:45:41PM +0800, Huang Shijie wrote:
> ? 2012?10?18? 14:18, Vinod Koul ??:
>> Why cant you do start (prepare clock etc) when you submit the descriptor
>> to dmaengine. Can be done in tx_submit callback.
>> Similarly remove the clock when dma transaction gets completed.
> I ever thought this method too.
>
> But it will become low efficient in the following case:
>
>   Assuming the gpmi-nand driver has to read out 1024 pages in one  
> _SINGLE_ read operation.
> The gpmi-nand will submit the descriptor to dmaengine per page. So with  
> your method,
> the system will repeat the enable/disable dma clock 1024 time. At every  
> enable/disable dma clock,
> the system has to enable the clock chain and it's parents ...

And what if you stop using clk_prepare_enable(), and prepare the clock
when the channel is requested and only use clk_enable() in the tx_submit
method?


From b32955 at freescale.com  Thu Oct 18 05:10:46 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 17:10:46 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <20121018085208.GR21164@n2100.arm.linux.org.uk>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3> <507FA595.4020507@freescale.com>
 <20121018085208.GR21164@n2100.arm.linux.org.uk>
Message-ID: <507FC796.7060401@freescale.com>

? 2012?10?18? 16:52, Russell King - ARM Linux ??:
> On Thu, Oct 18, 2012 at 02:45:41PM +0800, Huang Shijie wrote:
>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>> to dmaengine. Can be done in tx_submit callback.
>>> Similarly remove the clock when dma transaction gets completed.
>> I ever thought this method too.
>>
>> But it will become low efficient in the following case:
>>
>>    Assuming the gpmi-nand driver has to read out 1024 pages in one
>> _SINGLE_ read operation.
>> The gpmi-nand will submit the descriptor to dmaengine per page. So with
>> your method,
>> the system will repeat the enable/disable dma clock 1024 time. At every
>> enable/disable dma clock,
>> the system has to enable the clock chain and it's parents ...
> And what if you stop using clk_prepare_enable(), and prepare the clock
> when the channel is requested and only use clk_enable() in the tx_submit
yes. it's a little better.
There is nearly no difference between the clk_prepare_enable() and 
clk_enable() in actually.
the clk_gate2_ops does not have any @->prepare.

thanks
Huang Shijie

> method?
>




From b32955 at freescale.com  Thu Oct 18 05:13:11 2012
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 18 Oct 2012 17:13:11 +0800
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <201210181049.21556.marex@denx.de>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210181016.06782.marex@denx.de> <507FC290.10205@freescale.com>
 <201210181049.21556.marex@denx.de>
Message-ID: <507FC827.40601@freescale.com>

? 2012?10?18? 16:49, Marek Vasut ??:
> Dear Huang Shijie,
>
>> ? 2012?10?18? 16:16, Marek Vasut ??:
>>> So we can't stream data from the chip? About time to adjust the MTD
>>> framework to allow that. Maybe implement a command queue?
>> IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to
>> check the busy status
>> which means we have to stop in the middle, so we can not chain the all
>> the read-pages DMA commands.
> Can the DMA not branch?
it's too complicated to the MTD layer, as well as the gpmi driver.

Best Regards
Huang Shijie




From dedekind1 at gmail.com  Thu Oct 18 05:20:46 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 12:20:46 +0300
Subject: [RESEND PATCH 0/9] mtd_tests cleanup
In-Reply-To: <5075B105.4080701@gmail.com>
References: <5075B105.4080701@gmail.com>
Message-ID: <1350552046.5769.302.camel@sauron.fi.intel.com>

On Wed, 2012-10-10 at 23:01 +0530, Vikram Narayanan wrote:
> This patch series removes the usage of PRINT_PREF and printk's and
> replaces it with pr_{info,err,crit} whichever is applicable.
> 
> Cc: Brian Norris <computersforpeace at gmail.com>
> Cc: Artem Bityutskiy <dedekind1 at gmail.com>

Pushed the series to l2-mtd.git, thanks!

You can send the erase helper patch as well. I think you can put this
helper to mtdcore.c. And I think UBI and JFFS2 and may be mtdswap and
other drivers may reuse it - you can take a look.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/c3c1eef1/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 18 05:23:31 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 12:23:31 +0300
Subject: [PATCH] denali: nand: Fix build break for driver when built as
 a module
In-Reply-To: <1350017169-22166-1-git-send-email-dinguyen@altera.com>
References: <1350017169-22166-1-git-send-email-dinguyen@altera.com>
Message-ID: <1350552211.5769.303.camel@sauron.fi.intel.com>

On Thu, 2012-10-11 at 22:46 -0600, dinguyen at altera.com wrote:
> From: Dinh Nguyen <dinguyen at altera.com>
> 
> Make denali_init and denali_remove accessible when the driver
> is built as a loadable module.
> 
> Signed-off-by: Dinh Nguyen <dinguyen at altera.com>

I've folded this patch into
	"mtd: denali: split the generic driver and PCI layer"

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/7fe17a89/attachment.sig>

From jaswinder.singh at linaro.org  Thu Oct 18 05:29:10 2012
From: jaswinder.singh at linaro.org (Jassi Brar)
Date: Thu, 18 Oct 2012 14:59:10 +0530
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FA595.4020507@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3>
 <507FA595.4020507@freescale.com>
Message-ID: <CAJe_ZhfarH-HpJkEOpH=jY1Gc-UPEyuA4bJ4LSQES7Uyea2BQw@mail.gmail.com>

On 18 October 2012 12:15, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2012?10?18? 14:18, Vinod Koul ??:
>
>> Why cant you do start (prepare clock etc) when you submit the descriptor
>> to dmaengine. Can be done in tx_submit callback.
>> Similarly remove the clock when dma transaction gets completed.
>
> I ever thought this method too.
>
> But it will become low efficient in the following case:
>
>   Assuming the gpmi-nand driver has to read out 1024 pages in one _SINGLE_
> read operation.
> The gpmi-nand will submit the descriptor to dmaengine per page. So with your
> method,
> the system will repeat the enable/disable dma clock 1024 time. At every
> enable/disable dma clock,
> the system has to enable the clock chain and it's parents ...
>
> But with this patch, we only need to enable/disable dma clock one time, just
> at we select the nand chip.
>
If the clock is the dmac's property (not channels'), the toggling
seems too aggressive.
You could try using runtime_suspend/resume for clock
disabling/enabling. How about employing autosuspend with a few ms
delay?


From dedekind1 at gmail.com  Thu Oct 18 05:36:38 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 12:36:38 +0300
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc, gpio
 and ioremap
In-Reply-To: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
References: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
Message-ID: <1350552998.5769.306.camel@sauron.fi.intel.com>

On Sat, 2012-10-13 at 14:06 +0200, Jean-Christophe PLAGNIOL-VILLARD
wrote:
> this will allow to simply the error and remove path
> 
> Cc: linux-mtd at lists.infradead.org
> Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

$:~/git/l2-mtd$ git apply --check ~/tmp/jc.mbox
error: patch failed: drivers/mtd/nand/atmel_nand.c:1420
error: drivers/mtd/nand/atmel_nand.c: patch does not apply

Please, send an l2-mtd.git-based version.

git://git.infradead.org/users/dedekind/l2-mtd-2.6.git

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/eb936f5a/attachment.sig>

From dedekind1 at gmail.com  Thu Oct 18 05:39:37 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 12:39:37 +0300
Subject: [PATCH] Devicetree support for enc28j60 SPI Ethernet chip
In-Reply-To: <507B04AA.1050502@vanka.net>
References: <507B04AA.1050502@vanka.net>
Message-ID: <1350553177.5769.307.camel@sauron.fi.intel.com>

On Sun, 2012-10-14 at 20:30 +0200, Michal Vanka wrote:
> Hi,
> the following patch adds generic openfirmware/devicetree support to 
> enc28j60 driver.
> 
> It also adds support for custom hardware based (FPGA) "interrupt line 
> deasserter" for processors with level triggered interrupts
> (for example Altera Nios2).

Hi, please, re-send with

devicetree-discuss at lists.ozlabs.org

in CC.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/8c987ecb/attachment.sig>

From plagnioj at jcrosoft.com  Thu Oct 18 05:41:49 2012
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 18 Oct 2012 11:41:49 +0200
Subject: [PATCH 1/1] MTD: atmel_nand: use devm_xxx gpio kzalloc, gpio
 and ioremap
In-Reply-To: <1350552998.5769.306.camel@sauron.fi.intel.com>
References: <1350129982-12106-1-git-send-email-plagnioj@jcrosoft.com>
 <1350552998.5769.306.camel@sauron.fi.intel.com>
Message-ID: <20121018094149.GF12801@game.jcrosoft.org>

On 12:36 Thu 18 Oct     , Artem Bityutskiy wrote:
> On Sat, 2012-10-13 at 14:06 +0200, Jean-Christophe PLAGNIOL-VILLARD
> wrote:
> > this will allow to simply the error and remove path
> > 
> > Cc: linux-mtd at lists.infradead.org
> > Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> 
> $:~/git/l2-mtd$ git apply --check ~/tmp/jc.mbox
> error: patch failed: drivers/mtd/nand/atmel_nand.c:1420
> error: drivers/mtd/nand/atmel_nand.c: patch does not apply
> 
> Please, send an l2-mtd.git-based version.
> 
> git://git.infradead.org/users/dedekind/l2-mtd-2.6.git
this will have to be merge after pinctrl

it's ok I'll push it via at91

Best Regards,
J.


From marex at denx.de  Thu Oct 18 06:51:14 2012
From: marex at denx.de (Marek Vasut)
Date: Thu, 18 Oct 2012 12:51:14 +0200
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <507FC827.40601@freescale.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210181049.21556.marex@denx.de> <507FC827.40601@freescale.com>
Message-ID: <201210181251.15116.marex@denx.de>

Dear Huang Shijie,

> ? 2012?10?18? 16:49, Marek Vasut ??:
> > Dear Huang Shijie,
> > 
> >> ? 2012?10?18? 16:16, Marek Vasut ??:
> >>> So we can't stream data from the chip? About time to adjust the MTD
> >>> framework to allow that. Maybe implement a command queue?
> >> 
> >> IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to
> >> check the busy status
> >> which means we have to stop in the middle, so we can not chain the all
> >> the read-pages DMA commands.
> > 
> > Can the DMA not branch?
> 
> it's too complicated to the MTD layer, as well as the gpmi driver.

Can you please elaborate ?

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Thu Oct 18 08:26:46 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 18 Oct 2012 15:26:46 +0300
Subject: [PATCH v3] jffs2: Fix lock acquisition order bug in
 jffs2_write_begin
In-Reply-To: <20779914.XYDRY924qZ@linux-fiwg>
References: <20779914.XYDRY924qZ@linux-fiwg>
Message-ID: <1350563206.5769.313.camel@sauron.fi.intel.com>

On Wed, 2012-10-17 at 22:59 +0200, Thomas Betker wrote:
> jffs2_write_begin() first acquires the page lock, then f->sem. This 
> causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first 
> acquires f->sem, then the page lock:

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121018/e377b79b/attachment.sig>

From shijie8 at gmail.com  Thu Oct 18 11:11:15 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Thu, 18 Oct 2012 11:11:15 -0400
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <201210181251.15116.marex@denx.de>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <201210181049.21556.marex@denx.de> <507FC827.40601@freescale.com>
 <201210181251.15116.marex@denx.de>
Message-ID: <CAMiH66HCDLZaxXckQz1bfqscNm2X2480HTr4bFHdJNteDLb=ig@mail.gmail.com>

On Thu, Oct 18, 2012 at 6:51 AM, Marek Vasut <marex at denx.de> wrote:
> Dear Huang Shijie,
>
>> ? 2012?10?18? 16:49, Marek Vasut ??:
>> > Dear Huang Shijie,
>> >
>> >> ? 2012?10?18? 16:16, Marek Vasut ??:
>> >>> So we can't stream data from the chip? About time to adjust the MTD
>> >>> framework to allow that. Maybe implement a command queue?
>> >>
>> >> IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to
>> >> check the busy status
>> >> which means we have to stop in the middle, so we can not chain the all
>> >> the read-pages DMA commands.
>> >
>> > Can the DMA not branch?
>>
>> it's too complicated to the MTD layer, as well as the gpmi driver.
>
> Can you please elaborate ?
could you read the nand spec about how to read a page out with the
READ-PAGE(00-30) command,
and tell me how to make the DMA branch?
I really have no idea about how to make the DMA branch.

thanks
Huang Shijie
.


> Best regards,
> Marek Vasut


From shijie8 at gmail.com  Thu Oct 18 11:18:53 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Thu, 18 Oct 2012 11:18:53 -0400
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <CAJe_ZhfarH-HpJkEOpH=jY1Gc-UPEyuA4bJ4LSQES7Uyea2BQw@mail.gmail.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3>
 <507FA595.4020507@freescale.com>
 <CAJe_ZhfarH-HpJkEOpH=jY1Gc-UPEyuA4bJ4LSQES7Uyea2BQw@mail.gmail.com>
Message-ID: <CAMiH66H=VMEgHFMdEhCTqA5AtVw6iN97-cbwUd86Ghd77OLcWA@mail.gmail.com>

On Thu, Oct 18, 2012 at 5:29 AM, Jassi Brar <jaswinder.singh at linaro.org> wrote:
> On 18 October 2012 12:15, Huang Shijie <b32955 at freescale.com> wrote:
>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>
>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>> to dmaengine. Can be done in tx_submit callback.
>>> Similarly remove the clock when dma transaction gets completed.
>>
>> I ever thought this method too.
>>
>> But it will become low efficient in the following case:
>>
>>   Assuming the gpmi-nand driver has to read out 1024 pages in one _SINGLE_
>> read operation.
>> The gpmi-nand will submit the descriptor to dmaengine per page. So with your
>> method,
>> the system will repeat the enable/disable dma clock 1024 time. At every
>> enable/disable dma clock,
>> the system has to enable the clock chain and it's parents ...
>>
>> But with this patch, we only need to enable/disable dma clock one time, just
>> at we select the nand chip.
>>
> If the clock is the dmac's property (not channels'), the toggling
> seems too aggressive.
> You could try using runtime_suspend/resume for clock
> disabling/enabling. How about employing autosuspend with a few ms
> delay?

Yes, employing the autosuspend is workable method too.o
But it's a little more complicated then this patch. You have to create
a thread or workqueue to
do the job.

What's more, I think other DMA engine may also meets the same issue as
the mxs-dma, such as the imx-sdma.
It's somehow a common issue to disable the clocks when no one use the
DMA engine.
Do you also suggest employing the autosuspend? Why not use a simple
way to handle this issue?
When the dma device want to use a DMA engine, it just needs to issue a
DMA_START command.

thanks
Huang Shijie
Huang Shijie


From jaswinder.singh at linaro.org  Thu Oct 18 11:25:30 2012
From: jaswinder.singh at linaro.org (Jassi Brar)
Date: Thu, 18 Oct 2012 20:55:30 +0530
Subject: [PATCH] dma: add new DMA control commands
In-Reply-To: <CAMiH66H=VMEgHFMdEhCTqA5AtVw6iN97-cbwUd86Ghd77OLcWA@mail.gmail.com>
References: <1350538335-29026-1-git-send-email-b32955@freescale.com>
 <1350541111.5263.3.camel@vkoul-udesk3>
 <507FA595.4020507@freescale.com>
 <CAJe_ZhfarH-HpJkEOpH=jY1Gc-UPEyuA4bJ4LSQES7Uyea2BQw@mail.gmail.com>
 <CAMiH66H=VMEgHFMdEhCTqA5AtVw6iN97-cbwUd86Ghd77OLcWA@mail.gmail.com>
Message-ID: <CAJe_ZheWd3scXDhWukeZMuOOz8+bZRwZOw_ftDW8wmkqq9H45Q@mail.gmail.com>

On 18 October 2012 20:48, Huang Shijie <shijie8 at gmail.com> wrote:
> On Thu, Oct 18, 2012 at 5:29 AM, Jassi Brar <jaswinder.singh at linaro.org> wrote:
>> On 18 October 2012 12:15, Huang Shijie <b32955 at freescale.com> wrote:
>>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>>
>>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>>> to dmaengine. Can be done in tx_submit callback.
>>>> Similarly remove the clock when dma transaction gets completed.
>>>
>>> I ever thought this method too.
>>>
>>> But it will become low efficient in the following case:
>>>
>>>   Assuming the gpmi-nand driver has to read out 1024 pages in one _SINGLE_
>>> read operation.
>>> The gpmi-nand will submit the descriptor to dmaengine per page. So with your
>>> method,
>>> the system will repeat the enable/disable dma clock 1024 time. At every
>>> enable/disable dma clock,
>>> the system has to enable the clock chain and it's parents ...
>>>
>>> But with this patch, we only need to enable/disable dma clock one time, just
>>> at we select the nand chip.
>>>
>> If the clock is the dmac's property (not channels'), the toggling
>> seems too aggressive.
>> You could try using runtime_suspend/resume for clock
>> disabling/enabling. How about employing autosuspend with a few ms
>> delay?
>
> Yes, employing the autosuspend is workable method too.o
> But it's a little more complicated then this patch. You have to create
> a thread or workqueue to
> do the job.
>
I am not sure why you would need to create any thread/workqueue ?
Just pm_runtime_put_autosuspend() in drivers/ to see how it works.


From loanhouse at london.com  Thu Oct 18 08:36:10 2012
From: loanhouse at london.com (First Trust Capital Group Plc)
Date: Thu, 18 Oct 2012 14:36:10 +0200
Subject: Does your business/project need
Message-ID: <mailman.26.1350580022.1458.linux-mtd@lists.infradead.org>

RE: PROJECT FUNDING.

Hi There,

Does your business/project need a FAST EASY injection of capital at reasonable rates? Do it right the first time with our financing solutions specialists.

At First Trust Capital Group Plc brokerage firm, we have access to a combined International pool of nearly Half a Trillion in available Liquidity and if you have the right project, we have the right funding. We obtain financial commitments for loans, project funding, proof of funds, bank guarantees, letters of credit, standby letters of credit, collateral enhancements, credit enhancements, and funds for charities and non-profit organisations from domestic and international lending institutions which we would have approved for individuals, businesses, governments, corporations, and organisations.

These days everybody seems to have a project in need of funding but very few actually possess great intentions and innovative ideas. We only accept projects that we feel confident we can get funded and applications are obtained, reviewed and chosen selectively through this Invitation Only Proposal.

We invite you to take this opportunity of an unbeatable fast easy program and if we accept your project, it will be because we think it has merit and stands a good chance of funding. You will need to ensure you have all the necessary documentation (Business Plan, Executive Summary and what have you) to support your application. Once your application and supporting material is submitted, you will be contacted for any clarifications or questions that will assist us in providing you the best financing the market has to offer.

It is our primary objective to work with you and for you in a spirit of cooperation and direct communication to make this painless and a ?no surprises? and ?no delays? experience!

You are advised to act now and submit your application for Commitment today however choosing not to act is a choice in itself but can cost you and your project dearly. Remember fortune smiles on those who act at the right place, right time and right now. We value quality over quantity and time is always of the essence.

For more information about this opportunity of funding, please call during office hours or send a fax or email.
We will be happy to serve you.

Thank you.
Sincerely,
Margaret Richmond (Ms),
First Trust Capital Group Plc,
40, Bank Street, Poplar, London,
E14 5DS, United Kingdom.

Please consider the environment before printing this email.
******************* DISCLAIMER *******************
P.S. This is strictly on the guidelines of CAN-SPAM act of 2003. We have clearly mentioned the source mail-id of this mail,also clearly mentioned the subject lines and they are in no way misleading in any form. We have found your mail address through our own efforts on the web search and not through any un-authentic way. If you find this mail unsolicited, please reply with "Remove" in the subject line and we will take care that you do not receive any further mail from us.
This message contains confidential information and is intended only for the recipient. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately if you have received this e-mail by mistake and delete this e-mail from your system.


From vikram186 at gmail.com  Thu Oct 18 14:29:00 2012
From: vikram186 at gmail.com (Vikram Narayanan)
Date: Thu, 18 Oct 2012 23:59:00 +0530
Subject: [RESEND PATCH 0/9] mtd_tests cleanup
In-Reply-To: <1350552046.5769.302.camel@sauron.fi.intel.com>
References: <5075B105.4080701@gmail.com>
 <1350552046.5769.302.camel@sauron.fi.intel.com>
Message-ID: <50804A6C.8010609@gmail.com>

On 10/18/2012 2:50 PM, Artem Bityutskiy wrote:
> On Wed, 2012-10-10 at 23:01 +0530, Vikram Narayanan wrote:
>> This patch series removes the usage of PRINT_PREF and printk's and
>> replaces it with pr_{info,err,crit} whichever is applicable.
>>
>> Cc: Brian Norris<computersforpeace at gmail.com>
>> Cc: Artem Bityutskiy<dedekind1 at gmail.com>
>
> Pushed the series to l2-mtd.git, thanks!

Thanks Artem. Can you please make Brian Norris as the author for the 
last patch? i.e., mtd: mtd_oobtest: printk -> pr_{info,err,crit}

I forgot to post the patch with the original headers. But I've reposted 
it a few days back. Sorry about that.

> You can send the erase helper patch as well. I think you can put this
> helper to mtdcore.c. And I think UBI and JFFS2 and may be mtdswap and
> other drivers may reuse it - you can take a look.
>

Yeah, Sure. I need to grep into the sources to find the users of it. 
I'll post it soon.

Thanks,
Vikram


From opl127 at freemail.ru  Thu Oct 18 15:42:33 2012
From: opl127 at freemail.ru (=?windows-1251?B?dHJ1ZWJvYXJkLnJ1?=)
Date: Thu, 18 Oct 2012 23:42:33 +0400
Subject: =?windows-1251?B?xO7x6uAg4eXx7+vg8u379SDu4fr/4uvl7ejpIPEgyuDy4Ovu4+7sIM7w4+Dt6Ofg9ujp?=
Message-ID: <uWFWwFbzj5Y5pahl6SSoQajFTXtS0DHPlVOGvvH6Ac5M@freemail.ru>

?????????? ???? ?????????? ????????? ?? ????? ????? ?????????? ? ? ???????? ??????????? trueboard.ru, ??? ??????? ??? ????? ??? ????? ??????????? ????????????? ???????????????? ???? ?????? ??? ?????? ? ???? ?????????????? ???????? ? ????? ????? ?????????? ? ????????? ?????????? ? ??? ?? ???????? ??????????? .
 ????? ???? ???? ? ??? ???? ????, ?????????? ?? ??? ??? ???????? (?? ?????? "??????") ? ?? ???????? VIP ?????????? ?????????!



www.trueboard.ru




From dedekind1 at gmail.com  Fri Oct 19 01:57:12 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 19 Oct 2012 08:57:12 +0300
Subject: [PATCH v2 0/2] Add DMA and device tree support to the flash
 controller FLCTL
In-Reply-To: <CABYn4szACuH3LQ193VJj6E=J4q4Ye4E4O6cUgjB8jmQK6RRmpA@mail.gmail.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
 <1350473030.5769.137.camel@sauron.fi.intel.com>
 <CABYn4szACuH3LQ193VJj6E=J4q4Ye4E4O6cUgjB8jmQK6RRmpA@mail.gmail.com>
Message-ID: <1350626232.5769.318.camel@sauron.fi.intel.com>

On Wed, 2012-10-17 at 15:05 +0200, Bastian Hecht wrote:
> Hi Artem,
> 
> > Hi, I used to be able to compile MTD stuff for mackerel board with the
> > defconfig attached, but now it fails with 3.7-rc1 with as error:
> >
> > /tmp/cc2Nr7AN.s: Error: bad immediate value for 8-bit offset (1024)
> >
> > It fails for dogc4.c, but if I disable DOCG4, it fails for other drivers
> > with a similar error.
> >
> > I've tried (arm) gcc 4.6.3 and the latest Linaro 4.7 build.
> >
> > Any idea? I did not dig this, is this a known issue? Could you try to
> > reproduce this in your setup?
> >
> 
> I can reproduce the error with the following output:
> /tmp/ccYAbker.s: Assembler messages:
> /tmp/ccYAbker.s: Error: bad immediate value for 8-bit offset (2048)
> make[3]: *** [drivers/mtd/nand/docg4.o] Error 1
> 
> The compiler version is: gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
> I usually use: gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202) and
> can compile things without problems.

Yeah, a bug report would be great. I've switched to 4.4.1 and checked
your patches with aiaiai:

--------------------------------------------------------------------------------

Successfully built configuration "arm-mackerel_defconfig,arm,arm-none-linux-gnueabi-", results:

--- before_patching.log
+++ after_patching.log
@@ @@
+drivers/mtd/nand/sh_flctl.c:1142 flctl_probe() warn: 'irq' was not released on error [smatch]
+drivers/mtd/nand/sh_flctl.c:1142:2-8: ERROR: missing iounmap; ioremap on line 1117 and execution via conditional on line 1140 [coccinelle]
+drivers/mtd/nand/sh_flctl.c:164:25: warning: cast removes address space of expression [sparse]
+drivers/mtd/nand/sh_flctl.c:181:25: warning: cast removes address space of expression [sparse]
-drivers/mtd/nand/sh_flctl.c:311 write_fiforeg() Error invalid range 4096 to -1 [smatch]
-drivers/mtd/nand/sh_flctl.c:317:17: warning: incorrect type in argument 2 (different address spaces) [sparse]
-drivers/mtd/nand/sh_flctl.c:317:17:    expected void volatile [noderef] <asn:2>*addr [sparse]
-drivers/mtd/nand/sh_flctl.c:317:17:    got void *fifo_addr [sparse]
+drivers/mtd/nand/sh_flctl.c:469 write_fiforeg() Error invalid range 4096 to -1 [smatch]
+drivers/mtd/nand/sh_flctl.c:485:17: warning: incorrect type in argument 2 (different address spaces) [sparse]
+drivers/mtd/nand/sh_flctl.c:485:17:    expected void volatile [noderef] <asn:2>*addr [sparse]
+drivers/mtd/nand/sh_flctl.c:485:17:    got void *fifo_addr [sparse]

--------------------------------------------------------------------------------


Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121019/e8f29d12/attachment.sig>

From hechtb at googlemail.com  Fri Oct 19 06:05:09 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Fri, 19 Oct 2012 12:05:09 +0200
Subject: [PATCH v2 0/2] Add DMA and device tree support to the flash
 controller FLCTL
In-Reply-To: <1350626232.5769.318.camel@sauron.fi.intel.com>
References: <1349776729-9311-1-git-send-email-hechtb@gmail.com>
 <1350473030.5769.137.camel@sauron.fi.intel.com>
 <CABYn4szACuH3LQ193VJj6E=J4q4Ye4E4O6cUgjB8jmQK6RRmpA@mail.gmail.com>
 <1350626232.5769.318.camel@sauron.fi.intel.com>
Message-ID: <CABYn4swnc5xT=gOCHk5wzQTHWe8TNOE5_o2A36xEgPSnDosSBQ@mail.gmail.com>

Hey Artem,

>> I can reproduce the error with the following output:
>> /tmp/ccYAbker.s: Assembler messages:
>> /tmp/ccYAbker.s: Error: bad immediate value for 8-bit offset (2048)
>> make[3]: *** [drivers/mtd/nand/docg4.o] Error 1
>>
>> The compiler version is: gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
>> I usually use: gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202) and
>> can compile things without problems.
>
> Yeah, a bug report would be great. I've switched to 4.4.1 and checked
> your patches with aiaiai:

Ok I'll file one.

I've added a cleanup patch 1/3 and tackled the problems below as follows:

> --------------------------------------------------------------------------------
>
> Successfully built configuration "arm-mackerel_defconfig,arm,arm-none-linux-gnueabi-", results:
>
> --- before_patching.log
> +++ after_patching.log
> @@ @@
> +drivers/mtd/nand/sh_flctl.c:1142 flctl_probe() warn: 'irq' was not released on error [smatch]
> +drivers/mtd/nand/sh_flctl.c:1142:2-8: ERROR: missing iounmap; ioremap on line 1117 and execution via conditional on line 1140 [coccinelle]

Oh yes, my bad. Fixed in patch 3 (formerly 2).

> +drivers/mtd/nand/sh_flctl.c:164:25: warning: cast removes address space of expression [sparse]
> +drivers/mtd/nand/sh_flctl.c:181:25: warning: cast removes address space of expression [sparse]

Here I have no idea how to fix it. dma_addr_t is a typedef to u32. How
could I possibly not loose the address space?

> -drivers/mtd/nand/sh_flctl.c:311 write_fiforeg() Error invalid range 4096 to -1 [smatch]

Here my smatch (git head version) doesn't complain. Still I switched
to unsigned int for indexing an array member and hope this solves the
problem. Done in new patch 1/3.

> -drivers/mtd/nand/sh_flctl.c:317:17: warning: incorrect type in argument 2 (different address spaces) [sparse]
> -drivers/mtd/nand/sh_flctl.c:317:17:    expected void volatile [noderef] <asn:2>*addr [sparse]
> -drivers/mtd/nand/sh_flctl.c:317:17:    got void *fifo_addr [sparse]

Fixed in new patch 1/3.

> +drivers/mtd/nand/sh_flctl.c:469 write_fiforeg() Error invalid range 4096 to -1 [smatch]

Same as above. Unclear how to solve.

> +drivers/mtd/nand/sh_flctl.c:485:17: warning: incorrect type in argument 2 (different address spaces) [sparse]
> +drivers/mtd/nand/sh_flctl.c:485:17:    expected void volatile [noderef] <asn:2>*addr [sparse]
> +drivers/mtd/nand/sh_flctl.c:485:17:    got void *fifo_addr [sparse]

Fixed in patch 1/3.

Thanks for checking, I'll send out the new patch series in a moment,

Bastian


From hechtb at googlemail.com  Fri Oct 19 06:15:33 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Fri, 19 Oct 2012 12:15:33 +0200
Subject: [PATCH v3 0/3] Add DMA and device tree support to the flash
 controller FLCTL
Message-ID: <1350641736-18192-1-git-send-email-hechtb@gmail.com>

changelog v3:	- due to shame on me by letting aiaiai complain, I've added
		  a third patch (1/3) that cleans up some parts of the driver
		  and added a correct error path to probe() in patch 3 (formerly 2/2).
		  I found no way to fix this though:
+drivers/mtd/nand/sh_flctl.c:181:25: warning: cast removes address space of expression [sparse]
		
changelog v2: 	- cosmetic fixes in patch 1
		- added dmas and dma-names field in patch 2

This mini-series consists of 2 separately posted patch-sets that shrunk
to one patch each. It adds DMA support for the data part (not ECC) as
well as device tree support to the FLCTL flash controller.
As the 2nd patch is based on the 1st, I've decided to
collect them here to avoid any confusion.

The first set contained
[PATCH 1/2] mtd: sh_flctl: Setup and release DMA channels
[PATCH 2/2] mtd: sh_flctl: Use DMA for data fifo FLTDFIFO when available
and was merged after 2 reviews to
[PATCH] mtd: sh_flctl: Add DMA capabilty (same patch as in here)

The second set contained
[PATCH 1/3] mtd: sh_flctl: Probe SNAND_E flag from NAND chip
[PATCH 2/3] mtd: sh_flctl: Add device tree support
[PATCH 3/3] mtd: sh_flctl: Add sh7372 device tree config
and is merged here to
mtd: sh_flctl: Add device tree support

Patch 1 can be omitted as SNAND_E is handled in the FLCTL source anyway
correctly in set_cmd_regs() and the flag can be removed from existing board
codes without this patch.
Patch 2 without patch 3 may be confusing so I merged them too. Documentation
is added as well.

I've added linux-arm-kernel at lists.infradead.org as recipient for the
device tree part.

The patchset is based on
l2-mtd	git://git.infradead.org/users/dedekind/l2-mtd.git
with reverted commit e26c113b4130aefa1d8446602bb5b05cfd646bfe.


Bastian Hecht (2):
  mtd: sh_flctl: Add DMA capabilty
  mtd: sh_flctl: Add device tree support

 .../devicetree/bindings/mtd/flctl-nand.txt         |   37 +++
 drivers/mtd/nand/sh_flctl.c                        |  266 +++++++++++++++++++-
 include/linux/mtd/sh_flctl.h                       |   12 +
 3 files changed, 305 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

-- 
1.7.5.4



From hechtb at googlemail.com  Fri Oct 19 06:15:34 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Fri, 19 Oct 2012 12:15:34 +0200
Subject: [PATCH v3 1/3] mtd: sh_flctl: Minor cleanups
In-Reply-To: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
References: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
Message-ID: <1350641736-18192-2-git-send-email-hechtb@gmail.com>

Some small fixes to avoid sparse and smatch complain. Other cosmetic fixes
as well.

- Change of the type of the member index in struct sh_flctl from signed
to unsigned. We use index by addressing array members, so unsigned is more
concise here. Adapt functions relying on sh_flctl::index.
- Remove a blurring cast in write_fiforeg().
- Apply consistent naming scheme when refering to the data buffer.
- Shorten some unnecessarily verbose functions.
- Remove spaces at start of lines.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
---
v3: This is a newly added patch (v3 is misleading here) in reaction to the
aiaiai output of Artem. My smatch (git head) didn't complain about the
range problem mentioned in Artem's comment of v2 but I thought switching
to unsigned int can't hurt here and seems more clean.

 drivers/mtd/nand/sh_flctl.c  |   37 ++++++++++++++++---------------------
 include/linux/mtd/sh_flctl.h |    2 +-
 2 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 4fbfe96..78d18c0f 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -225,7 +225,7 @@ static enum flctl_ecc_res_t wait_recfifo_ready
 
 		for (i = 0; i < 3; i++) {
 			uint8_t org;
-			int index;
+			unsigned int index;
 
 			data = readl(ecc_reg[i]);
 
@@ -305,28 +305,29 @@ static enum flctl_ecc_res_t read_ecfiforeg
 	return res;
 }
 
-static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+static void write_fiforeg(struct sh_flctl *flctl, int rlen,
+						unsigned int offset)
 {
 	int i, len_4align;
-	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
-	void *fifo_addr = (void *)FLDTFIFO(flctl);
+	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 
 	len_4align = (rlen + 3) / 4;
 	for (i = 0; i < len_4align; i++) {
 		wait_wfifo_ready(flctl);
-		writel(cpu_to_be32(data[i]), fifo_addr);
+		writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl));
 	}
 }
 
-static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
+						unsigned int offset)
 {
 	int i, len_4align;
-	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 
 	len_4align = (rlen + 3) / 4;
 	for (i = 0; i < len_4align; i++) {
 		wait_wecfifo_ready(flctl);
-		writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
+		writel(cpu_to_be32(buf[i]), FLECFIFO(flctl));
 	}
 }
 
@@ -748,41 +749,35 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
 static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	int index = flctl->index;
 
-	memcpy(&flctl->done_buff[index], buf, len);
+	memcpy(&flctl->done_buff[flctl->index], buf, len);
 	flctl->index += len;
 }
 
 static uint8_t flctl_read_byte(struct mtd_info *mtd)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	int index = flctl->index;
 	uint8_t data;
 
-	data = flctl->done_buff[index];
+	data = flctl->done_buff[flctl->index];
 	flctl->index++;
 	return data;
 }
 
 static uint16_t flctl_read_word(struct mtd_info *mtd)
 {
-       struct sh_flctl *flctl = mtd_to_flctl(mtd);
-       int index = flctl->index;
-       uint16_t data;
-       uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
+	struct sh_flctl *flctl = mtd_to_flctl(mtd);
+	uint16_t *buf = (uint16_t *)&flctl->done_buff[flctl->index];
 
-       data = *buf;
-       flctl->index += 2;
-       return data;
+	flctl->index += 2;
+	return *buf;
 }
 
 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	int index = flctl->index;
 
-	memcpy(buf, &flctl->done_buff[index], len);
+	memcpy(buf, &flctl->done_buff[flctl->index], len);
 	flctl->index += len;
 }
 
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 01e4b15..4815576 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -147,7 +147,7 @@ struct sh_flctl {
 
 	uint8_t	done_buff[2048 + 64];	/* max size 2048 + 64 */
 	int	read_bytes;
-	int	index;
+	unsigned int index;
 	int	seqin_column;		/* column in SEQIN cmd */
 	int	seqin_page_addr;	/* page_addr in SEQIN cmd */
 	uint32_t seqin_read_cmd;		/* read cmd in SEQIN cmd */
-- 
1.7.9.5



From hechtb at googlemail.com  Fri Oct 19 06:15:35 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Fri, 19 Oct 2012 12:15:35 +0200
Subject: [PATCH v3 2/3] mtd: sh_flctl: Add DMA capabilty
In-Reply-To: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
References: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
Message-ID: <1350641736-18192-3-git-send-email-hechtb@gmail.com>

The code probes if DMA channels can get allocated and tears them down at
removal/failure if needed.
If available it uses them to transfer the data part (not ECC). On
failure we fall back to PIO mode.

Based on Guennadi Liakhovetski's code from the sh_mmcif driver.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
Reviewed-by: Guennadi Liakhovetski <g.liakhovetski at gmx.de>
---
v3: no changes. I don't know if the error

	warning: cast removes address space of expression [sparse]

because of line

	+       cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl);

can be fixed. dma_addr_t is loosly defined as u32 and I see no way how to make
a proper conversion.

 drivers/mtd/nand/sh_flctl.c  |  173 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/mtd/sh_flctl.h |   12 +++
 2 files changed, 183 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 78d18c0f..6dc0369 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -23,11 +23,15 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
@@ -106,6 +110,84 @@ static void wait_completion(struct sh_flctl *flctl)
 	writeb(0x0, FLTRCR(flctl));
 }
 
+static void flctl_dma_complete(void *param)
+{
+	struct sh_flctl *flctl = param;
+
+	complete(&flctl->dma_complete);
+}
+
+static void flctl_release_dma(struct sh_flctl *flctl)
+{
+	if (flctl->chan_fifo0_rx) {
+		dma_release_channel(flctl->chan_fifo0_rx);
+		flctl->chan_fifo0_rx = NULL;
+	}
+	if (flctl->chan_fifo0_tx) {
+		dma_release_channel(flctl->chan_fifo0_tx);
+		flctl->chan_fifo0_tx = NULL;
+	}
+}
+
+static void flctl_setup_dma(struct sh_flctl *flctl)
+{
+	dma_cap_mask_t mask;
+	struct dma_slave_config cfg;
+	struct platform_device *pdev = flctl->pdev;
+	struct sh_flctl_platform_data *pdata = pdev->dev.platform_data;
+	int ret;
+
+	if (!pdata)
+		return;
+
+	if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0)
+		return;
+
+	/* We can only either use DMA for both Tx and Rx or not use it at all */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_tx);
+	dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__,
+		flctl->chan_fifo0_tx);
+
+	if (!flctl->chan_fifo0_tx)
+		return;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.slave_id = pdata->slave_id_fifo0_tx;
+	cfg.direction = DMA_MEM_TO_DEV;
+	cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl);
+	cfg.src_addr = 0;
+	ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter,
+					    (void *)pdata->slave_id_fifo0_rx);
+	dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__,
+		flctl->chan_fifo0_rx);
+
+	if (!flctl->chan_fifo0_rx)
+		goto err;
+
+	cfg.slave_id = pdata->slave_id_fifo0_rx;
+	cfg.direction = DMA_DEV_TO_MEM;
+	cfg.dst_addr = 0;
+	cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl);
+	ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg);
+	if (ret < 0)
+		goto err;
+
+	init_completion(&flctl->dma_complete);
+
+	return;
+
+err:
+	flctl_release_dma(flctl);
+}
+
 static void set_addr(struct mtd_info *mtd, int column, int page_addr)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -261,6 +343,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl)
 	timeout_error(flctl, __func__);
 }
 
+static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
+					int len, enum dma_data_direction dir)
+{
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct dma_chan *chan;
+	enum dma_transfer_direction tr_dir;
+	dma_addr_t dma_addr;
+	dma_cookie_t cookie = -EINVAL;
+	uint32_t reg;
+	int ret;
+
+	if (dir == DMA_FROM_DEVICE) {
+		chan = flctl->chan_fifo0_rx;
+		tr_dir = DMA_DEV_TO_MEM;
+	} else {
+		chan = flctl->chan_fifo0_tx;
+		tr_dir = DMA_MEM_TO_DEV;
+	}
+
+	dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
+
+	if (dma_addr)
+		desc = dmaengine_prep_slave_single(chan, dma_addr, len,
+			tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+	if (desc) {
+		reg = readl(FLINTDMACR(flctl));
+		reg |= DREQ0EN;
+		writel(reg, FLINTDMACR(flctl));
+
+		desc->callback = flctl_dma_complete;
+		desc->callback_param = flctl;
+		cookie = dmaengine_submit(desc);
+
+		dma_async_issue_pending(chan);
+	} else {
+		/* DMA failed, fall back to PIO */
+		flctl_release_dma(flctl);
+		dev_warn(&flctl->pdev->dev,
+			 "DMA failed, falling back to PIO\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	ret =
+	wait_for_completion_timeout(&flctl->dma_complete,
+				msecs_to_jiffies(3000));
+
+	if (ret <= 0) {
+		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+		dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
+	}
+
+out:
+	reg = readl(FLINTDMACR(flctl));
+	reg &= ~DREQ0EN;
+	writel(reg, FLINTDMACR(flctl));
+
+	dma_unmap_single(chan->device->dev, dma_addr, len, dir);
+
+	/* ret > 0 is success */
+	return ret;
+}
+
 static void read_datareg(struct sh_flctl *flctl, int offset)
 {
 	unsigned long data;
@@ -279,11 +425,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 
 	len_4align = (rlen + 3) / 4;
 
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_rx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0)
+			goto convert;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_rfifo_ready(flctl);
 		buf[i] = readl(FLDTFIFO(flctl));
-		buf[i] = be32_to_cpu(buf[i]);
 	}
+
+convert:
+	for (i = 0; i < len_4align; i++)
+		buf[i] = be32_to_cpu(buf[i]);
 }
 
 static enum flctl_ecc_res_t read_ecfiforeg
@@ -325,9 +480,19 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
 	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
 
 	len_4align = (rlen + 3) / 4;
+
+	for (i = 0; i < len_4align; i++)
+		buf[i] = cpu_to_be32(buf[i]);
+
+	/* initiate DMA transfer */
+	if (flctl->chan_fifo0_tx && rlen >= 32 &&
+		flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0)
+			return;	/* DMA success */
+
+	/* do polling transfer */
 	for (i = 0; i < len_4align; i++) {
 		wait_wecfifo_ready(flctl);
-		writel(cpu_to_be32(buf[i]), FLECFIFO(flctl));
+		writel(buf[i], FLECFIFO(flctl));
 	}
 }
 
@@ -925,6 +1090,8 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_resume(&pdev->dev);
 
+	flctl_setup_dma(flctl);
+
 	ret = nand_scan_ident(flctl_mtd, 1, NULL);
 	if (ret)
 		goto err_chip;
@@ -942,6 +1109,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	return 0;
 
 err_chip:
+	flctl_release_dma(flctl);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(irq, flctl);
 err_flste:
@@ -955,6 +1123,7 @@ static int __devexit flctl_remove(struct platform_device *pdev)
 {
 	struct sh_flctl *flctl = platform_get_drvdata(pdev);
 
+	flctl_release_dma(flctl);
 	nand_release(&flctl->mtd);
 	pm_runtime_disable(&pdev->dev);
 	free_irq(platform_get_irq(pdev, 0), flctl);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 4815576..1c28f88 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -20,6 +20,7 @@
 #ifndef __SH_FLCTL_H__
 #define __SH_FLCTL_H__
 
+#include <linux/completion.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
@@ -107,6 +108,7 @@
 #define ESTERINTE	(0x1 << 24)	/* ECC error interrupt enable */
 #define AC1CLR		(0x1 << 19)	/* ECC FIFO clear */
 #define AC0CLR		(0x1 << 18)	/* Data FIFO clear */
+#define DREQ0EN		(0x1 << 16)	/* FLDTFIFODMA Request Enable */
 #define ECERB		(0x1 << 9)	/* ECC error */
 #define STERB		(0x1 << 8)	/* Status error */
 #define STERINTE	(0x1 << 4)	/* Status error enable */
@@ -138,6 +140,8 @@ enum flctl_ecc_res_t {
 	FL_TIMEOUT
 };
 
+struct dma_chan;
+
 struct sh_flctl {
 	struct mtd_info		mtd;
 	struct nand_chip	chip;
@@ -161,6 +165,11 @@ struct sh_flctl {
 	unsigned hwecc:1;	/* Hardware ECC (0 = disabled, 1 = enabled) */
 	unsigned holden:1;	/* Hardware has FLHOLDCR and HOLDEN is set */
 	unsigned qos_request:1;	/* QoS request to prevent deep power shutdown */
+
+	/* DMA related objects */
+	struct dma_chan		*chan_fifo0_rx;
+	struct dma_chan		*chan_fifo0_tx;
+	struct completion	dma_complete;
 };
 
 struct sh_flctl_platform_data {
@@ -170,6 +179,9 @@ struct sh_flctl_platform_data {
 
 	unsigned has_hwecc:1;
 	unsigned use_holden:1;
+
+	unsigned int            slave_id_fifo0_tx;
+	unsigned int            slave_id_fifo0_rx;
 };
 
 static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
-- 
1.7.9.5



From hechtb at googlemail.com  Fri Oct 19 06:15:36 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Fri, 19 Oct 2012 12:15:36 +0200
Subject: [PATCH v3 3/3] mtd: sh_flctl: Add device tree support
In-Reply-To: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
References: <1350641736-18192-1-git-send-email-hechtb@gmail.com>
Message-ID: <1350641736-18192-4-git-send-email-hechtb@gmail.com>

The flctl can now be probed via device tree setup in addition to the
existing platform data way.

SoC specific setup data is set in the .data member of the OF match, so
kept within the driver itself, while board/user specific setup - like
partitioning - is taken from the device tree.

Actual configuration is added for the SoC sh7372.

Signed-off-by: Bastian Hecht <hechtb at gmail.com>
---
v3: Now a proper cleanup path is taken in case of a missing platform or
faulty DT config. Fixes coccinelle and smatch errors from Artem's aiaiaia
output.

 .../devicetree/bindings/mtd/flctl-nand.txt         |   49 ++++++++++
 drivers/mtd/nand/sh_flctl.c                        |   94 ++++++++++++++++++--
 2 files changed, 136 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/flctl-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
new file mode 100644
index 0000000..427f46d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/flctl-nand.txt
@@ -0,0 +1,49 @@
+FLCTL NAND controller
+
+Required properties:
+- compatible : "renesas,shmobile-flctl-sh7372"
+- reg : Address range of the FLCTL
+- interrupts : flste IRQ number
+- nand-bus-width : bus width to NAND chip
+
+Optional properties:
+- dmas: DMA specifier(s)
+- dma-names: name for each DMA specifier. Valid names are
+	     "data_tx", "data_rx", "ecc_tx", "ecc_rx"
+
+The DMA fields are not used yet in the driver but are listed here for
+completing the bindings.
+
+The device tree may optionally contain sub-nodes describing partitions of the
+address space. See partition.txt for more detail.
+
+Example:
+
+	flctl at e6a30000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "renesas,shmobile-flctl-sh7372";
+		reg = <0xe6a30000 0x100>;
+		interrupts = <0x0d80>;
+
+		nand-bus-width = <16>;
+
+		dmas = <&dmac 1 /* data_tx */
+			&dmac 2;> /* data_rx */
+		dma-names = "data_tx", "data_rx";
+
+		system at 0 {
+			label = "system";
+			reg = <0x0 0x8000000>;
+		};
+
+		userdata at 8000000 {
+			label = "userdata";
+			reg = <0x8000000 0x10000000>;
+		};
+
+		cache at 18000000 {
+			label = "cache";
+			reg = <0x18000000 0x8000000>;
+		};
+	};
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 6dc0369..d51e3c1 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -29,6 +29,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mtd.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/sh_dma.h>
@@ -1016,6 +1019,73 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+struct flctl_soc_config {
+	unsigned long flcmncr_val;
+	unsigned has_hwecc:1;
+	unsigned use_holden:1;
+};
+
+static struct flctl_soc_config flctl_sh7372_config = {
+	.flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL,
+	.has_hwecc = 1,
+	.use_holden = 1,
+};
+
+static const struct of_device_id of_flctl_match[] = {
+	{ .compatible = "renesas,shmobile-flctl-sh7372",
+				.data = &flctl_sh7372_config },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_flctl_match);
+
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	const struct of_device_id *match;
+	struct flctl_soc_config *config;
+	struct sh_flctl_platform_data *pdata;
+	struct device_node *dn = dev->of_node;
+	int ret;
+
+	match = of_match_device(of_flctl_match, dev);
+	if (match)
+		config = (struct flctl_soc_config *)match->data;
+	else {
+		dev_err(dev, "%s: no OF configuration attached\n", __func__);
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data),
+								GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "%s: failed to allocate config data\n", __func__);
+		return NULL;
+	}
+
+	/* set SoC specific options */
+	pdata->flcmncr_val = config->flcmncr_val;
+	pdata->has_hwecc = config->has_hwecc;
+	pdata->use_holden = config->use_holden;
+
+	/* parse user defined options */
+	ret = of_get_nand_bus_width(dn);
+	if (ret == 16)
+		pdata->flcmncr_val |= SEL_16BIT;
+	else if (ret != 8) {
+		dev_err(dev, "%s: invalid bus width\n", __func__);
+		return NULL;
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+#define of_flctl_match NULL
+static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit flctl_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -1025,12 +1095,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	struct sh_flctl_platform_data *pdata;
 	int ret = -ENXIO;
 	int irq;
-
-	pdata = pdev->dev.platform_data;
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
+	struct mtd_part_parser_data ppdata = {};
 
 	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
 	if (!flctl) {
@@ -1062,6 +1127,17 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 		goto err_flste;
 	}
 
+	if (pdev->dev.of_node)
+		pdata = flctl_parse_dt(&pdev->dev);
+	else
+		pdata = pdev->dev.platform_data;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no setup data defined\n");
+		ret = -EINVAL;
+		goto err_pdata;
+	}
+
 	platform_set_drvdata(pdev, flctl);
 	flctl_mtd = &flctl->mtd;
 	nand = &flctl->chip;
@@ -1104,13 +1180,16 @@ static int __devinit flctl_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_chip;
 
-	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+	ppdata.of_node = pdev->dev.of_node;
+	ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts,
+			pdata->nr_parts);
 
 	return 0;
 
 err_chip:
 	flctl_release_dma(flctl);
 	pm_runtime_disable(&pdev->dev);
+err_pdata:
 	free_irq(irq, flctl);
 err_flste:
 	iounmap(flctl->reg);
@@ -1138,6 +1217,7 @@ static struct platform_driver flctl_driver = {
 	.driver = {
 		.name	= "sh_flctl",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_flctl_match,
 	},
 };
 
-- 
1.7.9.5



From matthieu.castet at parrot.com  Fri Oct 19 11:29:33 2012
From: matthieu.castet at parrot.com (Matthieu CASTET)
Date: Fri, 19 Oct 2012 17:29:33 +0200
Subject: [PATCH] mtdoops : don't erase flash at each boot
Message-ID: <1350660573-6631-1-git-send-email-matthieu.castet@parrot.com>

If there is no oops stored (flash is erased), find_next_position will
exit with maxcount == 0xffffffff and erase the first page.

Only erase it if mark_is_used.

Signed-off-by: Matthieu Castet <matthieu.castet at parrot@com>
---
 drivers/mtd/mtdoops.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index f5b3f91..97bb8f6 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -271,7 +271,7 @@ static void find_next_position(struct mtdoops_context *cxt)
 
 		if (count[0] == 0xffffffff && count[1] == 0xffffffff)
 			mark_page_unused(cxt, page);
-		if (count[0] == 0xffffffff)
+		if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC)
 			continue;
 		if (maxcount == 0xffffffff) {
 			maxcount = count[0];
@@ -289,14 +289,13 @@ static void find_next_position(struct mtdoops_context *cxt)
 		}
 	}
 	if (maxcount == 0xffffffff) {
-		cxt->nextpage = 0;
-		cxt->nextcount = 1;
-		schedule_work(&cxt->work_erase);
-		return;
+		cxt->nextpage = cxt->oops_pages - 1;
+		cxt->nextcount = 0;
+	}
+	else {
+		cxt->nextpage = maxpos;
+		cxt->nextcount = maxcount;
 	}
-
-	cxt->nextpage = maxpos;
-	cxt->nextcount = maxcount;
 
 	mtdoops_inc_counter(cxt);
 }
-- 
1.7.10.4



From w.sang at pengutronix.de  Sat Oct 20 11:12:56 2012
From: w.sang at pengutronix.de (Wolfram Sang)
Date: Sat, 20 Oct 2012 17:12:56 +0200
Subject: [PATCH] ubiformat: really skip some messages when quiet
Message-ID: <1350745976-1774-1-git-send-email-w.sang@pengutronix.de>

Both logic (only print when not quiet) and the indentation suggest that
the braces around the block have been forgotten.

Signed-off-by: Wolfram Sang <w.sang at pengutronix.de>
---
 ubi-utils/ubiformat.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ubi-utils/ubiformat.c b/ubi-utils/ubiformat.c
index a265a9a..8f9bd3a 100644
--- a/ubi-utils/ubiformat.c
+++ b/ubi-utils/ubiformat.c
@@ -875,11 +875,12 @@ int main(int argc, char * const argv[])
 		 * erase counters.
 		 */
 		if (percent < 50) {
-			if (!args.yes || !args.quiet)
+			if (!args.yes || !args.quiet) {
 				warnmsg("only %d of %d eraseblocks have valid erase counter",
 					si->ok_cnt, si->good_cnt);
 				normsg("erase counter 0 will be used for all eraseblocks");
 				normsg("note, arbitrary erase counter value may be specified using -e option");
+			}
 			if (!args.yes && want_exit()) {
 				if (args.yes && !args.quiet)
 					printf("yes\n");
@@ -888,11 +889,12 @@ int main(int argc, char * const argv[])
 			 args.ec = 0;
 			 args.override_ec = 1;
 		} else if (percent < 95) {
-			if (!args.yes || !args.quiet)
+			if (!args.yes || !args.quiet) {
 				warnmsg("only %d of %d eraseblocks have valid erase counter",
 					si->ok_cnt, si->good_cnt);
 				normsg("mean erase counter %lld will be used for the rest of eraseblock",
 				       si->mean_ec);
+			}
 			if (!args.yes && want_exit()) {
 				if (args.yes && !args.quiet)
 					printf("yes\n");
-- 
1.7.10.4



From computersforpeace at gmail.com  Sun Oct 21 03:21:18 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Sun, 21 Oct 2012 00:21:18 -0700
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <1350371511.5769.43.camel@sauron.fi.intel.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
 <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <1350371511.5769.43.camel@sauron.fi.intel.com>
Message-ID: <CAN8TOE9tDbW5QoRnY0wAOPJZqXEO=kdtVkS=BHYAUjebrPq=GA@mail.gmail.com>

On Tue, Oct 16, 2012 at 12:11 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> On Mon, 2012-10-15 at 09:27 -0700, Brian Norris wrote:
>> See the commit description for the following commit in mtd-utils.git:
>>
>>     commit 71c76e74661492b4f68f670514866cfc85f47089
>>     libmtd: fix mtd_write() issues for large data-only writes
>
> Well, this is another work-around.

Yeah, I know it was a workaround. It's another issue of balancing time
and the "best" solution. Of course, the solutions actually don't seem
that difficult now, so I probably should have just fixed the ioctl()
in the first place... But I was simply pointing this out as evidence
of a real memory-fragmentation issue.

> The better way to fix this would be
> to change kernel's 'mtdchar_write_ioctl()' to be iterative and avoid
> calling 'memdup_user(len)' for arbitrary 'len' passed from user-space.

That's one way, but it would require specifying some arbitrary
iteration length, right? Like some multiple of writesize?

Instead, how about modelling it more closely after mtdchar_write(),
using mtd_kmalloc_up_to(), then iteratively call copy_from_user()?

> So I thought about something like introducing an mtd_alloc() which
> would:
>    a. Try doing CMA allocation: dma_alloc_from_contiguous()
>    b. If it fails, use kmalloc().
...
> If both fail - bad luck. Go look at the code and switch to S-G lists
> instead of allocating contiguous regions. As I said, in many places it
> is easy to do, and there are few places when you would need to spend a
> bit more time.
>
> How does this sound to you?

It sounds OK, but that depends on the success rate of
dma_alloc_from_contiguous(). I'm not familiar with it.

Brian


From computersforpeace at gmail.com  Sun Oct 21 03:38:57 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Sun, 21 Oct 2012 00:38:57 -0700
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CACRpkdY2=PLS_MT1h_nQJj+2ju26yXtt-aXSi=t9uUQ5+WJasA@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com>
 <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
 <1350371685.5769.45.camel@sauron.fi.intel.com>
 <CACRpkdY2=PLS_MT1h_nQJj+2ju26yXtt-aXSi=t9uUQ5+WJasA@mail.gmail.com>
Message-ID: <CAN8TOE91TDewmo=w7585sDrsXcPmBnvOjmD7sTizPSJ8RH8_Gg@mail.gmail.com>

On Tue, Oct 16, 2012 at 3:05 AM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Tue, Oct 16, 2012 at 9:14 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
>> On Mon, 2012-10-15 at 21:51 +0200, Linus Walleij wrote:
>>> On Mon, Oct 15, 2012 at 6:27 PM, Brian Norris
>>> <computersforpeace at gmail.com> wrote:
>>>
>>> > I would prefer not building a solution that hopes kmalloc() can get a
>>> > large contiguous buffer (remember, eraseblock sizes come as large as
>>> > 2MB these days). A real solution like CMA or scatter-gather seems like
>>> > a better idea.
>>>
>>> +1 on that, and as I think I illustrated the MMC subsystem is using
>>> the block layer helpers to form scatter-gather lists for it's requests.
>>> I don't see why the MTD subsystem need to be very different?
>>
>> This is good idea, the problem is that it is a bit more work than
>> hacking the driver, so most people prefer the latter. By removing all
>> kmalloc()'s I basically wish to force people to go this way.

Did you mean vmalloc()'s?

>> What are the SC functions names you refer?
>
> I'm mainly thinking of blk_rq_map_sg()
> from block/blk-merge.c

I am also interested in the potential for the S-G approach. I'll see
what kind of work it takes to implement soon, hopefully.

As a side note, my hardware can, in fact, perform scatter-gather DMA.
If we were to support both S-G hardware like mine in addition to
standard, page-at-time access (nand_chip->write_page, for example),
could we introduce a DMA interface to nand_chip? Then this interface
would just be set to NULL for those that can't handle it.

Brian


From dedekind1 at gmail.com  Sun Oct 21 07:00:04 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sun, 21 Oct 2012 14:00:04 +0300
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <CAN8TOE91TDewmo=w7585sDrsXcPmBnvOjmD7sTizPSJ8RH8_Gg@mail.gmail.com>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com> <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
 <1350371685.5769.45.camel@sauron.fi.intel.com>
 <CACRpkdY2=PLS_MT1h_nQJj+2ju26yXtt-aXSi=t9uUQ5+WJasA@mail.gmail.com>
 <CAN8TOE91TDewmo=w7585sDrsXcPmBnvOjmD7sTizPSJ8RH8_Gg@mail.gmail.com>
Message-ID: <1350817204.1704.0.camel@kyv>

On Sun, 2012-10-21 at 00:38 -0700, Brian Norris wrote:
> >> This is good idea, the problem is that it is a bit more work than
> >> hacking the driver, so most people prefer the latter. By removing all
> >> kmalloc()'s I basically wish to force people to go this way.
> 
> Did you mean vmalloc()'s?

Yes.

> 
> >> What are the SC functions names you refer?
> >
> > I'm mainly thinking of blk_rq_map_sg()
> > from block/blk-merge.c

Yeah, may be re-working or extending MTD api with SG lists would be the
way to go, but this is a lot more work...

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121021/243509aa/attachment.sig>

From dedekind1 at gmail.com  Sun Oct 21 08:02:28 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sun, 21 Oct 2012 15:02:28 +0300
Subject: [PATCH 07/11] fsmc/nand: Provide contiguous buffers to dma
In-Reply-To: <1350817204.1704.0.camel@kyv>
References: <cover.1349778820.git.vipin.kumar@st.com>
 <2b88c853b3691338fae037f569917fc300cd6032.1349778821.git.vipin.kumar@st.com>
 <CACRpkdb6ArMUQ6MAsue+Gh15UfOUrWNAc9wrxd6awc0BTwOGiw@mail.gmail.com>
 <CAOh2x=ksMr7VRCnpF-rK+Mesg1p4Td++SQ-t=ShrguRRVWSSSQ@mail.gmail.com>
 <CACRpkdYjA8QUh4HqvE1rsnXcGA4WafTkMq_wLNJ__gXEnEYrow@mail.gmail.com>
 <507794B6.2000107@st.com> <1350307104.4115.23.camel@sauron.fi.intel.com>
 <CAN8TOE-7d=YUSYsHFw9X5vnz8cpSJYv5uZfvBpDyhg+-F_LDiQ@mail.gmail.com>
 <CACRpkdao_9TkH7=ia7kXB-KsQhNZQ7EfSS5B1X0wFPgg5OsuHA@mail.gmail.com>
 <1350371685.5769.45.camel@sauron.fi.intel.com>
 <CACRpkdY2=PLS_MT1h_nQJj+2ju26yXtt-aXSi=t9uUQ5+WJasA@mail.gmail.com>
 <CAN8TOE91TDewmo=w7585sDrsXcPmBnvOjmD7sTizPSJ8RH8_Gg@mail.gmail.com>
 <1350817204.1704.0.camel@kyv>
Message-ID: <1350820948.1704.2.camel@kyv>

On Sun, 2012-10-21 at 14:00 +0300, Artem Bityutskiy wrote:
> > > I'm mainly thinking of blk_rq_map_sg()
> > > from block/blk-merge.c
> 
> Yeah, may be re-working or extending MTD api with SG lists would be the
> way to go, but this is a lot more work...

Sorry, it would be correct to say that re-working MTD API _users_ to
incorporate the SG API would be a lot more work.

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121021/28e3b5cc/attachment.sig>

From mv at vanka.net  Sun Oct 21 12:34:34 2012
From: mv at vanka.net (Michal Vanka)
Date: Sun, 21 Oct 2012 18:34:34 +0200
Subject: [PATCH] Add devicetree support to m25p80 driver
Message-ID: <5084241A.5050801@vanka.net>

The following patch adds support for devicetree to m25p80 driver.
Note that for jedec chips the chip identification was simplified.
The particular chip is identified by jedec_id only.
Tested on custom Altera Nios2 system.

Signed-off-by: Michal Vanka <mv at vanka.net>

diff --git a/Documentation/devicetree/bindings/mtd/m25pxx.txt 
b/Documentation/devicetree/bindings/mtd/m25pxx.txt
index e69de29..c454a5b 100644
--- a/Documentation/devicetree/bindings/mtd/m25pxx.txt
+++ b/Documentation/devicetree/bindings/mtd/m25pxx.txt
@@ -0,0 +1,39 @@
+* M25PXX Serial Flash
+
+Required properties:
+- compatible : For jedec part should be "generic,m25pxx"
+               For non-jedec part should be one of the following:
+		"catalyst,cat25c11"
+		"catalyst,cat25c03"
+		"catalyst,cat25c09"
+		"catalyst,cat25c17"
+		"catalyst,cat25128"
+		"stmicro,m25p05-nonjedec"
+		"stmicro,m25p10-nonjedec"
+		"stmicro,m25p20-nonjedec"
+		"stmicro,m25p40-nonjedec"
+		"stmicro,m25p80-nonjedec"
+		"stmicro,m25p16-nonjedec"
+		"stmicro,m25p32-nonjedec"
+		"stmicro,m25p64-nonjedec"
+		"stmicro,m25p128-nonjedec"
+
+- spi-max-frequency : Maximum operating frequency for the given chip.
+- reg : Chipselect bit number on gpios chipselect port.
+
+Example: S25FL064K hooked to tinyspi controller:
+
+tiny_spi_2: spi at 0x4000 {
+	compatible = "opencores,tiny-spi-1.0", "opencores,tiny-spi-rtlsvn2";
+	reg = < 0x00004000 0x00000020 >;
+	interrupt-parent = < &cpu >;
+	interrupts = < 5 >;
+	clock-frequency = < 100000000 >;
+	baud-width = < 8 >;	/* BAUD_WIDTH type NUMBER */
+	gpios = < &spi2_cs 0 0 >;
+	spansion_flash: m25pxx at 0 {
+		compatible = "generic,m25pxx";
+		spi-max-frequency = < 20000000 >;
+		reg = <0>;
+	};
+};
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5d0d68c..1db2c63 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -744,6 +744,29 @@ static const struct spi_device_id m25p_ids[] = {
  };
  MODULE_DEVICE_TABLE(spi, m25p_ids);

+#ifdef CONFIG_OF
+static const struct of_device_id m25pxx_dt_ids[] = {
+	{ .compatible = "generic,m25pxx", },
+	{ .compatible = "catalyst,cat25c11", },
+	{ .compatible = "catalyst,cat25c03", },
+	{ .compatible = "catalyst,cat25c09", },
+	{ .compatible = "catalyst,cat25c17", },
+	{ .compatible = "catalyst,cat25128", },
+	{ .compatible = "stmicro,m25p05-nonjedec", },
+	{ .compatible = "stmicro,m25p10-nonjedec", },
+	{ .compatible = "stmicro,m25p20-nonjedec", },
+	{ .compatible = "stmicro,m25p40-nonjedec", },
+	{ .compatible = "stmicro,m25p80-nonjedec", },
+	{ .compatible = "stmicro,m25p16-nonjedec", },
+	{ .compatible = "stmicro,m25p32-nonjedec", },
+	{ .compatible = "stmicro,m25p64-nonjedec", },
+	{ .compatible = "stmicro,m25p128-nonjedec", },
+	{ /* sentinel */ }
+};
+#else
+#define m25pxx_dt_ids NULL
+#endif
+
  static const struct spi_device_id *__devinit jedec_probe(struct 
spi_device *spi)
  {
  	int			tmp;
@@ -798,7 +821,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
  	unsigned			i;
  	struct mtd_part_parser_data	ppdata;

-#ifdef CONFIG_MTD_OF_PARTS
+#if defined(CONFIG_MTD_OF_PARTS) || defined(CONFIG_OF)
  	if (!of_device_is_available(spi->dev.of_node))
  		return -ENODEV;
  #endif
@@ -825,27 +848,39 @@ static int __devinit m25p_probe(struct spi_device 
*spi)
  			dev_warn(&spi->dev, "unrecognized id %s\n", data->type);
  	}

-	info = (void *)id->driver_data;
-
-	if (info->jedec_id) {
-		const struct spi_device_id *jid;
-
-		jid = jedec_probe(spi);
-		if (IS_ERR(jid)) {
-			return PTR_ERR(jid);
-		} else if (jid != id) {
-			/*
-			 * JEDEC knows better, so overwrite platform ID. We
-			 * can't trust partitions any longer, but we'll let
-			 * mtd apply them anyway, since some partitions may be
-			 * marked read-only, and we don't want to lose that
-			 * information, even if it's not 100% accurate.
-			 */
-			dev_warn(&spi->dev, "found %s, expected %s\n",
-				 jid->name, id->name);
-			id = jid;
-			info = (void *)jid->driver_data;
+	if (id) {
+		info = (void *)id->driver_data;
+		if (info->jedec_id) {
+			const struct spi_device_id *jid;
+
+			jid = jedec_probe(spi);
+			if (IS_ERR(jid)) {
+				return PTR_ERR(jid);
+			} else if (jid != id) {
+				/*
+				 * JEDEC knows better, so overwrite platform ID.
+				 * We can't trust partitions any longer, but
+				 * we'll let mtd apply them anyway, since some
+				 * partitions may be marked read-only,
+				 * and we don't want to lose that information,
+				 * even if it's not 100% accurate.
+				 */
+				dev_warn(&spi->dev, "found %s, expected %s\n",
+					 jid->name, id->name);
+				id = jid;
+				info = (void *)jid->driver_data;
+			}
  		}
+	} else {
+		/*
+		 * No id -> we have been most likely configured
+		 * by devicetree "generic,m25pxx" record.
+		 */
+		id = jedec_probe(spi);
+		if (IS_ERR(id))
+			return PTR_ERR(id);
+
+		info = (void *)id->driver_data;
  	}

  	flash = kzalloc(sizeof *flash, GFP_KERNEL);
@@ -968,6 +1003,7 @@ static struct spi_driver m25p80_driver = {
  	.driver = {
  		.name	= "m25p80",
  		.owner	= THIS_MODULE,
+		.of_match_table = m25pxx_dt_ids,
  	},
  	.id_table	= m25p_ids,
  	.probe	= m25p_probe,


From bryanhundven at gmail.com  Mon Oct 22 20:40:47 2012
From: bryanhundven at gmail.com (Bryan Hundven)
Date: Mon, 22 Oct 2012 17:40:47 -0700
Subject: mtd: onenand: 8Gb SDP/DDP support
Message-ID: <CAJ+oik26oPY+AwN=LwkM-suW9WddZo09kSZX_4FpxTtH+NttqQ@mail.gmail.com>

Hello list,

Please cc: me, as I am not currently subscribed. Thank you!

I have been looking around for official changes from Samsung for their
8Gb (1GB) flash parts, and find a driver from a samsung phone called:
samsung_audi.c:

https://github.com/arighi/linux-gt-i9100/blob/master/drivers/mtd/onenand/samsung_audi.c

But, I'd rather use something that gets updated regularly by those who
know more about these chips.

I am wondering if there are any plans to support these chips in the
upstream kernel.

Thanks in advance,

-Bryan


From hejianet at linux.vnet.ibm.com  Tue Oct 23 03:13:41 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Tue, 23 Oct 2012 15:13:41 +0800
Subject: jffs2 copy too long after mounting
In-Reply-To: <1345794797.2848.264.camel@sauron.fi.intel.com>
References: <5019EE49.7000208@linux.vnet.ibm.com>
 <1345794797.2848.264.camel@sauron.fi.intel.com>
Message-ID: <508643A5.1020901@linux.vnet.ibm.com>

Hi Artem, thanks for your reply
Now I can reproduce it after 2-3 days stress tests:
1.just do lots of small writing(4k bytes each time) radomly in one of 1000
 thousand file
2.remove the 1000 files,now the jffs2 fs is *very* dirty.
3.I dynamically increase the threshold nr_free_blocks to trigger the gc
in jffs2_thread_should_wake():
     if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
            (dirty > c->nospc_dirty_size))
        ret = 1;
4. I watched after a while, there were tens of  thousands of lines (I enable the
jffs2 log level to be 1)
Check potential deletion dirent at 008ddd24
Check potential deletion dirent at 008ddcf4
Check potential deletion dirent at 008ddcc4
Check potential deletion dirent at 008ddc68
Check potential deletion dirent at 008dca34
Check potential deletion dirent at 008dca04
Check potential deletion dirent at 0088d77c
Check potential deletion dirent at 0088d74c
Check potential deletion dirent at 0088d71c
Check potential deletion dirent at 0088d6ec
Check potential deletion dirent at 0088d6bc
Check potential deletion dirent at 0088c648
Check potential deletion dirent at 0088c618
Check potential deletion dirent at 0088c2a8
Check potential deletion dirent at 0088c278
Check potential deletion dirent at 0088c248
Check potential deletion dirent at 0088c218
Check potential deletion dirent at 0088c1e8
Check potential deletion dirent at 00886b50
Check potential deletion dirent at 00885388
Check potential deletion dirent at 00885358
Check potential deletion dirent at 008852a8
Check potential deletion dirent at 00885278
5. I did find that the free blocks number of jffs2 is very slowly increased

So could you give me any ideas, it is normal or abnormal?
Thanks a lot
On 2012-08-24 15:53, Artem Bityutskiy wrote:
> On Thu, 2012-08-02 at 11:04 +0800, hejianet wrote:
>> hi All
>> my kernel is 2.6.16
>> after mounting the nand flash with jffs2 partition, the first copy operation
>> for a 15M file(from jffs2 partition to jffs2 partition) take 9
>> minutes,but the
>> second copy operation takes 1 minutes.
>> the disk usage(df result) is over 85%.
>> I wonder is there any patch ported to such old kernel?
> His is because how JFFS2 is designed. When the mount operation is
> finished, JFFS2 does not really finish mounting. There is the background
> process which keeps working - it basically reads all files in the system
> and checks the CRC, which is needed to find out which nodes are new and
> which are obsolete.
>
> So what happens is that you mount JFFS2, the background thread keeps
> working (see 'top' for example).
>
> While the background thread works, you can read files. But you cannot
> write - writes will be blocked. Well, it is a bit more complex - you can
> write a little, but from some point your writes will be blocked until
> the background thread finishes. Then the write will continue and finish.
>
> In you case, you mount, start writing your 15MiB file, write gets
> blocked, waits for the background thread, then continues write. The
> background thread takes ages to finish on big partitions.
>
> The second write is fast because you do not wait for the background
> thread any longer.
>




From avinashphilip at ti.com  Tue Oct 23 06:17:55 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Tue, 23 Oct 2012 10:17:55 +0000
Subject: [PATCH 1/4] mtd: nand: omap2: Update nerrors using ecc.strength
In-Reply-To: <87obk3va1j.fsf@macbook.be.48ers.dk>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-2-git-send-email-avinashphilip@ti.com>
 <87obk3va1j.fsf@macbook.be.48ers.dk>
Message-ID: <518397C60809E147AF5323E0420B992E3E9D29BE@DBDE01.ent.ti.com>

On Tue, Oct 16, 2012 at 00:26:40, Peter Korsgaard wrote:
> >>>>> Philip, Avinash <avinashphilip at ti.com> writes:
> 
>  > Update number of errors using nand ecc strength.
>  > Also add macro definitions BCH8_ERROR_MAX & BCH4_ERROR_MAX
> 
>  > Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
>  > ---
>  > :100644 100644 5b31386... af511a9... M	drivers/mtd/nand/omap2.c
>  >  drivers/mtd/nand/omap2.c |   12 ++++++++----
>  >  1 files changed, 8 insertions(+), 4 deletions(-)
> 
>  > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>  > index 5b31386..af511a9 100644
>  > --- a/drivers/mtd/nand/omap2.c
>  > +++ b/drivers/mtd/nand/omap2.c
>  > @@ -111,6 +111,9 @@
>  >  #define	ECCCLEAR			0x100
>  >  #define	ECC1				0x1
>  
>  > +#define BCH8_MAX_ERROR		8	/* upto 8 bit coorectable */
>  > +#define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */
> 
> First 'correctable' misspelled.

I will correct it

> 
> I don't personally think these defines improve readability very much
> compared to to just using 4/8, though.

Thought of removing magic numbers & provide information also.

Thanks
Avinash

> 
> -- 
> Bye, Peter Korsgaard
> 



From avinashphilip at ti.com  Tue Oct 23 06:18:02 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Tue, 23 Oct 2012 10:18:02 +0000
Subject: [PATCH 3/4] ARM: OMAP2: gpmc: Add support for BCH ECC scheme
In-Reply-To: <87vcebvaf5.fsf@macbook.be.48ers.dk>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-4-git-send-email-avinashphilip@ti.com>
 <87vcebvaf5.fsf@macbook.be.48ers.dk>
Message-ID: <518397C60809E147AF5323E0420B992E3E9D29C8@DBDE01.ent.ti.com>

On Tue, Oct 16, 2012 at 00:18:30, Peter Korsgaard wrote:
> >>>>> Philip, Avinash <avinashphilip at ti.com> writes:
> 
>  > Add support for BCH ECC scheme to gpmc driver and also enabling multi
>  > sector read/write. This helps in doing single shot NAND page read and
>  > write.
> 
>  > ECC engine configurations
>  > BCH 4 bit support
>  > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
>  > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
>  > 13 and ecc_size1 as 1.
> 
>  > BCH 8 bit support
>  > 1. write => ECC engine configured in wrap mode 6 and with ecc_size0 as 32.
>  > 2. read  => ECC engine configured in wrap mode 1 and with ecc_size0 as
>  > 26 and ecc_size1 as 2.
> 
>  > Note: For BCH8 ECC bytes set to 14 to make compatible with RBL.
> 
> On what device? In the am335x TRM (spruh73f.pdf) figure 26-15 (pg 4273)
> the rom code is documented to not use any padding on the ECC bytes
> (E.G. oob 2..53):
> 
> http://www.ti.com/litv/pdf/spruh73f
> 
> I see the driver in the u-boot-am33x tree (ti81xx_nand.c) seems to use
> 4x14 bytes as well though, so perhaps that's a bug in the documentation
> instead?

Yes, RBL uses 4x14 bytes.

Thanks
Avinash

> 
> -- 
> Bye, Peter Korsgaard
> 



From avinashphilip at ti.com  Tue Oct 23 06:17:58 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Tue, 23 Oct 2012 10:17:58 +0000
Subject: [PATCH 2/4] mtd: devices: elm: Add support for ELM error
 correction
In-Reply-To: <87hapvv800.fsf@macbook.be.48ers.dk>
References: <1349274589-11389-1-git-send-email-avinashphilip@ti.com>
 <1349274589-11389-3-git-send-email-avinashphilip@ti.com>
 <87hapvv800.fsf@macbook.be.48ers.dk>
Message-ID: <518397C60809E147AF5323E0420B992E3E9D29C3@DBDE01.ent.ti.com>

On Tue, Oct 16, 2012 at 01:10:47, Peter Korsgaard wrote:
> >>>>> Philip, Avinash <avinashphilip at ti.com> writes:
> 
>  > Platforms containing the ELM module can be used to correct errors
>  > reported by BCH 4, 8 & 16 bit ECC scheme. For now only 4 & 8 bit
>  > support is added.
> 
> This sounds odd to me. What about something like:
> 
> The ELM hardware module can be used to speedup BCH 4/8/16 ECC scheme
> error correction.
> 
> For now only 4 & 8 bit support is added.

Ok I will correct it.

> 
> 
>  > +++ b/drivers/mtd/devices/Makefile
>  > @@ -17,8 +17,10 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
>  >  obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
>  >  obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
>  >  obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
>  > +obj-$(CONFIG_MTD_NAND_OMAP2)	+= elm.o
> 
> You seem to only use it in 4/4 if CONFIG_MTD_NAND_OMAP_BCH is set, so it
> probably makes more sense to use that symbol to not needlessly include
> it if it won't be used.

Ok. This been good.

> 
> 
>  > +static void elm_write_reg(void *offset, u32 val)
>  > +{
>  > +	writel(val, offset);
>  > +}
>  > +
>  > +static u32 elm_read_reg(void *offset)
>  > +{
>  > +	return readl(offset);
>  > +}
> 
> As written these read/write wrappers don't add anything. How about
> passing struct elm_info and offset as an integer so you can drop
> elm_base from all call sites, E.G.:
> 
> static void elm_write_reg(struct elm_info *info, int offset, u32 val)
> {
>         writel(val, info->elm_base + offset);
> }
>

Ok, this helps to reduce some indentation levels also.
 
> 
>  > +void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
>  > +		struct elm_errorvec *err_vec)
>  > +{
>  > +	int i;
>  > +	u8 syndrome[BCH_MAX_ECC_BYTES_PER_SECTOR] = {0}, *syn_p;
> 
> 
> Why do you need to keep the entire syndrome around? You seem to only use
> it between elm_reverse_eccdata() and elm_load_syndrome(), so it could as
> well be BCH8_ECC_OOB_BYTES long (or rather a multiple of sizeof(u32).
> 
> It would also be good to do the shuffeling directly in elm_load_syndrome
> so you don't need the extra copy.

I will check.

> 
> 
>  > + */
>  > +
>  > +#ifndef __ELM_H
>  > +#define __ELM_H
>  > +
>  > +enum bch_ecc {
>  > +	BCH4_ECC = 0,
>  > +	BCH8_ECC,
>  > +	BCH16_ECC,
> 
> It probably makes more sense to not provide the enum value for BCH16 as
> you don't support it.
> 

Ok I will remove.

> 
>  > +};
>  > +

Thanks
Avinash




From hejianet at linux.vnet.ibm.com  Wed Oct 24 01:14:59 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Wed, 24 Oct 2012 13:14:59 +0800
Subject: [question]MTD:unstable bit issues?
Message-ID: <50877953.9040602@linux.vnet.ibm.com>

My hardware: vcs452 nandflash
my kernel:2.6.16(I know it is too old:(,but this problem seems not
relevant to the kernel version)

test steps:
1.copy a 100M file to the nand flash partition from remote client
2.use fsync to flush the mem to flash
3.use md5 to check whether the original file is different from the
copied one
4.repeat power-cuts test for 5 times, when booting up, it will check
the md5 again.
5.do step1 again

after a whole night test,(power-cut for 100 times), the step 4 failed.
1)there are some bytes changed:
-----------------------------------------------------
-original-file D0 40 E8 3E 00 00 BA 1A D0 40 0A 00 43 00 00 00
+file-in-flash D0 40 0F 41 00 00 BA 1A D0 40 0A 00 43 00 00 00
----------------------------------------------------- 
2)a 4k bytes hole with all 0 in the flash file.
-----------------------------------------------------
-original-file DD AF C8 EE 57 EB 84 CE A1 7F B1 38 E7 22 51 2F
-    94 AE 77 5B 48 EA 61 8C 09 BB C5 74 6E B1 87 D2 
-    A9 32 8D 2A E7 7F D2 C3 DB 1A 92 E7 66 7C B8 4E 
......
     
+file-in-flash 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
......
-----------------------------------------------------

I search google and find it might be relevant to "unstable bits
issue"(bit-flip) in nand.
I wonder is the bit-flip the possible reason to cause such a 4k all-zero
hole?
Thanks for any suggestion.

B.R.
Jia



From shijie8 at gmail.com  Wed Oct 24 02:13:46 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Wed, 24 Oct 2012 14:13:46 +0800
Subject: [PATCH] mtd: gpmi: remove unneccessary header
In-Reply-To: <1350147809-19616-1-git-send-email-shijie8@gmail.com>
References: <1350147809-19616-1-git-send-email-shijie8@gmail.com>
Message-ID: <CAMiH66E8WtAj3BedPEWaOPZzz8qamhGAZg_te4Rkqey4UB33Dg@mail.gmail.com>

ping.

On Sun, Oct 14, 2012 at 1:03 AM, Huang Shijie <shijie8 at gmail.com> wrote:
> The whole gpmi-nand driver has turned to pure devicetree supported.
> So the linux/mtd/gpmi-nand.h is not neccessary now. Just remove it,
> and move some macros to the gpmi-nand driver itself.
>
> Signed-off-by: Huang Shijie <shijie8 at gmail.com>
> ---
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |    1 -
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    7 +++-
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.h |    1 -
>  include/linux/mtd/gpmi-nand.h          |   68 --------------------------------
>  4 files changed, 6 insertions(+), 71 deletions(-)
>  delete mode 100644 include/linux/mtd/gpmi-nand.h
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> index 3502acc..1585c5b 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
> @@ -18,7 +18,6 @@
>   * with this program; if not, write to the Free Software Foundation, Inc.,
>   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>   */
> -#include <linux/mtd/gpmi-nand.h>
>  #include <linux/delay.h>
>  #include <linux/clk.h>
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index e2c56fc..d376198 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -25,7 +25,6 @@
>  #include <linux/slab.h>
>  #include <linux/interrupt.h>
>  #include <linux/module.h>
> -#include <linux/mtd/gpmi-nand.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/of.h>
> @@ -33,6 +32,12 @@
>  #include <linux/of_mtd.h>
>  #include "gpmi-nand.h"
>
> +/* Resource names for the GPMI NAND driver. */
> +#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
> +#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
> +#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
> +#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
> +
>  /* add our owner bbt descriptor */
>  static uint8_t scan_ff_pattern[] = { 0xff };
>  static struct nand_bbt_descr gpmi_bbt_descr = {
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> index 7ac25c1..3d93a5e 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
> @@ -130,7 +130,6 @@ struct gpmi_nand_data {
>         /* System Interface */
>         struct device           *dev;
>         struct platform_device  *pdev;
> -       struct gpmi_nand_platform_data  *pdata;
>
>         /* Resources */
>         struct resources        resources;
> diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h
> deleted file mode 100644
> index ed3c4e0..0000000
> --- a/include/linux/mtd/gpmi-nand.h
> +++ /dev/null
> @@ -1,68 +0,0 @@
> -/*
> - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> - */
> -
> -#ifndef __MACH_MXS_GPMI_NAND_H__
> -#define __MACH_MXS_GPMI_NAND_H__
> -
> -/* The size of the resources is fixed. */
> -#define GPMI_NAND_RES_SIZE     6
> -
> -/* Resource names for the GPMI NAND driver. */
> -#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
> -#define GPMI_NAND_GPMI_INTERRUPT_RES_NAME  "GPMI NAND GPMI Interrupt"
> -#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
> -#define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
> -#define GPMI_NAND_DMA_CHANNELS_RES_NAME    "GPMI NAND DMA Channels"
> -#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
> -
> -/**
> - * struct gpmi_nand_platform_data - GPMI NAND driver platform data.
> - *
> - * This structure communicates platform-specific information to the GPMI NAND
> - * driver that can't be expressed as resources.
> - *
> - * @platform_init:           A pointer to a function the driver will call to
> - *                           initialize the platform (e.g., set up the pin mux).
> - * @min_prop_delay_in_ns:    Minimum propagation delay of GPMI signals to and
> - *                           from the NAND Flash device, in nanoseconds.
> - * @max_prop_delay_in_ns:    Maximum propagation delay of GPMI signals to and
> - *                           from the NAND Flash device, in nanoseconds.
> - * @max_chip_count:          The maximum number of chips for which the driver
> - *                           should configure the hardware. This value most
> - *                           likely reflects the number of pins that are
> - *                           connected to a NAND Flash device. If this is
> - *                           greater than the SoC hardware can support, the
> - *                           driver will print a message and fail to initialize.
> - * @partitions:              An optional pointer to an array of partition
> - *                           descriptions.
> - * @partition_count:         The number of elements in the partitions array.
> - */
> -struct gpmi_nand_platform_data {
> -       /* SoC hardware information. */
> -       int             (*platform_init)(void);
> -
> -       /* NAND Flash information. */
> -       unsigned int    min_prop_delay_in_ns;
> -       unsigned int    max_prop_delay_in_ns;
> -       unsigned int    max_chip_count;
> -
> -       /* Medium information. */
> -       struct          mtd_partition *partitions;
> -       unsigned        partition_count;
> -};
> -#endif
> --
> 1.7.4.4
>


From shijie8 at gmail.com  Wed Oct 24 02:14:19 2012
From: shijie8 at gmail.com (Huang Shijie)
Date: Wed, 24 Oct 2012 14:14:19 +0800
Subject: [PATCH] mtd: use the NAND_STATUS_FAIL to replace the hardcode
In-Reply-To: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
References: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
Message-ID: <CAMiH66F8EJP8N0U1RBxKqvR=ik0JKaK5ABxedkr9j6iACE2e2A@mail.gmail.com>

ping

On Mon, Oct 15, 2012 at 11:47 AM, Huang Shijie <shijie8 at gmail.com> wrote:
> Use the NAND_STATUS_FAIL to replace the hardcode "0x01",
> which make the code more readable.
>
> Signed-off-by: Huang Shijie <shijie8 at gmail.com>
> ---
>  drivers/mtd/nand/nand_base.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index d5ece6e..4569174 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
>         /* Call wait ready function */
>         status = chip->waitfunc(mtd, chip);
>         /* See if device thinks it succeeded */
> -       if (status & 0x01) {
> +       if (status & NAND_STATUS_FAIL) {
>                 pr_debug("%s: error status = 0x%08x\n",
>                                         __func__, status);
>                 ret = -EIO;
> @@ -1004,7 +1004,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>         /* Call wait ready function */
>         status = chip->waitfunc(mtd, chip);
>         /* See if device thinks it succeeded */
> -       if (status & 0x01) {
> +       if (status & NAND_STATUS_FAIL) {
>                 pr_debug("%s: error status = 0x%08x\n",
>                                         __func__, status);
>                 ret = -EIO;
> --
> 1.7.4.4
>


From Thomas.Betker at rohde-schwarz.com  Wed Oct 24 04:13:02 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Wed, 24 Oct 2012 10:13:02 +0200
Subject: [question]MTD:unstable bit issues?
In-Reply-To: <50877953.9040602@linux.vnet.ibm.com>
References: <50877953.9040602@linux.vnet.ibm.com>
Message-ID: <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>

Hello Jia:

> ----------------------------------------------------- 
> 2)a 4k bytes hole with all 0 in the flash file.
> -----------------------------------------------------
> -original-file DD AF C8 EE 57 EB 84 CE A1 7F B1 38 E7 22 51 2F
> -    94 AE 77 5B 48 EA 61 8C 09 BB C5 74 6E B1 87 D2 
> -    A9 32 8D 2A E7 7F D2 C3 DB 1A 92 E7 66 7C B8 4E 
> ......
> 
> +file-in-flash 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> +    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> +    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> ......
> -----------------------------------------------------

We have also seen this "4k zeros" issue for some time. I never found out 
was was happening because the issue was suddenly no longer reproducible. 
:-(

In our case, though, we didn't have NAND flash, but JFFF2 with serial NOR 
flash. So I would guess that this is not a NAND problem.

Which file system do you run? Is it JFFS2?

Best regards,
Thomas



From hejianet at linux.vnet.ibm.com  Wed Oct 24 04:52:40 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Wed, 24 Oct 2012 16:52:40 +0800
Subject: [question]MTD:unstable bit issues?
In-Reply-To: <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
References: <50877953.9040602@linux.vnet.ibm.com>
 <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
Message-ID: <5087AC58.1000402@linux.vnet.ibm.com>

Hi Thomas
Yes, we use jffs2.
How did u solve your bug? :)
On 2012-10-24 16:13, Thomas.Betker at rohde-schwarz.com wrote:
> Hello Jia:
>
>> ----------------------------------------------------- 
>> 2)a 4k bytes hole with all 0 in the flash file.
>> -----------------------------------------------------
>> -original-file DD AF C8 EE 57 EB 84 CE A1 7F B1 38 E7 22 51 2F
>> -    94 AE 77 5B 48 EA 61 8C 09 BB C5 74 6E B1 87 D2 
>> -    A9 32 8D 2A E7 7F D2 C3 DB 1A 92 E7 66 7C B8 4E 
>> ......
>>
>> +file-in-flash 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> +    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
>> +    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
>> ......
>> -----------------------------------------------------
> We have also seen this "4k zeros" issue for some time. I never found out 
> was was happening because the issue was suddenly no longer reproducible. 
> :-(
>
> In our case, though, we didn't have NAND flash, but JFFF2 with serial NOR 
> flash. So I would guess that this is not a NAND problem.
>
> Which file system do you run? Is it JFFS2?
>
> Best regards,
> Thomas
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
>
>




From Thomas.Betker at rohde-schwarz.com  Wed Oct 24 05:01:02 2012
From: Thomas.Betker at rohde-schwarz.com (Thomas.Betker at rohde-schwarz.com)
Date: Wed, 24 Oct 2012 11:01:02 +0200
Subject: [question]MTD:unstable bit issues?
In-Reply-To: <5087AC58.1000402@linux.vnet.ibm.com>
References: <50877953.9040602@linux.vnet.ibm.com>
 <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
 <5087AC58.1000402@linux.vnet.ibm.com>
Message-ID: <OF4005835E.007816E8-ONC1257AA1.0030E2F0-C1257AA1.003189CF@rohde-schwarz.com>

Hello Jia:

> Yes, we use jffs2.
> How did u solve your bug? :)

> >> ----------------------------------------------------- 
> >> 2)a 4k bytes hole with all 0 in the flash file.
> >> -----------------------------------------------------

Unfortunately, we didn't solve it. Some day, it was simply gone; I have no 
idea what had changed. I couldn't reproduce it anymore, so I couldn't do 
any further analysis.

Anyway, most likely this is not a NAND issue or MTD issue, but a JFFS2 
issue. And I would certainly want to hear about it if you manage to find 
and fix it ...

Best regards,
Thomas



From hejianet at linux.vnet.ibm.com  Wed Oct 24 05:21:08 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Wed, 24 Oct 2012 17:21:08 +0800
Subject: [question]MTD:unstable bit issues?
In-Reply-To: <OF4005835E.007816E8-ONC1257AA1.0030E2F0-C1257AA1.003189CF@rohde-schwarz.com>
References: <50877953.9040602@linux.vnet.ibm.com>
 <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
 <5087AC58.1000402@linux.vnet.ibm.com>
 <OF4005835E.007816E8-ONC1257AA1.0030E2F0-C1257AA1.003189CF@rohde-schwarz.com>
Message-ID: <5087B304.8010903@linux.vnet.ibm.com>

Hi Thomas
till now, we have no evidence that it is a jffs2.
we only observed a ubi error msg(not 100% sure it caused this hole):

Oct 15 20:09:10 (none) kernel: UBI error: ubi_io_write error -5 while writing 2048 bytes to PEB 1663:20480, written 0 bytes

Besides, it only appeared in power-cut stress cut, so I suspect it is relevant
to "unstable bits issue". from google information, this issue appears in both
nand and nor flash, but more frequently in nand.

On 2012-10-24 17:01, Thomas.Betker at rohde-schwarz.com wrote:
> Hello Jia:
>
>> Yes, we use jffs2.
>> How did u solve your bug? :)
>>>> ----------------------------------------------------- 
>>>> 2)a 4k bytes hole with all 0 in the flash file.
>>>> -----------------------------------------------------
> Unfortunately, we didn't solve it. Some day, it was simply gone; I have no 
> idea what had changed. I couldn't reproduce it anymore, so I couldn't do 
> any further analysis.
>
> Anyway, most likely this is not a NAND issue or MTD issue, but a JFFS2 
> issue. And I would certainly want to hear about it if you manage to find 
> and fix it ...
>
> Best regards,
> Thomas
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
>
>




From jamie at shareable.org  Wed Oct 24 05:53:06 2012
From: jamie at shareable.org (Jamie Lokier)
Date: Wed, 24 Oct 2012 10:53:06 +0100
Subject: [question]MTD:unstable bit issues?
In-Reply-To: <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
References: <50877953.9040602@linux.vnet.ibm.com>
 <OFCD7F9EAE.28A631AD-ONC1257AA1.002B4604-C1257AA1.002D248C@rohde-schwarz.com>
Message-ID: <20121024095305.GA17431@jl-vm1.vm.bytemark.co.uk>

Thomas.Betker at rohde-schwarz.com wrote:
> Hello Jia:
> We have also seen this "4k zeros" issue for some time. I never found out 
> was was happening because the issue was suddenly no longer reproducible. 
> :-(
> 
> In our case, though, we didn't have NAND flash, but JFFF2 with serial NOR 
> flash. So I would guess that this is not a NAND problem.

I've seen it a number of times with JFFS2 with parallel NOR, on
ancient kernels (2.4.26-uc0).  Typically the symptom would be an
executable crashing, and a 4k hole would be causing that.

We always put it down to a faulty board with poor signal and/or timings
to the NOR, as it "seemed" to happen on particular boards more, and
simply removed those boards from service.  However testing wasn't very
systematic.

If JFFS2 sees a corrupt block (detected by CRC), it simply discards
that block from the file data as if it's never been written, making a
hole.  An I/O error would be much nicer than corrupt data, but a hole
is what we get.

It might have been caused by faulty boards but in a different way:
Some of our boards crashed every few weeks because the manufacturer's
tolerances between CPU and DRAM were too tight.  After a very long
time in the field (years), we learned to underclock those slightly.
Maybe, occasional DRAM corruption was also causing occasional NOR
corruption as a side effect (e.g. writing/reading data that didn't
match the CRC during JFFS2 GC), leading to 4k holes in previously good
files (bad but understandable); or maybe occasional crashes caused it
(not acceptable and shouldn't happen).  But I am not sure the two
issues were correlated anyway.

-- Jamie


From hechtb at googlemail.com  Wed Oct 24 06:38:14 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Wed, 24 Oct 2012 12:38:14 +0200
Subject: Possible regression in arm/io.h
Message-ID: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>

Hello Will,

your introduction of the "+Qo" in arch/arm/include/asm/io.h makes some
drivers fail to compile on newer gnu ARM gccs. Like in
drivers/mtd/nand/docg4.c there is an offset of 0x800 from a pointer
used to address I/O memory. This leads to the error message:

/tmp/ccwLMdCy.s: Error: bad immediate value for 8-bit offset (2048)

The gnu gcc people tracked it down to the asm directive "+Qo". Do we
really want to enforce to allow only addresses that are offsetable
with one byte? If I understand it correctly from the gnu gcc docs, the
"o" is doing this.

excerpt from asm/io.h:
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
        asm volatile("strh %1, %0"
                     : "+Qo" (*(volatile u16 __force *)addr)
                     : "r" (val));
}

Bug report:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54983

So do we want to remove the "o" from all __raw_readX and __raw_writeX
functions? I've tried it and stuff compiles again without errors.

cheers,

Bastian Hecht


From will.deacon at arm.com  Wed Oct 24 06:52:23 2012
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 24 Oct 2012 11:52:23 +0100
Subject: Possible regression in arm/io.h
In-Reply-To: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
Message-ID: <20121024105223.GC23775@mudshark.cambridge.arm.com>

On Wed, Oct 24, 2012 at 11:38:14AM +0100, Bastian Hecht wrote:
> Hello Will,

Hello,

> your introduction of the "+Qo" in arch/arm/include/asm/io.h makes some
> drivers fail to compile on newer gnu ARM gccs. Like in
> drivers/mtd/nand/docg4.c there is an offset of 0x800 from a pointer
> used to address I/O memory. This leads to the error message:
> 
> /tmp/ccwLMdCy.s: Error: bad immediate value for 8-bit offset (2048)

Urgh.

> The gnu gcc people tracked it down to the asm directive "+Qo". Do we
> really want to enforce to allow only addresses that are offsetable
> with one byte? If I understand it correctly from the gnu gcc docs, the
> "o" is doing this.
> 
> excerpt from asm/io.h:
> static inline void __raw_writew(u16 val, volatile void __iomem *addr)
> {
>         asm volatile("strh %1, %0"
>                      : "+Qo" (*(volatile u16 __force *)addr)
>                      : "r" (val));
> }
> 
> Bug report:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54983
> 
> So do we want to remove the "o" from all __raw_readX and __raw_writeX
> functions? I've tried it and stuff compiles again without errors.

I was under the impression that specifying multiple constraints would mean
that it would try "o", then if that didn't work it would fall back to "Q".
That's certainly the behaviour we've seen in the past... has this changed
with recent toolchains?

The problem with using "Q" on its own is that the compiler tends to generate
the address computation twice: once for "Q" and once for "r" -- this doesn't
happen with "o", where the address is computed once. This leads to an
increase in register pressure and I have seen the compiler choke claiming
that the inline asm block contains "impossible constraints" because it
insists on generating the address twice.

It sounds like we need to:

	(a) Understand what has changed in GCC to cause this error to start
	    cropping up.

	(b) Have a look at the impact of using only "Q" on the generated
	    code (especially register usage for the address).

Will


From hechtb at googlemail.com  Wed Oct 24 08:34:18 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Wed, 24 Oct 2012 14:34:18 +0200
Subject: Possible regression in arm/io.h
In-Reply-To: <20121024105223.GC23775@mudshark.cambridge.arm.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
Message-ID: <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>

2012/10/24 Will Deacon <will.deacon at arm.com>:
> On Wed, Oct 24, 2012 at 11:38:14AM +0100, Bastian Hecht wrote:
>> Hello Will,
>
> Hello,
>
>> your introduction of the "+Qo" in arch/arm/include/asm/io.h makes some
>> drivers fail to compile on newer gnu ARM gccs. Like in
>> drivers/mtd/nand/docg4.c there is an offset of 0x800 from a pointer
>> used to address I/O memory. This leads to the error message:
>>
>> /tmp/ccwLMdCy.s: Error: bad immediate value for 8-bit offset (2048)
>
> Urgh.

xD

>> The gnu gcc people tracked it down to the asm directive "+Qo". Do we
>> really want to enforce to allow only addresses that are offsetable
>> with one byte? If I understand it correctly from the gnu gcc docs, the
>> "o" is doing this.
>>
>> excerpt from asm/io.h:
>> static inline void __raw_writew(u16 val, volatile void __iomem *addr)
>> {
>>         asm volatile("strh %1, %0"
>>                      : "+Qo" (*(volatile u16 __force *)addr)
>>                      : "r" (val));
>> }
>>
>> Bug report:
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54983
>>
>> So do we want to remove the "o" from all __raw_readX and __raw_writeX
>> functions? I've tried it and stuff compiles again without errors.
>
> I was under the impression that specifying multiple constraints would mean
> that it would try "o", then if that didn't work it would fall back to "Q".
> That's certainly the behaviour we've seen in the past... has this changed
> with recent toolchains?
>
> The problem with using "Q" on its own is that the compiler tends to generate
> the address computation twice: once for "Q" and once for "r" -- this doesn't
> happen with "o", where the address is computed once. This leads to an
> increase in register pressure and I have seen the compiler choke claiming
> that the inline asm block contains "impossible constraints" because it
> insists on generating the address twice.
>
> It sounds like we need to:
>
>         (a) Understand what has changed in GCC to cause this error to start
>             cropping up.
>
>         (b) Have a look at the impact of using only "Q" on the generated
>             code (especially register usage for the address).
>
> Will

Uff... I've just started to write ARM assembly and have no practical
experience with the inner workings of real world compilers. So this
time I'm afraid I was just good enough to report this. It sounds
interesting to hunt it, but would take ages for me at this point.

cheers,

 Bastian


From will.deacon at arm.com  Wed Oct 24 09:09:57 2012
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 24 Oct 2012 14:09:57 +0100
Subject: Possible regression in arm/io.h
In-Reply-To: <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
Message-ID: <20121024130957.GB7339@mudshark.cambridge.arm.com>

On Wed, Oct 24, 2012 at 01:34:18PM +0100, Bastian Hecht wrote:
> 2012/10/24 Will Deacon <will.deacon at arm.com>:
> > It sounds like we need to:
> >
> >         (a) Understand what has changed in GCC to cause this error to start
> >             cropping up.
> >
> >         (b) Have a look at the impact of using only "Q" on the generated
> >             code (especially register usage for the address).
> >
> 
> Uff... I've just started to write ARM assembly and have no practical
> experience with the inner workings of real world compilers. So this
> time I'm afraid I was just good enough to report this. It sounds
> interesting to hunt it, but would take ages for me at this point.

Ok, I'll have a look at the impact of moving exclusively to "Q" when I get a
chance. Which toolchain are you using?

Will


From hechtb at googlemail.com  Wed Oct 24 09:35:11 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Wed, 24 Oct 2012 15:35:11 +0200
Subject: Possible regression in arm/io.h
In-Reply-To: <20121024130957.GB7339@mudshark.cambridge.arm.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
 <20121024130957.GB7339@mudshark.cambridge.arm.com>
Message-ID: <CABYn4sz4v7Uf07am=MtPAKAvvAjwt+-bTRaLrBjoiRuyR9cfZw@mail.gmail.com>

2012/10/24 Will Deacon <will.deacon at arm.com>:
> On Wed, Oct 24, 2012 at 01:34:18PM +0100, Bastian Hecht wrote:
>> 2012/10/24 Will Deacon <will.deacon at arm.com>:
>> > It sounds like we need to:
>> >
>> >         (a) Understand what has changed in GCC to cause this error to start
>> >             cropping up.
>> >
>> >         (b) Have a look at the impact of using only "Q" on the generated
>> >             code (especially register usage for the address).
>> >
>>
>> Uff... I've just started to write ARM assembly and have no practical
>> experience with the inner workings of real world compilers. So this
>> time I'm afraid I was just good enough to report this. It sounds
>> interesting to hunt it, but would take ages for me at this point.
>
> Ok, I'll have a look at the impact of moving exclusively to "Q" when I get a
> chance. Which toolchain are you using?

gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
For a more verbose info take a look at the bug report link.

> Will


From will.deacon at arm.com  Wed Oct 24 09:58:54 2012
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 24 Oct 2012 14:58:54 +0100
Subject: Possible regression in arm/io.h
In-Reply-To: <CABYn4sz4v7Uf07am=MtPAKAvvAjwt+-bTRaLrBjoiRuyR9cfZw@mail.gmail.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
 <20121024130957.GB7339@mudshark.cambridge.arm.com>
 <CABYn4sz4v7Uf07am=MtPAKAvvAjwt+-bTRaLrBjoiRuyR9cfZw@mail.gmail.com>
Message-ID: <20121024135854.GD7339@mudshark.cambridge.arm.com>

On Wed, Oct 24, 2012 at 02:35:11PM +0100, Bastian Hecht wrote:
> 2012/10/24 Will Deacon <will.deacon at arm.com>:
> > On Wed, Oct 24, 2012 at 01:34:18PM +0100, Bastian Hecht wrote:
> >> 2012/10/24 Will Deacon <will.deacon at arm.com>:
> >> > It sounds like we need to:
> >> >
> >> >         (a) Understand what has changed in GCC to cause this error to start
> >> >             cropping up.
> >> >
> >> >         (b) Have a look at the impact of using only "Q" on the generated
> >> >             code (especially register usage for the address).
> >> >
> >>
> >> Uff... I've just started to write ARM assembly and have no practical
> >> experience with the inner workings of real world compilers. So this
> >> time I'm afraid I was just good enough to report this. It sounds
> >> interesting to hunt it, but would take ages for me at this point.
> >
> > Ok, I'll have a look at the impact of moving exclusively to "Q" when I get a
> > chance. Which toolchain are you using?
> 
> gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
> For a more verbose info take a look at the bug report link.

Ok, thanks. One other thing you could try while I try to find a copy of that
toolchain is changing the "+" modifier to an "=", like I proposed in this
version of the patch:

  http://lists.infradead.org/pipermail/linux-arm-kernel/2012-August/114971.html

Cheers,

Will


From hechtb at googlemail.com  Wed Oct 24 11:04:46 2012
From: hechtb at googlemail.com (Bastian Hecht)
Date: Wed, 24 Oct 2012 17:04:46 +0200
Subject: Possible regression in arm/io.h
In-Reply-To: <20121024135854.GD7339@mudshark.cambridge.arm.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
 <20121024130957.GB7339@mudshark.cambridge.arm.com>
 <CABYn4sz4v7Uf07am=MtPAKAvvAjwt+-bTRaLrBjoiRuyR9cfZw@mail.gmail.com>
 <20121024135854.GD7339@mudshark.cambridge.arm.com>
Message-ID: <CABYn4sxnwzj8KFfELzCLzQMcAjiqS3_Vr2kStkm-na8G1noPHA@mail.gmail.com>

>> > Ok, I'll have a look at the impact of moving exclusively to "Q" when I get a
>> > chance. Which toolchain are you using?
>>
>> gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
>> For a more verbose info take a look at the bug report link.
>
> Ok, thanks. One other thing you could try while I try to find a copy of that
> toolchain is changing the "+" modifier to an "=", like I proposed in this
> version of the patch:

So if alter it to fit to your patch scheme the result is:

  CC      arch/arm/kernel/asm-offsets.s
In file included from include/linux/scatterlist.h:10,
                 from include/linux/dma-mapping.h:9,
                 from arch/arm/kernel/asm-offsets.c:15:
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h: In function
'__raw_readb':
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:100: error:
output operand constraint lacks '='
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:98: error:
output operand constraint lacks '='
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:98: error:
invalid lvalue in asm output 0
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h: In function
'__raw_readl':
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:109: error:
output operand constraint lacks '='
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:107: error:
output operand constraint lacks '='
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:107: error:
invalid lvalue in asm output 0

and if I just replace all +Q with =Q it's this:
  LD      kernel/time/built-in.o
drivers/sh/intc/access.c: In function 'test_8':
drivers/sh/intc/access.c:78: warning: passing argument 1 of
'__raw_readb' makes pointer from integer without a cast
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:95: note:
expected 'const volatile void *' but argument is of type 'long
unsigned int'
drivers/sh/intc/access.c: In function 'test_16':
drivers/sh/intc/access.c:84: warning: passing argument 1 of
'__raw_readw' makes pointer from integer without a cast
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:71: note:
expected 'const volatile void *' but argument is of type 'long
unsigned int'
drivers/sh/intc/access.c: In function 'test_32':
drivers/sh/intc/access.c:90: warning: passing argument 1 of
'__raw_readl' makes pointer from integer without a cast
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:104: note:
expected 'const volatile void *' but argument is of type 'long
unsigned int'
drivers/sh/intc/access.c: In function 'write_8':
drivers/sh/intc/access.c:96: warning: passing argument 2 of
'__raw_writeb' makes pointer from integer without a cast
/home/basti/renesas/flctl_patch/arch/arm/include/asm/io.h:81: note:
expected 'volatile void *' but argument is of type 'long unsigned int'
... and so on

cheers,

 Bastian


From will.deacon at arm.com  Wed Oct 24 11:27:30 2012
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 24 Oct 2012 16:27:30 +0100
Subject: Possible regression in arm/io.h
In-Reply-To: <CABYn4sxnwzj8KFfELzCLzQMcAjiqS3_Vr2kStkm-na8G1noPHA@mail.gmail.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <CABYn4swp9JBEHgGTOkoe=tOh3Mf1dq5WYr=2xuKNpTmLX5LcFQ@mail.gmail.com>
 <20121024130957.GB7339@mudshark.cambridge.arm.com>
 <CABYn4sz4v7Uf07am=MtPAKAvvAjwt+-bTRaLrBjoiRuyR9cfZw@mail.gmail.com>
 <20121024135854.GD7339@mudshark.cambridge.arm.com>
 <CABYn4sxnwzj8KFfELzCLzQMcAjiqS3_Vr2kStkm-na8G1noPHA@mail.gmail.com>
Message-ID: <20121024152730.GH7339@mudshark.cambridge.arm.com>

On Wed, Oct 24, 2012 at 04:04:46PM +0100, Bastian Hecht wrote:
> >> > Ok, I'll have a look at the impact of moving exclusively to "Q" when I get a
> >> > chance. Which toolchain are you using?
> >>
> >> gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
> >> For a more verbose info take a look at the bug report link.
> >
> > Ok, thanks. One other thing you could try while I try to find a copy of that
> > toolchain is changing the "+" modifier to an "=", like I proposed in this
> > version of the patch:
> 
> So if alter it to fit to your patch scheme the result is:

Sorry, the change wasn't as trivial as I thought -- you have to reorder the
constraints because an output becomes an input for the load accessors. I
tried it myself and it doesn't fix the issue (I can reproduce it now).

Will


From hejianet at linux.vnet.ibm.com  Wed Oct 24 21:41:10 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Thu, 25 Oct 2012 09:41:10 +0800
Subject: jffs2 copy too long after mounting
In-Reply-To: <50881109.3010107@linux.vnet.ibm.com>
References: <50881109.3010107@linux.vnet.ibm.com>
Message-ID: <508898B6.8060504@linux.vnet.ibm.com>

Hi all
  I think I find the reason why there are so many similar logs("Check
potential deletion dirent").
  It seems in jffs2_garbage_collect_deletion_dirent(), jffs2 tries to 
find "whether this deletion dirent is still needed to actively delete
a 'real' dirent with the same name that's still somewhere else on the 
flash."
  I wonder why there is such a necessary handling procedure? There must
be a newest valid direntry. Why we need to remove the older one and 
"write out a new deletion dirent to replace it"? What if jffs2 just 
did not search the older deletion dirent allover the flash?
Thanks.
B.R.
Jia


On 2012-10-23 15:13, hejianet wrote:
> Hi Artem, thanks for your reply
> Now I can reproduce it after 2-3 days stress tests:
> 1.just do lots of small writing(4k bytes each time) radomly in one of 1000
>  thousand file
> 2.remove the 1000 files,now the jffs2 fs is *very* dirty.
> 3.I dynamically increase the threshold nr_free_blocks to trigger the gc
> in jffs2_thread_should_wake():
>      if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
>             (dirty > c->nospc_dirty_size))
>         ret = 1;
> 4. I watched after a while, there were tens of  thousands of lines (I enable the
> jffs2 log level to be 1)
> Check potential deletion dirent at 008ddd24
> Check potential deletion dirent at 008ddcf4
> Check potential deletion dirent at 008ddcc4
> Check potential deletion dirent at 008ddc68
> Check potential deletion dirent at 008dca34
> Check potential deletion dirent at 008dca04
> Check potential deletion dirent at 0088d77c
> Check potential deletion dirent at 0088d74c
> Check potential deletion dirent at 0088d71c
> Check potential deletion dirent at 0088d6ec
> Check potential deletion dirent at 0088d6bc
> Check potential deletion dirent at 0088c648
> Check potential deletion dirent at 0088c618
> Check potential deletion dirent at 0088c2a8
> Check potential deletion dirent at 0088c278
> Check potential deletion dirent at 0088c248
> Check potential deletion dirent at 0088c218
> Check potential deletion dirent at 0088c1e8
> Check potential deletion dirent at 00886b50
> Check potential deletion dirent at 00885388
> Check potential deletion dirent at 00885358
> Check potential deletion dirent at 008852a8
> Check potential deletion dirent at 00885278
> 5. I did find that the free blocks number of jffs2 is very slowly increased
>
> So could you give me any ideas, it is normal or abnormal?
> Thanks a lot
> On 2012-08-24 15:53, Artem Bityutskiy wrote:
>> On Thu, 2012-08-02 at 11:04 +0800, hejianet wrote:
>>> hi All
>>> my kernel is 2.6.16
>>> after mounting the nand flash with jffs2 partition, the first copy operation
>>> for a 15M file(from jffs2 partition to jffs2 partition) take 9
>>> minutes,but the
>>> second copy operation takes 1 minutes.
>>> the disk usage(df result) is over 85%.
>>> I wonder is there any patch ported to such old kernel?
>> His is because how JFFS2 is designed. When the mount operation is
>> finished, JFFS2 does not really finish mounting. There is the background
>> process which keeps working - it basically reads all files in the system
>> and checks the CRC, which is needed to find out which nodes are new and
>> which are obsolete.
>>
>> So what happens is that you mount JFFS2, the background thread keeps
>> working (see 'top' for example).
>>
>> While the background thread works, you can read files. But you cannot
>> write - writes will be blocked. Well, it is a bit more complex - you can
>> write a little, but from some point your writes will be blocked until
>> the background thread finishes. Then the write will continue and finish.
>>
>> In you case, you mount, start writing your 15MiB file, write gets
>> blocked, waits for the background thread, then continues write. The
>> background thread takes ages to finish on big partitions.
>>
>> The second write is fast because you do not wait for the background
>> thread any longer.
>>
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
>
>







From dedekind1 at gmail.com  Thu Oct 25 02:55:22 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 25 Oct 2012 09:55:22 +0300
Subject: Possible regression in arm/io.h
In-Reply-To: <20121024105223.GC23775@mudshark.cambridge.arm.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
Message-ID: <1351148122.2507.63.camel@sauron.fi.intel.com>

On Wed, 2012-10-24 at 11:52 +0100, Will Deacon wrote:
> 	(a) Understand what has changed in GCC to cause this error to start
> 	    cropping up.

This is about already quite old gcc 4.6.3, which I use for about 4 last
kernel releases already. So it is only the kernel that changed.

You can download the GCC I used from here:
http://kernel.org/pub/tools/crosstool/

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121025/15484097/attachment.sig>

From shawn.guo at linaro.org  Thu Oct 25 03:16:34 2012
From: shawn.guo at linaro.org (Shawn Guo)
Date: Thu, 25 Oct 2012 15:16:34 +0800
Subject: [PATCH] ARM: dts: mxs: add the "clock-names" for gpmi-nand
In-Reply-To: <1349864829-19565-1-git-send-email-b32955@freescale.com>
References: <201210101237.13640.marex@denx.de>
 <1349864829-19565-1-git-send-email-b32955@freescale.com>
Message-ID: <20121025071629.GD2464@S2101-09.ap.freescale.net>

Hi Arnd, Olof,

Can you please apply this fix for -rc?  Otherwise, please let me know
if you prefer to get a pull request from me.

Shawn

On Wed, Oct 10, 2012 at 06:27:09PM +0800, Huang Shijie wrote:
> The current DT nodes for mx23/mx28 miss the `clocks-names` item for gpmi-nand.
> So the gpmi-nand driver could not find the proper clock.
> 
> This patch fixes this issue.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  arch/arm/boot/dts/imx23.dtsi |    1 +
>  arch/arm/boot/dts/imx28.dtsi |    1 +
>  2 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
> index 9ca4ca7..6d31aa3 100644
> --- a/arch/arm/boot/dts/imx23.dtsi
> +++ b/arch/arm/boot/dts/imx23.dtsi
> @@ -69,6 +69,7 @@
>  				interrupts = <13>, <56>;
>  				interrupt-names = "gpmi-dma", "bch";
>  				clocks = <&clks 34>;
> +				clock-names = "gpmi_io";
>  				fsl,gpmi-dma-channel = <4>;
>  				status = "disabled";
>  			};
> diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
> index e16d631..55c57ea 100644
> --- a/arch/arm/boot/dts/imx28.dtsi
> +++ b/arch/arm/boot/dts/imx28.dtsi
> @@ -85,6 +85,7 @@
>  				interrupts = <88>, <41>;
>  				interrupt-names = "gpmi-dma", "bch";
>  				clocks = <&clks 50>;
> +				clock-names = "gpmi_io";
>  				fsl,gpmi-dma-channel = <4>;
>  				status = "disabled";
>  			};
> -- 
> 1.7.0.4
> 
> 


From will.deacon at arm.com  Thu Oct 25 07:17:05 2012
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 25 Oct 2012 12:17:05 +0100
Subject: Possible regression in arm/io.h
In-Reply-To: <1351148122.2507.63.camel@sauron.fi.intel.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <1351148122.2507.63.camel@sauron.fi.intel.com>
Message-ID: <20121025111705.GD11267@mudshark.cambridge.arm.com>

On Thu, Oct 25, 2012 at 07:55:22AM +0100, Artem Bityutskiy wrote:
> On Wed, 2012-10-24 at 11:52 +0100, Will Deacon wrote:
> > 	(a) Understand what has changed in GCC to cause this error to start
> > 	    cropping up.
> 
> This is about already quite old gcc 4.6.3, which I use for about 4 last
> kernel releases already. So it is only the kernel that changed.

Looks like it's broken with gcc 4.7 too, so it might be that it's never
worked. The problem seems to be that offsettable addresses are assumed by
GCC to have a 12-bit immediate range, which isn't true for half- and double-
work accessors, so GAS barfs when presented with the final (invalid) code.

Since we don't have double-word I/O accessors, we can just fallback to "Q"
for the half-word case:


diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 35c1ed8..42f042e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
 static inline void __raw_writew(u16 val, volatile void __iomem *addr)
 {
        asm volatile("strh %1, %0"
-                    : "+Qo" (*(volatile u16 __force *)addr)
+                    : "+Q" (*(volatile u16 __force *)addr)
                     : "r" (val));
 }
 
@@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
 {
        u16 val;
        asm volatile("ldrh %1, %0"
-                    : "+Qo" (*(volatile u16 __force *)addr),
+                    : "+Q" (*(volatile u16 __force *)addr),
                       "=r" (val));
        return val;
 }


but this has the downside of *always* generating the target address into a
register and then using the basic [rN] addressing mode. A simple example
being smsc911x_rx_readfifo, where we see:

  c021bbe4:       e1d230b2        ldrh    r3, [r2, #2]

changed into:

  c021bd50:       e2820002        add     r0, r2, #2
  c021bd54:       e1d030b0        ldrh    r3, [r0]

which sucks, frankly. Unfortunately, GCC doesn't give us another constraint
that we can use for this, so I think we just have to grin and bear it.

Will


From mikpe at it.uu.se  Thu Oct 25 08:35:21 2012
From: mikpe at it.uu.se (Mikael Pettersson)
Date: Thu, 25 Oct 2012 14:35:21 +0200
Subject: Possible regression in arm/io.h
In-Reply-To: <20121025111705.GD11267@mudshark.cambridge.arm.com>
References: <CABYn4syj0GZAsDYVQfXg_qKAFkbrxPLoZWpKRzwf3gfRkMGZkQ@mail.gmail.com>
 <20121024105223.GC23775@mudshark.cambridge.arm.com>
 <1351148122.2507.63.camel@sauron.fi.intel.com>
 <20121025111705.GD11267@mudshark.cambridge.arm.com>
Message-ID: <20617.12809.803356.83369@pilspetsen.it.uu.se>

Will Deacon writes:
 > On Thu, Oct 25, 2012 at 07:55:22AM +0100, Artem Bityutskiy wrote:
 > > On Wed, 2012-10-24 at 11:52 +0100, Will Deacon wrote:
 > > > 	(a) Understand what has changed in GCC to cause this error to start
 > > > 	    cropping up.
 > > 
 > > This is about already quite old gcc 4.6.3, which I use for about 4 last
 > > kernel releases already. So it is only the kernel that changed.
 > 
 > Looks like it's broken with gcc 4.7 too, so it might be that it's never
 > worked. The problem seems to be that offsettable addresses are assumed by
 > GCC to have a 12-bit immediate range, which isn't true for half- and double-
 > work accessors, so GAS barfs when presented with the final (invalid) code.
...
 > Unfortunately, GCC doesn't give us another constraint
 > that we can use for this, so I think we just have to grin and bear it.

Please file a GCC bugzilla entry with an enhancement request to support
ARM constraint letters for other immediate sizes than 12 (and list which
sizes are missing).


From arnd at arndb.de  Thu Oct 25 09:23:33 2012
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 25 Oct 2012 13:23:33 +0000
Subject: [PATCH] ARM: dts: mxs: add the "clock-names" for gpmi-nand
In-Reply-To: <20121025071629.GD2464@S2101-09.ap.freescale.net>
References: <201210101237.13640.marex@denx.de>
 <1349864829-19565-1-git-send-email-b32955@freescale.com>
 <20121025071629.GD2464@S2101-09.ap.freescale.net>
Message-ID: <201210251323.34353.arnd@arndb.de>

On Thursday 25 October 2012, Shawn Guo wrote:
> 
> Hi Arnd, Olof,
> 
> Can you please apply this fix for -rc?  Otherwise, please let me know
> if you prefer to get a pull request from me.
> 

Applied to fixes branch, and added your Ack as well as the Review
tag from Marek.

	Arnd



From rpjday at crashcourse.ca  Thu Oct 25 09:43:10 2012
From: rpjday at crashcourse.ca (Robert P. J. Day)
Date: Thu, 25 Oct 2012 09:43:10 -0400 (EDT)
Subject: [PATCH] MTD: Fix kernel-doc content to avoid warning.
Message-ID: <alpine.DEB.2.02.1210250941170.27692@oneiric>


Add missing colons to fix kernel-doc generation warnings.

Signed-off-by: Robert P. J. Day <rpjday at crashcourse.ca>

---

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 24e9159..9d8a604 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -471,8 +471,8 @@ struct nand_buffers {
  *			non 0 if ONFI supported.
  * @onfi_params:	[INTERN] holds the ONFI page parameter when ONFI is
  *			supported, 0 otherwise.
- * @onfi_set_features	[REPLACEABLE] set the features for ONFI nand
- * @onfi_get_features	[REPLACEABLE] get the features for ONFI nand
+ * @onfi_set_features:	[REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features:	[REPLACEABLE] get the features for ONFI nand
  * @ecclayout:		[REPLACEABLE] the default ECC placement scheme
  * @bbt:		[INTERN] bad block table pointer
  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================


From computersforpeace at gmail.com  Thu Oct 25 12:07:00 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 25 Oct 2012 09:07:00 -0700
Subject: [PATCH] mtd: use the NAND_STATUS_FAIL to replace the hardcode
In-Reply-To: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
References: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
Message-ID: <CAN8TOE9BAHUFZf0pW7RvE4B0gbQgXNywQi9mvRgP_f3MKMmtuA@mail.gmail.com>

FWIW

On Sun, Oct 14, 2012 at 8:47 PM, Huang Shijie <shijie8 at gmail.com> wrote:
> Use the NAND_STATUS_FAIL to replace the hardcode "0x01",
> which make the code more readable.
>
> Signed-off-by: Huang Shijie <shijie8 at gmail.com>

Acked-by: Brian Norris <computersforpeace at gmail.com>


From vincenzo.aliberti at gmail.com  Thu Oct 25 18:00:50 2012
From: vincenzo.aliberti at gmail.com (Vincenzo Aliberti)
Date: Fri, 26 Oct 2012 00:00:50 +0200
Subject: [PATCH] [MTD] MTD driver for LPDDR2-NVM PCM memories
In-Reply-To: <1350479369.5769.153.camel@sauron.fi.intel.com>
References: <1349385434-3073-1-git-send-email-valibert@micron.com>
 <1349954577.12014.13.camel@sauron.fi.intel.com> <507DD09C.6050600@gmail.com>
 <1350479369.5769.153.camel@sauron.fi.intel.com>
Message-ID: <5089B692.1030203@gmail.com>

On 10/17/2012 03:09 PM, Artem Bityutskiy wrote:
> On Tue, 2012-10-16 at 23:24 +0200, Vincenzo Aliberti wrote:
>> The only Warning is
>> WARNING: line over 80 characters
>> #605: FILE: include/uapi/mtd/mtd-abi.h:112:
>> +#define MTD_CAP_PCM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
>>
>> But in the file include/uapi/mtd/mtd-abi.h there is already the raw:
>> #define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
> 
> You can ignore this warning.
> 

Artem, David do you see the need for further changes or do you think it can be
pulled in the main line?


From hejianet at linux.vnet.ibm.com  Thu Oct 25 21:45:47 2012
From: hejianet at linux.vnet.ibm.com (hejianet)
Date: Fri, 26 Oct 2012 09:45:47 +0800
Subject: jffs2 copy too long after mounting
In-Reply-To: <508898B6.8060504@linux.vnet.ibm.com>
References: <50881109.3010107@linux.vnet.ibm.com>
 <508898B6.8060504@linux.vnet.ibm.com>
Message-ID: <5089EB4B.5020800@linux.vnet.ibm.com>

Sorry,maybe my question is long and bothering:(
I try to make it more easily and clearly
in jffs2_garbage_collect_deletion_dirent(),
what does it mean, why in nand, we can't actually mark nodes obsolete
pernamently
    /* On a medium where we can't actually mark nodes obsolete
       pernamently, such as NAND flash, ..... */

On 2012-10-25 09:41, hejianet wrote:
> Hi all
>   I think I find the reason why there are so many similar logs("Check
> potential deletion dirent").
>   It seems in jffs2_garbage_collect_deletion_dirent(), jffs2 tries to 
> find "whether this deletion dirent is still needed to actively delete
> a 'real' dirent with the same name that's still somewhere else on the 
> flash."
>   I wonder why there is such a necessary handling procedure? There must
> be a newest valid direntry. Why we need to remove the older one and 
> "write out a new deletion dirent to replace it"? What if jffs2 just 
> did not search the older deletion dirent allover the flash?
> Thanks.
> B.R.
> Jia
>
>
> On 2012-10-23 15:13, hejianet wrote:
>> Hi Artem, thanks for your reply
>> Now I can reproduce it after 2-3 days stress tests:
>> 1.just do lots of small writing(4k bytes each time) radomly in one of 1000
>>  thousand file
>> 2.remove the 1000 files,now the jffs2 fs is *very* dirty.
>> 3.I dynamically increase the threshold nr_free_blocks to trigger the gc
>> in jffs2_thread_should_wake():
>>      if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
>>             (dirty > c->nospc_dirty_size))
>>         ret = 1;
>> 4. I watched after a while, there were tens of  thousands of lines (I enable the
>> jffs2 log level to be 1)
>> Check potential deletion dirent at 008ddd24
>> Check potential deletion dirent at 008ddcf4
>> Check potential deletion dirent at 008ddcc4
>> Check potential deletion dirent at 008ddc68
>> Check potential deletion dirent at 008dca34
>> Check potential deletion dirent at 008dca04
>> Check potential deletion dirent at 0088d77c
>> Check potential deletion dirent at 0088d74c
>> Check potential deletion dirent at 0088d71c
>> Check potential deletion dirent at 0088d6ec
>> Check potential deletion dirent at 0088d6bc
>> Check potential deletion dirent at 0088c648
>> Check potential deletion dirent at 0088c618
>> Check potential deletion dirent at 0088c2a8
>> Check potential deletion dirent at 0088c278
>> Check potential deletion dirent at 0088c248
>> Check potential deletion dirent at 0088c218
>> Check potential deletion dirent at 0088c1e8
>> Check potential deletion dirent at 00886b50
>> Check potential deletion dirent at 00885388
>> Check potential deletion dirent at 00885358
>> Check potential deletion dirent at 008852a8
>> Check potential deletion dirent at 00885278
>> 5. I did find that the free blocks number of jffs2 is very slowly increased
>>
>> So could you give me any ideas, it is normal or abnormal?
>> Thanks a lot
>> On 2012-08-24 15:53, Artem Bityutskiy wrote:
>>> On Thu, 2012-08-02 at 11:04 +0800, hejianet wrote:
>>>> hi All
>>>> my kernel is 2.6.16
>>>> after mounting the nand flash with jffs2 partition, the first copy operation
>>>> for a 15M file(from jffs2 partition to jffs2 partition) take 9
>>>> minutes,but the
>>>> second copy operation takes 1 minutes.
>>>> the disk usage(df result) is over 85%.
>>>> I wonder is there any patch ported to such old kernel?
>>> His is because how JFFS2 is designed. When the mount operation is
>>> finished, JFFS2 does not really finish mounting. There is the background
>>> process which keeps working - it basically reads all files in the system
>>> and checks the CRC, which is needed to find out which nodes are new and
>>> which are obsolete.
>>>
>>> So what happens is that you mount JFFS2, the background thread keeps
>>> working (see 'top' for example).
>>>
>>> While the background thread works, you can read files. But you cannot
>>> write - writes will be blocked. Well, it is a bit more complex - you can
>>> write a little, but from some point your writes will be blocked until
>>> the background thread finishes. Then the write will continue and finish.
>>>
>>> In you case, you mount, start writing your 15MiB file, write gets
>>> blocked, waits for the background thread, then continues write. The
>>> background thread takes ages to finish on big partitions.
>>>
>>> The second write is fast because you do not wait for the background
>>> thread any longer.
>>>
>>
>> ______________________________________________________
>> Linux MTD discussion mailing list
>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>
>>
>>
>
>
>
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
>
>




From paul at pwsan.com  Thu Oct 25 21:48:44 2012
From: paul at pwsan.com (Paul Walmsley)
Date: Fri, 26 Oct 2012 01:48:44 +0000 (UTC)
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of
 cpu_is
In-Reply-To: <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
References: <cover.1349672877.git.afzal@ti.com>
 <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
Message-ID: <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>

Hi Afzal

On Mon, 8 Oct 2012, Afzal Mohammed wrote:

> platform data now contains a field to indicate whether
> soc belongs to omap34xx family, use it instead of
> cpu_is_* check.
> 
> This helps in removing dependency of platform specific
> header file - cpu.h
> 
> Signed-off-by: Afzal Mohammed <afzal at ti.com>

This one breaks an N800 multi-OMAP build here:

  LD      init/built-in.o
drivers/built-in.o: In function `omap2_onenand_probe':
/home/paul/linux-bisect/drivers/mtd/onenand/omap2.c:788: undefined 
reference to `omap3_onenand_read_bufferram'
/home/paul/linux-bisect/drivers/mtd/onenand/omap2.c:788: undefined 
reference to `omap3_onenand_write_bufferram'
make: *** [vmlinux] Error 1

A fix is below.


- Paul


---
 drivers/mtd/onenand/omap2.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 53069ae..f87cf39 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -445,13 +445,19 @@ out_copy:
 
 #else
 
-int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
-				 unsigned char *buffer, int offset,
-				 size_t count);
+static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+					unsigned char *buffer, int offset,
+					size_t count)
+{
+	return -ENOSYS;
+}
 
-int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
-				  const unsigned char *buffer,
-				  int offset, size_t count);
+static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+					 const unsigned char *buffer,
+					 int offset, size_t count)
+{
+	return -ENOSYS;
+}
 
 #endif
 
-- 
1.7.10.4



From paul at pwsan.com  Fri Oct 26 01:04:10 2012
From: paul at pwsan.com (Paul Walmsley)
Date: Fri, 26 Oct 2012 05:04:10 +0000 (UTC)
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of
 cpu_is
In-Reply-To: <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
References: <cover.1349672877.git.afzal@ti.com>
 <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
 <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
Message-ID: <alpine.DEB.2.00.1210260411140.27963@utopia.booyaka.com>

On Fri, 26 Oct 2012, Paul Walmsley wrote:

> On Mon, 8 Oct 2012, Afzal Mohammed wrote:
> 
> > platform data now contains a field to indicate whether
> > soc belongs to omap34xx family, use it instead of
> > cpu_is_* check.
> > 
> > This helps in removing dependency of platform specific
> > header file - cpu.h
> > 
> > Signed-off-by: Afzal Mohammed <afzal at ti.com>
> 
> This one breaks an N800 multi-OMAP build here:

It also breaks an OMAP3+4 config:

drivers/built-in.o: In function `omap2_onenand_probe':
/home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:742: 
undefined reference to `omap2_onenand_read_bufferram'
/home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:743: 
undefined reference to `omap2_onenand_write_bufferram'
/home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:742: 
undefined reference to `omap2_onenand_read_bufferram'
/home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:743: 
undefined reference to `omap2_onenand_write_bufferram'

Fix below.


- Paul

---
 drivers/mtd/onenand/omap2.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index f87cf39..99f96e1 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -555,13 +555,19 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 
 #else
 
-int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-				 unsigned char *buffer, int offset,
-				 size_t count);
+static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
+					unsigned char *buffer, int offset,
+					size_t count)
+{
+	return -ENOSYS;
+}
 
-int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-				  const unsigned char *buffer,
-				  int offset, size_t count);
+static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
+					 const unsigned char *buffer,
+					 int offset, size_t count)
+{
+	return -ENOSYS;
+}
 
 #endif
 
-- 
1.7.10.4


From dedekind1 at gmail.com  Fri Oct 26 09:41:32 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 26 Oct 2012 16:41:32 +0300
Subject: [PATCH] mtd: gpmi: remove unneccessary header
In-Reply-To: <1350147809-19616-1-git-send-email-shijie8@gmail.com>
References: <1350147809-19616-1-git-send-email-shijie8@gmail.com>
Message-ID: <1351258892.1823.20.camel@sauron.fi.intel.com>

On Sat, 2012-10-13 at 13:03 -0400, Huang Shijie wrote:
> The whole gpmi-nand driver has turned to pure devicetree supported.
> So the linux/mtd/gpmi-nand.h is not neccessary now. Just remove it,
> and move some macros to the gpmi-nand driver itself.
> 
> Signed-off-by: Huang Shijie <shijie8 at gmail.com>

I cannot compile-test it because the MXS configuration file I always
used for compile-testing gpmi-nand patches (attached) does not work
anymore - I get the following compilation errors:

/home/dedekind/git/l2-mtd/arch/arm/include/asm/processor.h:82: warning: "__LINUX_ARM_ARCH__" is not defined
/home/dedekind/git/l2-mtd/arch/arm/include/asm/processor.h:97: warning: "__LINUX_ARM_ARCH__" is not defined
In file included from include/linux/time.h:6,
                 from include/uapi/linux/timex.h:56,
                 from include/linux/timex.h:56,
                 from include/linux/sched.h:17,
                 from arch/arm/kernel/asm-offsets.c:13:
include/linux/math64.h: In function 'div_u64_rem':
include/linux/math64.h:55: error: '__LINUX_ARM_ARCH__' undeclared (first use in this function)
include/linux/math64.h:55: error: (Each undeclared identifier is reported only once
include/linux/math64.h:55: error: for each function it appears in.)
In file included from include/linux/mm_types.h:15,
                 from include/linux/sched.h:24,
                 from arch/arm/kernel/asm-offsets.c:13:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/page.h: At top level:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/page.h:107: error: #error Unknown user operations model
In file included from include/linux/mm.h:44,
                 from arch/arm/kernel/asm-offsets.c:14:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/pgtable.h:210: warning: "__LINUX_ARM_ARCH__" is not defined
In file included from include/linux/scatterlist.h:10,
                 from include/linux/dma-mapping.h:9,
                 from arch/arm/kernel/asm-offsets.c:15:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/io.h:50: warning: "__LINUX_ARM_ARCH__" is not defined
In file included from include/linux/dma-mapping.h:76,
                 from arch/arm/kernel/asm-offsets.c:15:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/dma-mapping.h: In function 'dma_mapping_error':
/home/dedekind/git/l2-mtd/arch/arm/include/asm/dma-mapping.h:94: error: implicit declaration of function 'debug_dma_mapping_error'
In file included from /home/dedekind/git/l2-mtd/arch/arm/include/asm/cacheflush.h:15,
                 from arch/arm/kernel/asm-offsets.c:16:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/glue-cache.h: At top level:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/glue-cache.h:129: error: #error Unknown cache maintenance model
In file included from /home/dedekind/git/l2-mtd/arch/arm/include/asm/cacheflush.h:17,
                 from arch/arm/kernel/asm-offsets.c:16:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/cachetype.h:28: warning: "__LINUX_ARM_ARCH__" is not defined
/home/dedekind/git/l2-mtd/arch/arm/include/asm/cachetype.h:33: warning: "__LINUX_ARM_ARCH__" is not defined
In file included from arch/arm/kernel/asm-offsets.c:16:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/cacheflush.h:204: warning: "__LINUX_ARM_ARCH__" is not defined
/home/dedekind/git/l2-mtd/arch/arm/include/asm/cacheflush.h:206: warning: "__LINUX_ARM_ARCH__" is not defined
In file included from arch/arm/kernel/asm-offsets.c:17:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/glue-df.h:99: error: #error Unknown data abort handler type
In file included from arch/arm/kernel/asm-offsets.c:18:
/home/dedekind/git/l2-mtd/arch/arm/include/asm/glue-pf.h:54: error: #error Unknown prefetch abort handler type
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
make: *** [prepare0] Error 2

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_PID_NS is not set
CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_MXS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_AEABI=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_AUTO_ZRELADDR=y
CONFIG_FPE_NWFPE=y
CONFIG_DEVTMPFS=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_AFS_PARTS=y
CONFIG_MTD_AR7_PARTS=m
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=y
CONFIG_FTL=m
CONFIG_NFTL=y
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=y
CONFIG_SSFDC=y
CONFIG_SM_FTL=y
CONFIG_MTD_OOPS=y
CONFIG_MTD_SWAP=y
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_ROM=m
CONFIG_MTD_ABSENT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_IMPA7=m
CONFIG_MTD_GPIO_ADDR=y
CONFIG_MTD_PLATRAM=y
CONFIG_MTD_LATCH_ADDR=y
CONFIG_MTD_DATAFLASH=m
CONFIG_MTD_DATAFLASH_OTP=y
CONFIG_MTD_M25P80=m
# CONFIG_M25PXX_USE_FAST_READ is not set
CONFIG_MTD_SST25L=m
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_DOC2000=m
CONFIG_MTD_DOC2001=m
CONFIG_MTD_DOC2001PLUS=m
CONFIG_MTD_DOCG3=y
CONFIG_MTD_NAND_ECC_SMC=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_GPIO=y
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
CONFIG_MTD_NAND_DOCG4=y
CONFIG_MTD_NAND_NANDSIM=m
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_ONENAND=m
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_GENERIC=m
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_SIM=m
CONFIG_MTD_LPDDR=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_GLUEBI=m
# CONFIG_BLK_DEV is not set
CONFIG_ATMEL_PWM=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_SPI=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_DMADEVICES=y
# CONFIG_IOMMU_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_JFFS2_FS=m
# CONFIG_JFFS2_FS_WRITEBUFFER is not set
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
# CONFIG_JFFS2_RTIME is not set
CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_NONE=y
CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
# CONFIG_UBIFS_FS_LZO is not set
CONFIG_LOGFS=y
CONFIG_PRINTK_TIME=y
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_TIMER_STATS=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_INFO=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_STRICT_DEVMEM=y
CONFIG_DEBUG_USER=y
CONFIG_KEYS=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC7=m
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121026/4d1aa881/attachment-0001.sig>

From dedekind1 at gmail.com  Fri Oct 26 09:56:28 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 26 Oct 2012 16:56:28 +0300
Subject: [PATCH] mtd: mkfs.ubifs: Improve error handling of is_contained()
In-Reply-To: <1350388261.25368.92.camel@lnxprebble2.se.axis.com>
References: <1350388261.25368.92.camel@lnxprebble2.se.axis.com>
Message-ID: <1351259788.1823.22.camel@sauron.fi.intel.com>

On Tue, 2012-10-16 at 13:51 +0200, Marcus Prebble wrote:
> mtd: mtd-utils/mkfs.ubifs: Improve error handling of is_contained()
> 
> The is_contained() function returns -1 if an error occurs when
> canonicalizing the output file path/root directory. This resulted in the
> confusing error message 'Error: The output file cannot be in the UBIFS
> root' when specifying a non-existent directory for the output.
> This patch changes the error handling to display a different error
> message for the case when is_contained() returns -1.
> Additionally it frees all memory allocated by is_contained().
> 
> Signed-off-by: Marcus Prebble <marcus.prebble at axis.com>

Pushed to mtd-utils.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121026/b7d27484/attachment.sig>

From dedekind1 at gmail.com  Fri Oct 26 10:22:06 2012
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 26 Oct 2012 17:22:06 +0300
Subject: [PATCH] mtd: use the NAND_STATUS_FAIL to replace the hardcode
In-Reply-To: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
References: <1350272844-21866-1-git-send-email-shijie8@gmail.com>
Message-ID: <1351261326.1823.24.camel@sauron.fi.intel.com>

On Sun, 2012-10-14 at 23:47 -0400, Huang Shijie wrote:
> Use the NAND_STATUS_FAIL to replace the hardcode "0x01",
> which make the code more readable.
> 
> Signed-off-by: Huang Shijie <shijie8 at gmail.com>

Pushed to l2-mtd.git, thanks!

-- 
Best Regards,
Artem Bityutskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121026/2289e845/attachment.sig>

From tony at atomide.com  Fri Oct 26 12:40:06 2012
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 26 Oct 2012 09:40:06 -0700
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of
 cpu_is
In-Reply-To: <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
References: <cover.1349672877.git.afzal@ti.com>
 <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
 <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
Message-ID: <20121026164005.GD11908@atomide.com>

* Paul Walmsley <paul at pwsan.com> [121025 18:50]:
> Hi Afzal
> 
> On Mon, 8 Oct 2012, Afzal Mohammed wrote:
> 
> > platform data now contains a field to indicate whether
> > soc belongs to omap34xx family, use it instead of
> > cpu_is_* check.
> > 
> > This helps in removing dependency of platform specific
> > header file - cpu.h
> > 
> > Signed-off-by: Afzal Mohammed <afzal at ti.com>
> 
> This one breaks an N800 multi-OMAP build here:
> 
>   LD      init/built-in.o
> drivers/built-in.o: In function `omap2_onenand_probe':
> /home/paul/linux-bisect/drivers/mtd/onenand/omap2.c:788: undefined 
> reference to `omap3_onenand_read_bufferram'
> /home/paul/linux-bisect/drivers/mtd/onenand/omap2.c:788: undefined 
> reference to `omap3_onenand_write_bufferram'
> make: *** [vmlinux] Error 1
> 
> A fix is below.

If you can add this too into your fixes branch on top of
omap-for-v3.8/cleanup-headers that would be nice.

Regards,

Tony

> ---
>  drivers/mtd/onenand/omap2.c |   18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 53069ae..f87cf39 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -445,13 +445,19 @@ out_copy:
>  
>  #else
>  
> -int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -				 unsigned char *buffer, int offset,
> -				 size_t count);
> +static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +					unsigned char *buffer, int offset,
> +					size_t count)
> +{
> +	return -ENOSYS;
> +}
>  
> -int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -				  const unsigned char *buffer,
> -				  int offset, size_t count);
> +static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +					 const unsigned char *buffer,
> +					 int offset, size_t count)
> +{
> +	return -ENOSYS;
> +}
>  
>  #endif
>  
> -- 
> 1.7.10.4
> 


From tony at atomide.com  Fri Oct 26 12:41:15 2012
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 26 Oct 2012 09:41:15 -0700
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of
 cpu_is
In-Reply-To: <alpine.DEB.2.00.1210260411140.27963@utopia.booyaka.com>
References: <cover.1349672877.git.afzal@ti.com>
 <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
 <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
 <alpine.DEB.2.00.1210260411140.27963@utopia.booyaka.com>
Message-ID: <20121026164115.GE11908@atomide.com>

* Paul Walmsley <paul at pwsan.com> [121025 22:05]:
> On Fri, 26 Oct 2012, Paul Walmsley wrote:
> 
> > On Mon, 8 Oct 2012, Afzal Mohammed wrote:
> > 
> > > platform data now contains a field to indicate whether
> > > soc belongs to omap34xx family, use it instead of
> > > cpu_is_* check.
> > > 
> > > This helps in removing dependency of platform specific
> > > header file - cpu.h
> > > 
> > > Signed-off-by: Afzal Mohammed <afzal at ti.com>
> > 
> > This one breaks an N800 multi-OMAP build here:
> 
> It also breaks an OMAP3+4 config:
> 
> drivers/built-in.o: In function `omap2_onenand_probe':
> /home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:742: 
> undefined reference to `omap2_onenand_read_bufferram'
> /home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:743: 
> undefined reference to `omap2_onenand_write_bufferram'
> /home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:742: 
> undefined reference to `omap2_onenand_read_bufferram'
> /home/paul/test_build/temp/test_cleanup_prcm_8634155e_with_fixes/20121025214236/linux/drivers/mtd/onenand/omap2.c:743: 
> undefined reference to `omap2_onenand_write_bufferram'
> 
> Fix below.

Thanks, I'd like to pull this fix in too along with the
others.

Regards,

Tony


 
>  drivers/mtd/onenand/omap2.c |   18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index f87cf39..99f96e1 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -555,13 +555,19 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  
>  #else
>  
> -int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -				 unsigned char *buffer, int offset,
> -				 size_t count);
> +static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +					unsigned char *buffer, int offset,
> +					size_t count)
> +{
> +	return -ENOSYS;
> +}
>  
> -int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -				  const unsigned char *buffer,
> -				  int offset, size_t count);
> +static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +					 const unsigned char *buffer,
> +					 int offset, size_t count)
> +{
> +	return -ENOSYS;
> +}
>  
>  #endif
>  
> -- 
> 1.7.10.4


From charvey at matrox.com  Fri Oct 26 15:36:43 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Fri, 26 Oct 2012 15:36:43 -0400
Subject: [PATCH v2] mtd: omap: nand: Remove 0xFF's that prefixed 16bit NAND
 commands
In-Reply-To: <20121026193410.GA21474@harvey-pc.matrox.com>
Message-ID: <20121026193643.GA21510@harvey-pc.matrox.com>

In 16bit NAND mode the GPMC would send the command 0xNN as 0xFFNN
instead of 0x00NN on the bus. The 0xFFs were actually uninitialized
bits that were left unset in the GPMC command output register. The
reason they weren't initialized in 16bit mode is that if the same code
that writes to this register was used in 8bit mode then 2 commands
would be output in 8bit mode. One for the low byte, and an extra 0x0
command for the high byte. This commit uses writew if we're using
16bit NAND.

Most chips seem fine with the extra 0xFFs, but the ONFI spec says
otherwise.

Signed-off-by: Christopher Harvey <charvey at matrox.com>
---
 drivers/mtd/nand/omap2.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..ae6738f 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -225,16 +225,20 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct omap_nand_info *info = container_of(mtd,
 					struct omap_nand_info, mtd);
+	void __iomem *reg;
 
 	if (cmd != NAND_CMD_NONE) {
 		if (ctrl & NAND_CLE)
-			writeb(cmd, info->reg.gpmc_nand_command);
-
+			reg = info->reg.gpmc_nand_command;
 		else if (ctrl & NAND_ALE)
-			writeb(cmd, info->reg.gpmc_nand_address);
-
+			reg = info->reg.gpmc_nand_address;
 		else /* NAND_NCE */
-			writeb(cmd, info->reg.gpmc_nand_data);
+			reg = info->reg.gpmc_nand_data;
+
+		if (info->nand.options & NAND_BUSWIDTH_16)
+			writew(cmd, reg);
+		else
+			writeb(cmd, reg);
 	}
 }
 
-- 
1.7.8.6


From charvey at matrox.com  Fri Oct 26 15:34:10 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Fri, 26 Oct 2012 15:34:10 -0400
Subject: [PATCH v2] 16 bit NAND fix, request for testers
Message-ID: <20121026193410.GA21474@harvey-pc.matrox.com>

just a small patch to access GPMC NAND registers with 16 bits when the
NAND is in 16 bit mode. I tested this on a 2.6.37 kernel, and noticed
it was still unpatched in the latest kernel. I don't have the hardware
setup or defconfigs to test this patch out, and even if I did I don't
have the logic analyzer setup to completely reproduce it on other
hardware with the latest kernel. It would be nice to get a tested-by
on this patch.

(CC'd mtd list this time)

Thanks.


Christopher Harvey (1):
  mtd: omap: nand: Remove 0xFF's that prefixed 16bit NAND commands

 drivers/mtd/nand/omap2.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

-- 
1.7.8.6


From charvey at matrox.com  Fri Oct 26 15:35:31 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Fri, 26 Oct 2012 15:35:31 -0400
Subject: [PATCH v2] mtd: omap: nand: Remove 0xFF's that prefixed 16bit NAND
 commands
In-Reply-To: <cover.1351278594.git.charvey@matrox.com>
References: <cover.1351278594.git.charvey@matrox.com>
Message-ID: <20121026193531.GA21481@harvey-pc.matrox.com>

In 16bit NAND mode the GPMC would send the command 0xNN as 0xFFNN
instead of 0x00NN on the bus. The 0xFFs were actually uninitialized
bits that were left unset in the GPMC command output register. The
reason they weren't initialized in 16bit mode is that if the same code
that writes to this register was used in 8bit mode then 2 commands
would be output in 8bit mode. One for the low byte, and an extra 0x0
command for the high byte. This commit uses writew if we're using
16bit NAND.

Most chips seem fine with the extra 0xFFs, but the ONFI spec says
otherwise.

Signed-off-by: Christopher Harvey <charvey at matrox.com>
---
 drivers/mtd/nand/omap2.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..ae6738f 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -225,16 +225,20 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct omap_nand_info *info = container_of(mtd,
 					struct omap_nand_info, mtd);
+	void __iomem *reg;
 
 	if (cmd != NAND_CMD_NONE) {
 		if (ctrl & NAND_CLE)
-			writeb(cmd, info->reg.gpmc_nand_command);
-
+			reg = info->reg.gpmc_nand_command;
 		else if (ctrl & NAND_ALE)
-			writeb(cmd, info->reg.gpmc_nand_address);
-
+			reg = info->reg.gpmc_nand_address;
 		else /* NAND_NCE */
-			writeb(cmd, info->reg.gpmc_nand_data);
+			reg = info->reg.gpmc_nand_data;
+
+		if (info->nand.options & NAND_BUSWIDTH_16)
+			writew(cmd, reg);
+		else
+			writeb(cmd, reg);
 	}
 }
 
-- 
1.7.8.6


From akinobu.mita at gmail.com  Sun Oct 28 03:19:01 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:01 +0900
Subject: [PATCH 4/9] mtd: nandsim: use random32_get_bytes
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-4-git-send-email-akinobu.mita@gmail.com>

This also removes unnecessary memset call which is immediately overwritten
with random bytes.

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/nand/nandsim.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index a932c48..d074b4c 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -1397,10 +1397,7 @@ int do_read_error(struct nandsim *ns, int num)
 	unsigned int page_no = ns->regs.row;
 
 	if (read_error(page_no)) {
-		int i;
-		memset(ns->buf.byte, 0xFF, num);
-		for (i = 0; i < num; ++i)
-			ns->buf.byte[i] = random32();
+		random32_get_bytes(ns->buf.byte, num);
 		NS_WARN("simulating read error in page %u\n", page_no);
 		return 1;
 	}
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:18:58 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:18:58 +0900
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
Message-ID: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>

Add functions to get the requested number of pseudo-random bytes.

The difference from get_random_bytes() is that it uses pseudo-random
numbers generated by random32.  It is fast, suitable for generating
random bytes for testing, and reproducible if prandom32 interface is used.

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: "Theodore Ts'o" <tytso at mit.edu>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: Adrian Hunter <adrian.hunter at intel.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 include/linux/random.h |  2 ++
 lib/random32.c         | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/include/linux/random.h b/include/linux/random.h
index 6330ed4..eedf429b 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -27,8 +27,10 @@ unsigned long randomize_range(unsigned long start, unsigned long end, unsigned l
 
 u32 random32(void);
 void srandom32(u32 seed);
+void random32_get_bytes(void *buf, int nbytes);
 
 u32 prandom32(struct rnd_state *);
+void prandom32_get_bytes(struct rnd_state *state, void *buf, int nbytes);
 
 /*
  * Handle minimum values for seeds
diff --git a/lib/random32.c b/lib/random32.c
index 938bde5..aee87dd 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -61,6 +61,44 @@ u32 prandom32(struct rnd_state *state)
 EXPORT_SYMBOL(prandom32);
 
 /**
+ *	prandom32_get_bytes - get the requested number of pseudo-random bytes
+ *	@state: pointer to state structure holding seeded state.
+ *	@buf: where to copy the pseudo-random bytes to
+ *	@bytes: the requested number of bytes
+ *
+ *	This is used for pseudo-randomness with no outside seeding.
+ *	For more random results, use random32_get_bytes().
+ */
+void prandom32_get_bytes(struct rnd_state *state, void *buf, int bytes)
+{
+	unsigned char *p = buf;
+
+	for (; bytes > 0 && ((unsigned long)p) % sizeof(u32); bytes--, p++)
+		*p = prandom32(state);
+
+	for (; bytes > sizeof(u32) - 1; bytes -= sizeof(u32), p += sizeof(u32))
+		*(u32 *)p = prandom32(state);
+
+	for (; bytes > 0; bytes--, p++)
+		*p = prandom32(state);
+}
+EXPORT_SYMBOL(prandom32_get_bytes);
+
+/**
+ *	random32_get_bytes - get the requested number of pseudo-random bytes
+ *	@buf: where to copy the pseudo-random bytes to
+ *	@bytes: the requested number of bytes
+ */
+void random32_get_bytes(void *buf, int bytes)
+{
+	struct rnd_state *state = &get_cpu_var(net_rand_state);
+
+	prandom32_get_bytes(state, buf, bytes);
+	put_cpu_var(state);
+}
+EXPORT_SYMBOL(random32_get_bytes);
+
+/**
  *	random32 - pseudo random number generator
  *
  *	A 32 bit pseudo-random number is generated using a fast
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:00 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:00 +0900
Subject: [PATCH 3/9] mtd: mtd_nandecctest: use random32_get_bytes instead of
 get_random_bytes()
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-3-git-send-email-akinobu.mita@gmail.com>

Using random32_get_bytes() is enough.  Because this data is only used
for testing, not used for cryptographic use.

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/tests/mtd_nandecctest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index a5fb9b0..0ddcbec 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -253,7 +253,7 @@ static int nand_ecc_test_run(const size_t size)
 		goto error;
 	}
 
-	get_random_bytes(correct_data, size);
+	random32_get_bytes(correct_data, size);
 	__nand_calculate_ecc(correct_data, size, correct_ecc);
 
 	for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) {
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:02 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:02 +0900
Subject: [PATCH 5/9] ubifs: use random32_get_bytes
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-5-git-send-email-akinobu.mita@gmail.com>

This also converts filling memory loop to use memset.

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: Adrian Hunter <adrian.hunter at intel.com>
Cc: linux-mtd at lists.infradead.org
---
 fs/ubifs/debug.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 6291163..f3e4a25 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2560,7 +2560,7 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
 static int corrupt_data(const struct ubifs_info *c, const void *buf,
 			unsigned int len)
 {
-	unsigned int from, to, i, ffs = chance(1, 2);
+	unsigned int from, to, ffs = chance(1, 2);
 	unsigned char *p = (void *)buf;
 
 	from = random32() % (len + 1);
@@ -2571,11 +2571,9 @@ static int corrupt_data(const struct ubifs_info *c, const void *buf,
 		   ffs ? "0xFFs" : "random data");
 
 	if (ffs)
-		for (i = from; i < to; i++)
-			p[i] = 0xFF;
+		memset(p + from, 0xFF, to - from);
 	else
-		for (i = from; i < to; i++)
-			p[i] = random32() % 0x100;
+		random32_get_bytes(p + from, to - from);
 
 	return to;
 }
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:03 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:03 +0900
Subject: [PATCH 6/9] mtd: mtd_oobtest: convert to use prandom32_get_bytes()
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-6-git-send-email-akinobu.mita@gmail.com>

This removes home-brewed pseudo-random number generator and use
prandom32_get_bytes().

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/tests/mtd_oobtest.c | 49 ++++++++++++++---------------------------
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index ed9b628..41670ed 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/random.h>
 
 #define PRINT_PREF KERN_INFO "mtd_oobtest: "
 
@@ -46,26 +47,7 @@ static int use_offset;
 static int use_len;
 static int use_len_max;
 static int vary_offset;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
-	next = seed;
-}
-
-static void set_random_data(unsigned char *buf, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; ++i)
-		buf[i] = simple_rand();
-}
+static struct rnd_state rnd_state;
 
 static int erase_eraseblock(int ebnum)
 {
@@ -130,7 +112,7 @@ static int write_eraseblock(int ebnum)
 	loff_t addr = ebnum * mtd->erasesize;
 
 	for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
-		set_random_data(writebuf, use_len);
+		prandom32_get_bytes(&rnd_state, writebuf, use_len);
 		ops.mode      = MTD_OPS_AUTO_OOB;
 		ops.len       = 0;
 		ops.retlen    = 0;
@@ -183,7 +165,7 @@ static int verify_eraseblock(int ebnum)
 	loff_t addr = ebnum * mtd->erasesize;
 
 	for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
-		set_random_data(writebuf, use_len);
+		prandom32_get_bytes(&rnd_state, writebuf, use_len);
 		ops.mode      = MTD_OPS_AUTO_OOB;
 		ops.len       = 0;
 		ops.retlen    = 0;
@@ -275,7 +257,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
 	loff_t addr = ebnum * mtd->erasesize;
 	size_t len = mtd->ecclayout->oobavail * pgcnt;
 
-	set_random_data(writebuf, len);
+	prandom32_get_bytes(&rnd_state, writebuf, len);
 	ops.mode      = MTD_OPS_AUTO_OOB;
 	ops.len       = 0;
 	ops.retlen    = 0;
@@ -426,12 +408,12 @@ static int __init mtd_oobtest_init(void)
 	if (err)
 		goto out;
 
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	err = write_whole_device();
 	if (err)
 		goto out;
 
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	err = verify_all_eraseblocks();
 	if (err)
 		goto out;
@@ -446,13 +428,13 @@ static int __init mtd_oobtest_init(void)
 	if (err)
 		goto out;
 
-	simple_srand(3);
+	prandom32_seed(&rnd_state, 3);
 	err = write_whole_device();
 	if (err)
 		goto out;
 
 	/* Check all eraseblocks */
-	simple_srand(3);
+	prandom32_seed(&rnd_state, 3);
 	printk(PRINT_PREF "verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -481,7 +463,7 @@ static int __init mtd_oobtest_init(void)
 	use_len = mtd->ecclayout->oobavail;
 	use_len_max = mtd->ecclayout->oobavail;
 	vary_offset = 1;
-	simple_srand(5);
+	prandom32_seed(&rnd_state, 5);
 
 	err = write_whole_device();
 	if (err)
@@ -492,7 +474,7 @@ static int __init mtd_oobtest_init(void)
 	use_len = mtd->ecclayout->oobavail;
 	use_len_max = mtd->ecclayout->oobavail;
 	vary_offset = 1;
-	simple_srand(5);
+	prandom32_seed(&rnd_state, 5);
 	err = verify_all_eraseblocks();
 	if (err)
 		goto out;
@@ -651,7 +633,7 @@ static int __init mtd_oobtest_init(void)
 		goto out;
 
 	/* Write all eraseblocks */
-	simple_srand(11);
+	prandom32_seed(&rnd_state, 11);
 	printk(PRINT_PREF "writing OOBs of whole device\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		int cnt = 2;
@@ -661,7 +643,7 @@ static int __init mtd_oobtest_init(void)
 			continue;
 		addr = (i + 1) * mtd->erasesize - mtd->writesize;
 		for (pg = 0; pg < cnt; ++pg) {
-			set_random_data(writebuf, sz);
+			prandom32_get_bytes(&rnd_state, writebuf, sz);
 			ops.mode      = MTD_OPS_AUTO_OOB;
 			ops.len       = 0;
 			ops.retlen    = 0;
@@ -683,12 +665,13 @@ static int __init mtd_oobtest_init(void)
 	printk(PRINT_PREF "written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
-	simple_srand(11);
+	prandom32_seed(&rnd_state, 11);
 	printk(PRINT_PREF "verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt - 1; ++i) {
 		if (bbt[i] || bbt[i + 1])
 			continue;
-		set_random_data(writebuf, mtd->ecclayout->oobavail * 2);
+		prandom32_get_bytes(&rnd_state, writebuf,
+					mtd->ecclayout->oobavail * 2);
 		addr = (i + 1) * mtd->erasesize - mtd->writesize;
 		ops.mode      = MTD_OPS_AUTO_OOB;
 		ops.len       = 0;
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:04 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:04 +0900
Subject: [PATCH 7/9] mtd: mtd_pagetest: convert to use prandom32_get_bytes()
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-7-git-send-email-akinobu.mita@gmail.com>

This removes home-brewed pseudo-random number generator and use
prandom32_get_bytes().

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/tests/mtd_pagetest.c | 43 ++++++++++++----------------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c
index 252ddb0..ae390c3 100644
--- a/drivers/mtd/tests/mtd_pagetest.c
+++ b/drivers/mtd/tests/mtd_pagetest.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/random.h>
 
 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
 
@@ -45,26 +46,7 @@ static int bufsize;
 static int ebcnt;
 static int pgcnt;
 static int errcnt;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
-	next = seed;
-}
-
-static void set_random_data(unsigned char *buf, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; ++i)
-		buf[i] = simple_rand();
-}
+static struct rnd_state rnd_state;
 
 static int erase_eraseblock(int ebnum)
 {
@@ -98,7 +80,7 @@ static int write_eraseblock(int ebnum)
 	size_t written;
 	loff_t addr = ebnum * mtd->erasesize;
 
-	set_random_data(writebuf, mtd->erasesize);
+	prandom32_get_bytes(&rnd_state, writebuf, mtd->erasesize);
 	cond_resched();
 	err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf);
 	if (err || written != mtd->erasesize)
@@ -124,7 +106,7 @@ static int verify_eraseblock(int ebnum)
 	for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i)
 		addrn -= mtd->erasesize;
 
-	set_random_data(writebuf, mtd->erasesize);
+	prandom32_get_bytes(&rnd_state, writebuf, mtd->erasesize);
 	for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) {
 		/* Do a read to set the internal dataRAMs to different data */
 		err = mtd_read(mtd, addr0, bufsize, &read, twopages);
@@ -160,7 +142,8 @@ static int verify_eraseblock(int ebnum)
 	}
 	/* Check boundary between eraseblocks */
 	if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) {
-		unsigned long oldnext = next;
+		struct rnd_state old_state = rnd_state;
+
 		/* Do a read to set the internal dataRAMs to different data */
 		err = mtd_read(mtd, addr0, bufsize, &read, twopages);
 		if (mtd_is_bitflip(err))
@@ -188,13 +171,13 @@ static int verify_eraseblock(int ebnum)
 			return err;
 		}
 		memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize);
-		set_random_data(boundary + pgsize, pgsize);
+		prandom32_get_bytes(&rnd_state, boundary + pgsize, pgsize);
 		if (memcmp(twopages, boundary, bufsize)) {
 			printk(PRINT_PREF "error: verify failed at %#llx\n",
 			       (long long)addr);
 			errcnt += 1;
 		}
-		next = oldnext;
+		rnd_state = old_state;
 	}
 	return err;
 }
@@ -326,7 +309,7 @@ static int erasecrosstest(void)
 		return err;
 
 	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
-	set_random_data(writebuf, pgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
@@ -359,7 +342,7 @@ static int erasecrosstest(void)
 		return err;
 
 	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
-	set_random_data(writebuf, pgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, pgsize);
 	strcpy(writebuf, "There is no data like this!");
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
@@ -417,7 +400,7 @@ static int erasetest(void)
 		return err;
 
 	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
-	set_random_data(writebuf, pgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, pgsize);
 	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
 	if (err || written != pgsize) {
 		printk(PRINT_PREF "error: write failed at %#llx\n",
@@ -565,7 +548,7 @@ static int __init mtd_pagetest_init(void)
 	printk(PRINT_PREF "erased %u eraseblocks\n", i);
 
 	/* Write all eraseblocks */
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	printk(PRINT_PREF "writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -580,7 +563,7 @@ static int __init mtd_pagetest_init(void)
 	printk(PRINT_PREF "written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	printk(PRINT_PREF "verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:05 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:05 +0900
Subject: [PATCH 8/9] mtd: mtd_speedtest: use random32_get_bytes
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-8-git-send-email-akinobu.mita@gmail.com>

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/tests/mtd_speedtest.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 42b0f74..57f0383 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -49,13 +49,6 @@ static int pgcnt;
 static int goodebcnt;
 static struct timeval start, finish;
 
-static void set_random_data(unsigned char *buf, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; ++i)
-		buf[i] = random32();
-}
 
 static int erase_eraseblock(int ebnum)
 {
@@ -396,7 +389,7 @@ static int __init mtd_speedtest_init(void)
 		goto out;
 	}
 
-	set_random_data(iobuf, mtd->erasesize);
+	random32_get_bytes(iobuf, mtd->erasesize);
 
 	err = scan_for_bad_eraseblocks();
 	if (err)
-- 
1.7.11.7



From akinobu.mita at gmail.com  Sun Oct 28 03:19:06 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Sun, 28 Oct 2012 16:19:06 +0900
Subject: [PATCH 9/9] mtd: mtd_subpagetest: convert to use prandom32_get_bytes()
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <1351408746-8623-9-git-send-email-akinobu.mita@gmail.com>

This removes home-brewed pseudo-random number generator and use
prandom32_get_bytes().

Signed-off-by: Akinobu Mita <akinobu.mita at gmail.com>
Cc: Artem Bityutskiy <dedekind1 at gmail.com>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
---
 drivers/mtd/tests/mtd_subpagetest.c | 42 +++++++++++--------------------------
 1 file changed, 12 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c
index 9667bf5..86a7140 100644
--- a/drivers/mtd/tests/mtd_subpagetest.c
+++ b/drivers/mtd/tests/mtd_subpagetest.c
@@ -26,6 +26,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/random.h>
 
 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
 
@@ -43,26 +44,7 @@ static int bufsize;
 static int ebcnt;
 static int pgcnt;
 static int errcnt;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
-	next = seed;
-}
-
-static void set_random_data(unsigned char *buf, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; ++i)
-		buf[i] = simple_rand();
-}
+static struct rnd_state rnd_state;
 
 static inline void clear_data(unsigned char *buf, size_t len)
 {
@@ -119,7 +101,7 @@ static int write_eraseblock(int ebnum)
 	int err = 0;
 	loff_t addr = ebnum * mtd->erasesize;
 
-	set_random_data(writebuf, subpgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
 		printk(PRINT_PREF "error: write failed at %#llx\n",
@@ -133,7 +115,7 @@ static int write_eraseblock(int ebnum)
 
 	addr += subpgsize;
 
-	set_random_data(writebuf, subpgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, subpgsize);
 	err = mtd_write(mtd, addr, subpgsize, &written, writebuf);
 	if (unlikely(err || written != subpgsize)) {
 		printk(PRINT_PREF "error: write failed at %#llx\n",
@@ -157,7 +139,7 @@ static int write_eraseblock2(int ebnum)
 	for (k = 1; k < 33; ++k) {
 		if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
 			break;
-		set_random_data(writebuf, subpgsize * k);
+		prandom32_get_bytes(&rnd_state, writebuf, subpgsize * k);
 		err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
 		if (unlikely(err || written != subpgsize * k)) {
 			printk(PRINT_PREF "error: write failed at %#llx\n",
@@ -193,7 +175,7 @@ static int verify_eraseblock(int ebnum)
 	int err = 0;
 	loff_t addr = ebnum * mtd->erasesize;
 
-	set_random_data(writebuf, subpgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, subpgsize);
 	clear_data(readbuf, subpgsize);
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
@@ -220,7 +202,7 @@ static int verify_eraseblock(int ebnum)
 
 	addr += subpgsize;
 
-	set_random_data(writebuf, subpgsize);
+	prandom32_get_bytes(&rnd_state, writebuf, subpgsize);
 	clear_data(readbuf, subpgsize);
 	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
 	if (unlikely(err || read != subpgsize)) {
@@ -257,7 +239,7 @@ static int verify_eraseblock2(int ebnum)
 	for (k = 1; k < 33; ++k) {
 		if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
 			break;
-		set_random_data(writebuf, subpgsize * k);
+		prandom32_get_bytes(&rnd_state, writebuf, subpgsize * k);
 		clear_data(readbuf, subpgsize * k);
 		err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
 		if (unlikely(err || read != subpgsize * k)) {
@@ -430,7 +412,7 @@ static int __init mtd_subpagetest_init(void)
 		goto out;
 
 	printk(PRINT_PREF "writing whole device\n");
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
 			continue;
@@ -443,7 +425,7 @@ static int __init mtd_subpagetest_init(void)
 	}
 	printk(PRINT_PREF "written %u eraseblocks\n", i);
 
-	simple_srand(1);
+	prandom32_seed(&rnd_state, 1);
 	printk(PRINT_PREF "verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -466,7 +448,7 @@ static int __init mtd_subpagetest_init(void)
 		goto out;
 
 	/* Write all eraseblocks */
-	simple_srand(3);
+	prandom32_seed(&rnd_state, 3);
 	printk(PRINT_PREF "writing whole device\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
@@ -481,7 +463,7 @@ static int __init mtd_subpagetest_init(void)
 	printk(PRINT_PREF "written %u eraseblocks\n", i);
 
 	/* Check all eraseblocks */
-	simple_srand(3);
+	prandom32_seed(&rnd_state, 3);
 	printk(PRINT_PREF "verifying all eraseblocks\n");
 	for (i = 0; i < ebcnt; ++i) {
 		if (bbt[i])
-- 
1.7.11.7



From x0148406 at ti.com  Mon Oct 29 04:06:59 2012
From: x0148406 at ti.com (Afzal Mohammed)
Date: Mon, 29 Oct 2012 13:36:59 +0530
Subject: [PATCH v2 06/14] mtd: onenand: omap: use pdata info instead of
 cpu_is
In-Reply-To: <20121026164115.GE11908@atomide.com>
References: <cover.1349672877.git.afzal@ti.com>
 <860ba92c34cbb490beccd5442087087c1751a6a2.1349672877.git.afzal@ti.com>
 <alpine.DEB.2.00.1210260146270.11251@utopia.booyaka.com>
 <alpine.DEB.2.00.1210260411140.27963@utopia.booyaka.com>
 <20121026164115.GE11908@atomide.com>
Message-ID: <508E3923.4020209@ti.com>


On Friday 26 October 2012 10:11 PM, Tony Lindgren wrote:
> * Paul Walmsley<paul at pwsan.com>  [121025 22:05]:

>> It also breaks an OMAP3+4 config:

>> Fix below.
> Thanks, I'd like to pull this fix in too along with the
> others.

Thanks Paul and Tony for taking care of this issue.

I am sorry about the issue and had been on vacation
last week.

Regards
Afzal


From ivan.djelic at parrot.com  Mon Oct 29 09:49:03 2012
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Mon, 29 Oct 2012 14:49:03 +0100
Subject: [PATCH v2] mtd: omap: nand: Remove 0xFF's that prefixed 16bit
 NAND commands
In-Reply-To: <20121026193643.GA21510@harvey-pc.matrox.com>
References: <20121026193410.GA21474@harvey-pc.matrox.com>
 <20121026193643.GA21510@harvey-pc.matrox.com>
Message-ID: <20121029134903.GA30857@parrot.com>

On Fri, Oct 26, 2012 at 08:36:43PM +0100, Christopher Harvey wrote:
> In 16bit NAND mode the GPMC would send the command 0xNN as 0xFFNN
> instead of 0x00NN on the bus. The 0xFFs were actually uninitialized
> bits that were left unset in the GPMC command output register. The
> reason they weren't initialized in 16bit mode is that if the same code
> that writes to this register was used in 8bit mode then 2 commands
> would be output in 8bit mode. One for the low byte, and an extra 0x0
> command for the high byte. This commit uses writew if we're using
> 16bit NAND.
> 
> Most chips seem fine with the extra 0xFFs, but the ONFI spec says
> otherwise.

Hi Christopher,

Nitpick: I think you should replace 'command' with 'address' in your commit message.
The ONFI spec says Host should send _address_ byte NN as 0x00NN. It is OK to send
command NN as 0xFFNN, as explicitly mentioned in ONFI 3.1 spec (section 2.16):

  2.16.          Bus Width Requirements
All NAND Targets per device shall use the same data bus width. All targets shall either have an
8-bit bus width or a 16-bit bus width. Note that devices that support the NV-DDR or NV-DDR2
data interface shall have an 8-bit bus width.
When the host supports a 16-bit bus width, only data is transferred at the 16-bit width. All
address and command line transfers shall use only the lower 8-bits of the data bus. During
command transfers, the host may place any value on the upper 8-bits of the data bus. During
address transfers, the host shall set the upper 8-bits of the data bus to 00h.

Your patch deals with both command and address bytes, which does not hurt.
BR,
--
Ivan

> 
> Signed-off-by: Christopher Harvey <charvey at matrox.com>
> ---
>  drivers/mtd/nand/omap2.c |   14 +++++++++-----
>  1 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 5b31386..ae6738f 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -225,16 +225,20 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
>  {
>  	struct omap_nand_info *info = container_of(mtd,
>  					struct omap_nand_info, mtd);
> +	void __iomem *reg;
>  
>  	if (cmd != NAND_CMD_NONE) {
>  		if (ctrl & NAND_CLE)
> -			writeb(cmd, info->reg.gpmc_nand_command);
> -
> +			reg = info->reg.gpmc_nand_command;
>  		else if (ctrl & NAND_ALE)
> -			writeb(cmd, info->reg.gpmc_nand_address);
> -
> +			reg = info->reg.gpmc_nand_address;
>  		else /* NAND_NCE */
> -			writeb(cmd, info->reg.gpmc_nand_data);
> +			reg = info->reg.gpmc_nand_data;
> +
> +		if (info->nand.options & NAND_BUSWIDTH_16)
> +			writew(cmd, reg);
> +		else
> +			writeb(cmd, reg);
>  	}
>  }
>  
> -- 
> 1.7.8.6
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/


From charvey at matrox.com  Mon Oct 29 13:04:58 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Mon, 29 Oct 2012 13:04:58 -0400
Subject: [PATCH v2] mtd: omap: nand: Remove 0xFF's that prefixed 16bit
 NAND commands
In-Reply-To: <20121029134903.GA30857@parrot.com>
References: <20121026193410.GA21474@harvey-pc.matrox.com>
 <20121026193643.GA21510@harvey-pc.matrox.com>
 <20121029134903.GA30857@parrot.com>
Message-ID: <20121029170458.GB2650@harvey-pc.matrox.com>

On Mon, Oct 29, 2012 at 02:49:03PM +0100, Ivan Djelic wrote:
> On Fri, Oct 26, 2012 at 08:36:43PM +0100, Christopher Harvey wrote:
> > In 16bit NAND mode the GPMC would send the command 0xNN as 0xFFNN
> > instead of 0x00NN on the bus. The 0xFFs were actually uninitialized
> > bits that were left unset in the GPMC command output register. The
> > reason they weren't initialized in 16bit mode is that if the same code
> > that writes to this register was used in 8bit mode then 2 commands
> > would be output in 8bit mode. One for the low byte, and an extra 0x0
> > command for the high byte. This commit uses writew if we're using
> > 16bit NAND.
> > 
> > Most chips seem fine with the extra 0xFFs, but the ONFI spec says
> > otherwise.
> 
> Hi Christopher,
> 
> Nitpick: I think you should replace 'command' with 'address' in your commit message.
> The ONFI spec says Host should send _address_ byte NN as 0x00NN. It is OK to send
> command NN as 0xFFNN, as explicitly mentioned in ONFI 3.1 spec (section 2.16):
> 
>   2.16.          Bus Width Requirements
> All NAND Targets per device shall use the same data bus width. All targets shall either have an
> 8-bit bus width or a 16-bit bus width. Note that devices that support the NV-DDR or NV-DDR2
> data interface shall have an 8-bit bus width.
> When the host supports a 16-bit bus width, only data is transferred at the 16-bit width. All
> address and command line transfers shall use only the lower 8-bits of the data bus. During
> command transfers, the host may place any value on the upper 8-bits of the data bus. During
> address transfers, the host shall set the upper 8-bits of the data bus to 00h.
> 
> Your patch deals with both command and address bytes, which does not hurt.
> BR,
> --
> Ivan

Ok, makes sense. Thanks for pointing that out. I'll update the wording.

> > 
> > Signed-off-by: Christopher Harvey <charvey at matrox.com>
> > ---
> >  drivers/mtd/nand/omap2.c |   14 +++++++++-----
> >  1 files changed, 9 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index 5b31386..ae6738f 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -225,16 +225,20 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
> >  {
> >  	struct omap_nand_info *info = container_of(mtd,
> >  					struct omap_nand_info, mtd);
> > +	void __iomem *reg;
> >  
> >  	if (cmd != NAND_CMD_NONE) {
> >  		if (ctrl & NAND_CLE)
> > -			writeb(cmd, info->reg.gpmc_nand_command);
> > -
> > +			reg = info->reg.gpmc_nand_command;
> >  		else if (ctrl & NAND_ALE)
> > -			writeb(cmd, info->reg.gpmc_nand_address);
> > -
> > +			reg = info->reg.gpmc_nand_address;
> >  		else /* NAND_NCE */
> > -			writeb(cmd, info->reg.gpmc_nand_data);
> > +			reg = info->reg.gpmc_nand_data;
> > +
> > +		if (info->nand.options & NAND_BUSWIDTH_16)
> > +			writew(cmd, reg);
> > +		else
> > +			writeb(cmd, reg);
> >  	}
> >  }
> >  
> > -- 
> > 1.7.8.6
> > 


From viresh.kumar at linaro.org  Mon Oct 29 13:17:26 2012
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 29 Oct 2012 22:47:26 +0530
Subject: [PATCH] mtd: map: Fix compilation warning
Message-ID: <dd11b4d47ab566931cb943dea34e67c1ce2c3e59.1351530856.git.viresh.kumar@linaro.org>

This patch is an attempt to fix following compilation warning.

In file included from drivers/mtd/chips/cfi_cmdset_0001.c:35:0:
drivers/mtd/chips/cfi_cmdset_0001.c: In function 'cfi_intelext_write_words':
include/linux/mtd/map.h:331:11: warning: 'r.x[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]

I could have used uninitialized_var() too, but didn't used it as the final else
part of map_word_load() is missing. So there is a chance that it might be passed
uninitialized. Better initialize to zero.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 include/linux/mtd/map.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 3595a02..56c7936 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -328,7 +328,7 @@ static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word
 
 static inline map_word map_word_load(struct map_info *map, const void *ptr)
 {
-	map_word r;
+	map_word r = {{0} };
 
 	if (map_bankwidth_is_1(map))
 		r.x[0] = *(unsigned char *)ptr;
-- 
1.7.12.rc2.18.g61b472e



From charvey at matrox.com  Mon Oct 29 15:51:27 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Mon, 29 Oct 2012 15:51:27 -0400
Subject: [PATCH v3] mtd: omap: nand: Remove 0xFF's that prefixed 16bit NAND
 addresses
In-Reply-To: <20121026193410.GA21474@harvey-pc.matrox.com>
Message-ID: <20121029195127.GA32749@harvey-pc.matrox.com>

In 16bit NAND mode the GPMC would send the address 0xNN as 0xFFNN
instead of 0x00NN on the bus. The 0xFFs were actually uninitialized
bits that were left unset in the GPMC command output register. The
reason they weren't initialized in 16bit mode is that if the same code
that writes to this register was used in 8bit mode then 2 commands
would be output in 8bit mode. One for the low byte, and an extra 0x0
command for the high byte. This commit uses writew if we're using
16bit NAND. This commit also changes the high byte in the command
output register, but they are ignored by NAND chips anyway.

Most chips seem fine with the extra 0xFFs, but the ONFI spec says
otherwise.

Signed-off-by: Christopher Harvey <charvey at matrox.com>
---
 drivers/mtd/nand/omap2.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5b31386..ae6738f 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -225,16 +225,20 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
 	struct omap_nand_info *info = container_of(mtd,
 					struct omap_nand_info, mtd);
+	void __iomem *reg;
 
 	if (cmd != NAND_CMD_NONE) {
 		if (ctrl & NAND_CLE)
-			writeb(cmd, info->reg.gpmc_nand_command);
-
+			reg = info->reg.gpmc_nand_command;
 		else if (ctrl & NAND_ALE)
-			writeb(cmd, info->reg.gpmc_nand_address);
-
+			reg = info->reg.gpmc_nand_address;
 		else /* NAND_NCE */
-			writeb(cmd, info->reg.gpmc_nand_data);
+			reg = info->reg.gpmc_nand_data;
+
+		if (info->nand.options & NAND_BUSWIDTH_16)
+			writew(cmd, reg);
+		else
+			writeb(cmd, reg);
 	}
 }
 
-- 
1.7.8.6


From charvey at matrox.com  Mon Oct 29 16:42:27 2012
From: charvey at matrox.com (Christopher Harvey)
Date: Mon, 29 Oct 2012 16:42:27 -0400
Subject: state of support for "external ECC hardware"
Message-ID: <20121029204227.GA32300@harvey-pc.matrox.com>

I know of at least one Micron NAND chip that has the ability to handle
ECC completely on the NAND chip itself. All the host has to do is send
data and the OOB section is updated automatically. The automatic ECC
hardware can be enabled and disabled with the "Set Feature" command,
(0xEF) and bit flips are reported via get status after page reads. I
don't see support for this in 2.6.37, and a quick check in the logs
doesn't show anything new for these chips in the latest version of the
kernel. Any idea floating around on this list? Are these chips going
to be the future for NAND and does Linux care about them?

thanks,
Chris


From tytso at mit.edu  Mon Oct 29 16:39:37 2012
From: tytso at mit.edu (Theodore Ts'o)
Date: Mon, 29 Oct 2012 16:39:37 -0400
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
In-Reply-To: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
Message-ID: <20121029203937.GC7098@thunk.org>

On Sun, Oct 28, 2012 at 04:18:58PM +0900, Akinobu Mita wrote:
>  /**
> + *	prandom32_get_bytes - get the requested number of pseudo-random bytes
> + *	@state: pointer to state structure holding seeded state.
> + *	@buf: where to copy the pseudo-random bytes to
> + *	@bytes: the requested number of bytes
> + *
> + *	This is used for pseudo-randomness with no outside seeding.
> + *	For more random results, use random32_get_bytes().
> + */
> +
> +/**
> + *	random32_get_bytes - get the requested number of pseudo-random bytes
> + *	@buf: where to copy the pseudo-random bytes to
> + *	@bytes: the requested number of bytes
> + */

This naming scheme is going to be very confusing.  If the function is
going to return a pseudo-random number, it *must* have a "prandom"
suffix.  Otherwise some kernel developer, somewhere, will get confused
between get_random_bytes() and random32_get_bytes(), and the result
may be a very embarassing security exposure.

How about prandom32_get_bytes_state() and prandom32_get_bytes() instead?

						- Ted


From akinobu.mita at gmail.com  Tue Oct 30 07:01:01 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Tue, 30 Oct 2012 20:01:01 +0900
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
In-Reply-To: <20121029203937.GC7098@thunk.org>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
 <20121029203937.GC7098@thunk.org>
Message-ID: <CAC5umyhje4oDtKzw6kYSXw99rVzZJOaeApfizGeDos3SnmUcjA@mail.gmail.com>

2012/10/30 Theodore Ts'o <tytso at mit.edu>:
> On Sun, Oct 28, 2012 at 04:18:58PM +0900, Akinobu Mita wrote:
>>  /**
>> + *   prandom32_get_bytes - get the requested number of pseudo-random bytes
>> + *   @state: pointer to state structure holding seeded state.
>> + *   @buf: where to copy the pseudo-random bytes to
>> + *   @bytes: the requested number of bytes
>> + *
>> + *   This is used for pseudo-randomness with no outside seeding.
>> + *   For more random results, use random32_get_bytes().
>> + */
>> +
>> +/**
>> + *   random32_get_bytes - get the requested number of pseudo-random bytes
>> + *   @buf: where to copy the pseudo-random bytes to
>> + *   @bytes: the requested number of bytes
>> + */
>
> This naming scheme is going to be very confusing.  If the function is
> going to return a pseudo-random number, it *must* have a "prandom"
> suffix.  Otherwise some kernel developer, somewhere, will get confused
> between get_random_bytes() and random32_get_bytes(), and the result
> may be a very embarassing security exposure.
>
> How about prandom32_get_bytes_state() and prandom32_get_bytes() instead?

I agree with your suggestion.  I'll rename them and try again.

By the way, should we also rename the existing random32() and
prandom32() in the future?

Specifically, rename random32() to prandom32(), and prandom32() to
prandom32_state().  As a result, it will cause a little confusion
between old and new prandom32(). But the number of arguments will
be changed from 3 to 2, so gcc can detect the misuse of prandom32().

Is there any other idea of renaming? Or should we keep them as is?


From akinobu.mita at gmail.com  Tue Oct 30 07:12:39 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Tue, 30 Oct 2012 20:12:39 +0900
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
In-Reply-To: <CAC5umyhje4oDtKzw6kYSXw99rVzZJOaeApfizGeDos3SnmUcjA@mail.gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
 <20121029203937.GC7098@thunk.org>
 <CAC5umyhje4oDtKzw6kYSXw99rVzZJOaeApfizGeDos3SnmUcjA@mail.gmail.com>
Message-ID: <CAC5umyi=f+Q2Dxc4KS8nKd8uD3yvVNf8M9g1-nBt+6UsqSGHdg@mail.gmail.com>

2012/10/30 Akinobu Mita <akinobu.mita at gmail.com>:
> 2012/10/30 Theodore Ts'o <tytso at mit.edu>:
>> On Sun, Oct 28, 2012 at 04:18:58PM +0900, Akinobu Mita wrote:
>>>  /**
>>> + *   prandom32_get_bytes - get the requested number of pseudo-random bytes
>>> + *   @state: pointer to state structure holding seeded state.
>>> + *   @buf: where to copy the pseudo-random bytes to
>>> + *   @bytes: the requested number of bytes
>>> + *
>>> + *   This is used for pseudo-randomness with no outside seeding.
>>> + *   For more random results, use random32_get_bytes().
>>> + */
>>> +
>>> +/**
>>> + *   random32_get_bytes - get the requested number of pseudo-random bytes
>>> + *   @buf: where to copy the pseudo-random bytes to
>>> + *   @bytes: the requested number of bytes
>>> + */
>>
>> This naming scheme is going to be very confusing.  If the function is
>> going to return a pseudo-random number, it *must* have a "prandom"
>> suffix.  Otherwise some kernel developer, somewhere, will get confused
>> between get_random_bytes() and random32_get_bytes(), and the result
>> may be a very embarassing security exposure.
>>
>> How about prandom32_get_bytes_state() and prandom32_get_bytes() instead?
>
> I agree with your suggestion.  I'll rename them and try again.
>
> By the way, should we also rename the existing random32() and
> prandom32() in the future?
>
> Specifically, rename random32() to prandom32(), and prandom32() to
> prandom32_state().  As a result, it will cause a little confusion
> between old and new prandom32(). But the number of arguments will
> be changed from 3 to 2, so gcc can detect the misuse of prandom32().

Oops, I intended to say "the number of arguments of prandom32() will be
changed from 1 to 0". And I realized that the exisiting srandom32() also should
be renamed to sprandom32().


From tytso at mit.edu  Tue Oct 30 23:29:02 2012
From: tytso at mit.edu (Theodore Ts'o)
Date: Tue, 30 Oct 2012 23:29:02 -0400
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
In-Reply-To: <CAC5umyi=f+Q2Dxc4KS8nKd8uD3yvVNf8M9g1-nBt+6UsqSGHdg@mail.gmail.com>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
 <20121029203937.GC7098@thunk.org>
 <CAC5umyhje4oDtKzw6kYSXw99rVzZJOaeApfizGeDos3SnmUcjA@mail.gmail.com>
 <CAC5umyi=f+Q2Dxc4KS8nKd8uD3yvVNf8M9g1-nBt+6UsqSGHdg@mail.gmail.com>
Message-ID: <20121031032902.GD9475@thunk.org>

On Tue, Oct 30, 2012 at 08:12:39PM +0900, Akinobu Mita wrote:
> >>
> >> How about prandom32_get_bytes_state() and prandom32_get_bytes() instead?
> >
> > I agree with your suggestion.  I'll rename them and try again.
> >
> > By the way, should we also rename the existing random32() and
> > prandom32() in the future?

I suppose the other way to go is to just use random32 as the common
prefix, and just have random32() and random32_state().  My concern was
that people might assume that prandom32() and random32() might imply
that only prandom32() was the one using a pseudo-random number
generator.  This might be easier since there are large number of uses
of random32() in the source tree, but only a relative few using
prandom32().

    	   	     	    	     - Ted


From avinashphilip at ti.com  Wed Oct 31 03:08:24 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 31 Oct 2012 12:38:24 +0530
Subject: [PATCH v2 0/3] mtd: nand: OMAP: ELM error correction support for BCH
 ecc
Message-ID: <1351667307-447-1-git-send-email-avinashphilip@ti.com>

Support to use ELM as BCH 4 & 8 bit error correction module. Also performance
enhancement by adding single shot read_page and write_page functions for the
nand flashes with page size less than 4 KB.

ELM module can be used to correct errors reported by BCH 4, 8 & 16 bit
ECC scheme. For now only 4 & 8 bit support is added.

BCH 4 & 8 bit error detection support is already available in mainline
kernel and works with software error correction.

This series is based on [1] and tested with RFC: OMAP GPMC bindings
patch series

1. linux-next/20121030

Changes since v1:
	- Erased page is identified by checking byte [13/7] in read
	  ecc. To filter out bit flips in OOB area, check 0 bits in
	  the byte greater than 4.
	- GPMC ecc engine configuration moves to omap2.c NAND driver.

Philip, Avinash (3):
  mtd: nand: omap2: Update nerrors using ecc.strength
  mtd: devices: elm: Add support for ELM error correction
  mtd: nand: omap2: Support for hardware BCH error correction

 Documentation/devicetree/bindings/mtd/elm.txt |   18 +
 drivers/mtd/devices/Makefile                  |    4 +-
 drivers/mtd/devices/elm.c                     |  420 +++++++++++++++++++
 drivers/mtd/nand/omap2.c                      |  542 +++++++++++++++++++++++--
 include/linux/platform_data/elm.h             |   54 +++
 include/linux/platform_data/mtd-nand-omap2.h  |    1 +
 6 files changed, 997 insertions(+), 42 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/elm.txt
 create mode 100644 drivers/mtd/devices/elm.c
 create mode 100644 include/linux/platform_data/elm.h



From avinashphilip at ti.com  Wed Oct 31 03:08:25 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 31 Oct 2012 12:38:25 +0530
Subject: [PATCH v2 1/3] mtd: nand: omap2: Update nerrors using ecc.strength
In-Reply-To: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
References: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1351667307-447-2-git-send-email-avinashphilip@ti.com>

Update number of errors using nand ecc strength.
Also add macro definitions BCH8_ERROR_MAX & BCH4_ERROR_MAX

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
---
:100644 100644 5c8978e... a02be29... M	drivers/mtd/nand/omap2.c
 drivers/mtd/nand/omap2.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5c8978e..a02be29 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -118,6 +118,9 @@
 
 #define OMAP24XX_DMA_GPMC		4
 
+#define BCH8_MAX_ERROR		8	/* upto 8 bit correctable */
+#define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */
+
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -1042,7 +1045,7 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	struct nand_chip *chip = mtd->priv;
 	u32 val;
 
-	nerrors = (info->nand.ecc.bytes == 13) ? 8 : 4;
+	nerrors = info->nand.ecc.strength;
 	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
 	nsectors = 1;
 	/*
@@ -1219,13 +1222,14 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 #ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = 8;
+	const int hw_errors = BCH8_MAX_ERROR;
 #else
-	const int hw_errors = 4;
+	const int hw_errors = BCH4_MAX_ERROR;
 #endif
 	info->bch = NULL;
 
-	max_errors = (ecc_opt == OMAP_ECC_BCH8_CODE_HW) ? 8 : 4;
+	max_errors = (ecc_opt == OMAP_ECC_BCH8_CODE_HW) ?
+		BCH8_MAX_ERROR : BCH4_MAX_ERROR;
 	if (max_errors != hw_errors) {
 		pr_err("cannot configure %d-bit BCH ecc, only %d-bit supported",
 		       max_errors, hw_errors);
-- 
1.7.0.4



From avinashphilip at ti.com  Wed Oct 31 03:08:27 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 31 Oct 2012 12:38:27 +0530
Subject: [PATCH v2 3/3] mtd: nand: omap2: Support for hardware BCH error
 correction
In-Reply-To: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
References: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1351667307-447-4-git-send-email-avinashphilip@ti.com>

ELM module can be used for hardware error correction of BCH 4 & 8 bit.
Also support read & write page in one shot by adding custom read_page &
write_page methods. This helps in optimizing code for NAND flashes with
page size less than 4 KB.

New structure member "is_elm_used" is added to know the status of
whether the ELM module is used for error correction or not.

Note:
ECC layout uses 1 extra bytes for 512 byte of data to handle erased
pages. Extra byte programmed to zero for programmed pages. Also BCH8
requires 14 byte ecc to maintain compatibility with RBL ECC layout.
This results a common ecc layout across RBL, U-boot & Linux with BCH8.

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
---
Changes since v1:
	- Incorporated GPMC modification to nand driver
	- Erased page detects by checking OOB byte at fixed offset.

:100644 100644 a02be29... 89bddc4... M	drivers/mtd/nand/omap2.c
:100644 100644 d4fce31... b732089... M	include/linux/platform_data/elm.h
:100644 100644 24d32ca... db8c68b... M	include/linux/platform_data/mtd-nand-omap2.h
 drivers/mtd/nand/omap2.c                     |  532 ++++++++++++++++++++++++--
 include/linux/platform_data/elm.h            |    2 +-
 include/linux/platform_data/mtd-nand-omap2.h |    1 +
 3 files changed, 496 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a02be29..89bddc4 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,6 +25,7 @@
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/bch.h>
+#include <linux/platform_data/elm.h>
 #endif
 
 #include <plat-omap/dma-omap.h>
@@ -121,6 +122,30 @@
 #define BCH8_MAX_ERROR		8	/* upto 8 bit correctable */
 #define BCH4_MAX_ERROR		4	/* upto 4 bit correctable */
 
+#define SECTOR_BYTES		512
+/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
+#define BCH4_BIT_PAD		4
+#define BCH8_ECC_MAX		((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8)
+#define BCH4_ECC_MAX		((SECTOR_BYTES + BCH4_ECC_OOB_BYTES) * 8)
+
+/* GPMC ecc engine settings for read */
+#define BCH_WRAPMODE_1		1	/* BCH wrap mode 1 */
+#define BCH8R_ECC_SIZE0		0x1a	/* ecc_size0 = 26 */
+#define BCH8R_ECC_SIZE1		0x2	/* ecc_size1 = 2 */
+#define BCH4R_ECC_SIZE0		0xd	/* ecc_size0 = 13 */
+#define BCH4R_ECC_SIZE1		0x3	/* ecc_size1 = 3 */
+
+/* GPMC ecc engine settings for write */
+#define BCH_WRAPMODE_6		6	/* BCH wrap mode 6 */
+#define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
+#define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
+
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
+	0xac, 0x6b, 0xff, 0x99, 0x7b};
+static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
+#endif
+
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -160,6 +185,8 @@ struct omap_nand_info {
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	struct bch_control             *bch;
 	struct nand_ecclayout           ecclayout;
+	bool				is_elm_used;
+	struct device			*elm_dev;
 #endif
 };
 
@@ -1035,6 +1062,12 @@ static int omap_dev_ready(struct mtd_info *mtd)
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
  * @mode: Read/Write mode
+ * When using BCH, sector size is hardcoded to 512 bytes.
+ * Using wrapping mode 6 both for reading and writing if ELM module not uses
+ * for error correction.
+ * On writing,
+ * eccsize0 = 0  (no additional protected byte in spare area)
+ * eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
  */
 static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 {
@@ -1043,32 +1076,59 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 	struct nand_chip *chip = mtd->priv;
-	u32 val;
+	u32 val, wr_mode;
+	unsigned int ecc_size1, ecc_size0;
+
+	/* Using wrapping mode 6 for writing */
+	wr_mode = BCH_WRAPMODE_6;
 
-	nerrors = info->nand.ecc.strength;
-	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
-	nsectors = 1;
 	/*
-	 * Program GPMC to perform correction on one 512-byte sector at a time.
-	 * Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible and
-	 * gives a slight (5%) performance gain (but requires additional code).
+	 * ECC engine enabled for valid ecc_size0 nibbles
+	 * & disabled for ecc_size1 nibbles.
 	 */
+	ecc_size0 = BCH_ECC_SIZE0;
+	ecc_size1 = BCH_ECC_SIZE1;
 
-	writel(ECC1, info->reg.gpmc_ecc_control);
+	 /* Perform ecc calculation on 512-byte sector */
+	nsectors = 1;
+
+	/* update number of error correction */
+	nerrors = info->nand.ecc.strength;
 
 	/*
-	 * When using BCH, sector size is hardcoded to 512 bytes.
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
+	 * Perform multi sector reading/writing for
+	 * NAND flashes with page size < 4096
 	 */
-	val = (32 << ECCSIZE1_SHIFT) | (0 << ECCSIZE0_SHIFT);
+	if (info->is_elm_used && (mtd->writesize <= 4096)) {
+		if (mode == NAND_ECC_READ) {
+			/* Using wrapping mode 1 for reading */
+			wr_mode = BCH_WRAPMODE_1;
+
+			/*
+			 * ECC engine enabled for ecc_size0 nibbles
+			 * & disabled for ecc_size1 nibbles.
+			 */
+			ecc_size0 = (nerrors == 8) ?
+				BCH8R_ECC_SIZE0 : BCH4R_ECC_SIZE0;
+			ecc_size1 = (nerrors == 8) ?
+				BCH8R_ECC_SIZE1 : BCH4R_ECC_SIZE1;
+		}
+
+		/* Perform ecc calculation for one page (< 4096) */
+		nsectors = info->nand.ecc.steps;
+	}
+
+	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+
+	writel(ECC1, info->reg.gpmc_ecc_control);
+
+	val = (ecc_size1 << ECCSIZE1_SHIFT) | (ecc_size0 << ECCSIZE0_SHIFT);
 	writel(val, info->reg.gpmc_ecc_size_config);
 
 	/* BCH configuration */
 	val = ((1                        << 16) | /* enable BCH */
 	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
-	       (0x06                     <<  8) | /* wrap mode = 6 */
+	       (wr_mode                  <<  8) | /* wrap mode */
 	       (dev_width                <<  7) | /* bus width */
 	       (((nsectors-1) & 0x7)     <<  4) | /* number of sectors */
 	       (info->gpmc_cs            <<  1) | /* ECC CS */
@@ -1166,6 +1226,280 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 }
 
 /**
+ * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
+ * @mtd:	MTD device structure
+ * @dat:	The pointer to data on which ecc is computed
+ * @ecc_code:	The ecc_code buffer
+ *
+ * support reading og BCH4/8 ecc vectors for the page
+ */
+static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
+				    u_char *ecc_code)
+{
+	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
+						   mtd);
+	unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4;
+	int i, eccbchtsel;
+
+	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
+	/*
+	 * find BCH scheme used
+	 * 0 -> BCH4
+	 * 1 -> BCH8
+	 */
+	eccbchtsel = ((readl(info->reg.gpmc_ecc_config) >> 12) & 0x3);
+
+	for (i = 0; i < nsectors; i++) {
+
+		/* Read hw-computed remainder */
+		bch_val1 = readl(info->reg.gpmc_bch_result0[i]);
+		bch_val2 = readl(info->reg.gpmc_bch_result1[i]);
+		if (eccbchtsel) {
+			bch_val3 = readl(info->reg.gpmc_bch_result2[i]);
+			bch_val4 = readl(info->reg.gpmc_bch_result3[i]);
+		}
+
+		if (eccbchtsel) {
+			/* BCH8 ecc scheme */
+			*ecc_code++ = (bch_val4 & 0xFF);
+			*ecc_code++ = ((bch_val3 >> 24) & 0xFF);
+			*ecc_code++ = ((bch_val3 >> 16) & 0xFF);
+			*ecc_code++ = ((bch_val3 >> 8) & 0xFF);
+			*ecc_code++ = (bch_val3 & 0xFF);
+			*ecc_code++ = ((bch_val2 >> 24) & 0xFF);
+			*ecc_code++ = ((bch_val2 >> 16) & 0xFF);
+			*ecc_code++ = ((bch_val2 >> 8) & 0xFF);
+			*ecc_code++ = (bch_val2 & 0xFF);
+			*ecc_code++ = ((bch_val1 >> 24) & 0xFF);
+			*ecc_code++ = ((bch_val1 >> 16) & 0xFF);
+			*ecc_code++ = ((bch_val1 >> 8) & 0xFF);
+			*ecc_code++ = (bch_val1 & 0xFF);
+			/*
+			 * Setting 14th byte to zero to handle
+			 * erased page & maintain compatibility
+			 * with RBL
+			 */
+			*ecc_code++ = 0x0;
+		} else {
+			/* BCH4 ecc scheme */
+			*ecc_code++ = ((bch_val2 >> 12) & 0xFF);
+			*ecc_code++ = ((bch_val2 >> 4) & 0xFF);
+			*ecc_code++ = ((bch_val2 & 0xF) << 4) |
+				((bch_val1 >> 28) & 0xF);
+			*ecc_code++ = ((bch_val1 >> 20) & 0xFF);
+			*ecc_code++ = ((bch_val1 >> 12) & 0xFF);
+			*ecc_code++ = ((bch_val1 >> 4) & 0xFF);
+			*ecc_code++ = ((bch_val1 & 0xF) << 4);
+			/*
+			 * Setting 8th byte to zero to handle
+			 * erased page
+			 */
+			*ecc_code++ = 0x0;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * erased_sector_bitflips - count bit flips
+ * @data:	data sector buffer
+ * @oob:	oob buffer
+ * @info:	omap_nand_info
+ *
+ * Check the bit flips in erased page falls below correctable level.
+ * If falls below, report the page as erased with correctable bit
+ * flip, else report as uncorrectable page.
+ */
+static int erased_sector_bitflips(u_char *data, u_char *oob,
+		struct omap_nand_info *info)
+{
+	int flip_bits = 0, i;
+
+	for (i = 0; i < info->nand.ecc.size; i++) {
+		flip_bits += hweight8(~data[i]);
+		if (flip_bits > info->nand.ecc.strength)
+			return 0;
+	}
+
+	for (i = 0; i < info->nand.ecc.bytes - 1; i++) {
+		flip_bits += hweight8(~oob[i]);
+		if (flip_bits > info->nand.ecc.strength)
+			return 0;
+	}
+
+	/*
+	 * Bit flips falls in correctable level.
+	 * Fill data araea with 0xFF
+	 */
+	memset(data, 0xFF, info->nand.ecc.size);
+
+	return flip_bits;
+}
+
+/**
+ * omap_elm_correct_data - corrects page data area in case error reported
+ * @mtd:	MTD device structure
+ * @data:	page data
+ * @read_ecc:	ecc read from nand flash
+ * @calc_ecc:	ecc read from HW ECC registers
+ *
+ * Calculated ecc vector reported as zero in case of non-error pages.
+ * In case of error/erased pages non-zero error vector is reported.
+ * In case of non-zero ecc vector, check read_ecc at fixed offset
+ * (x = 13/7 in case of BCH8/4 == 0) to find page programmed or not.
+ * To handle bit flips in this data, count the number of 0's in
+ * read_ecc[x] and check if it greater than 4. If it is less, it is
+ * programmed page, else erased page.
+ *
+ * 1. If page is erased, check with standard ecc vector (ecc vector
+ * for erased page to find any bit flip). If check fails, bit flip
+ * is present in erased page. Count the bit flips in erased page and
+ * if it falls under correctable level, report page with 0xFF and
+ * update the correctable bit information.
+ * 2. If error is reported on programmed page, update elm error
+ * vector and correct the page with ELM error correction routine.
+ *
+ */
+static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
+				u_char *read_ecc, u_char *calc_ecc)
+{
+	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
+			mtd);
+	int eccsteps = info->nand.ecc.steps;
+	int i , j, stat = 0;
+	int eccsize, eccflag, ecc_vector_size;
+	struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
+	u_char *ecc_vec = calc_ecc;
+	u_char *erased_ecc_vec;
+	enum bch_ecc type;
+	bool is_error_reported = false;
+
+	/* Initialize elm error vector to zero */
+	memset(err_vec, 0, sizeof(err_vec));
+
+	if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
+		type = BCH8_ECC;
+		ecc_vector_size = BCH8_SIZE;
+		eccsize = BCH8_ECC_OOB_BYTES;
+		erased_ecc_vec = bch8_vector;
+	} else {
+		type = BCH4_ECC;
+		ecc_vector_size = BCH4_SIZE;
+		eccsize = BCH4_ECC_OOB_BYTES;
+		erased_ecc_vec = bch4_vector;
+	}
+
+	for (i = 0; i < eccsteps ; i++) {
+		eccflag = 0;	/* initialize eccflag */
+
+		/*
+		 * Check any error reported,
+		 * In case of error, non zero ecc reported.
+		 */
+
+		for (j = 0; (j < eccsize); j++) {
+			if (calc_ecc[j] != 0) {
+				eccflag = 1; /* non zero ecc, error present */
+				break;
+			}
+		}
+
+		if (eccflag == 1) {
+
+			/*
+			 * Check data area is programmed by counting
+			 * number of 0's at fixed offset in spare area.
+			 * Checking count of 0's against 4(threshold set
+			 * to 4 to allow half bit flips at byte offset,
+			 * worst case)
+			 * In case programmed page expects at least 4
+			 * zeros in byte.
+			 * If zeros are less than 4 for programmed page /
+			 * zeros are more than 4 erased page, either
+			 * case page reported as uncorrectable.
+			 */
+			if (hweight8(~read_ecc[eccsize]) >= 4) {
+				/*
+				 * Update elm error vector as
+				 * data area is programmed
+				 */
+				err_vec[i].error_reported = true;
+				is_error_reported = true;
+			} else {
+				/* Error reported in erased page */
+				int bitflip_count;
+				u_char *buf = &data[info->nand.ecc.size * i];
+
+				if (memcmp(calc_ecc, erased_ecc_vec, eccsize)) {
+					bitflip_count = erased_sector_bitflips(
+							buf, read_ecc, info);
+
+					if (bitflip_count)
+						stat += bitflip_count;
+					else
+						return -EINVAL;
+				}
+			}
+		}
+
+		/* Update the ecc vector */
+		calc_ecc = calc_ecc + ecc_vector_size;
+		read_ecc = read_ecc + ecc_vector_size;
+	}
+
+	/* Check if any error reported */
+	if (!is_error_reported)
+		return stat;
+
+	/* Decode BCH error using ELM module */
+	elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
+
+	for (i = 0; i < eccsteps; i++) {
+		if (err_vec[i].error_reported) {
+			for (j = 0; j < err_vec[i].error_count; j++) {
+				u32 bit_pos, byte_pos, error_max, pos;
+
+				if (type == BCH8_ECC)
+					error_max = BCH8_ECC_MAX;
+				else
+					error_max = BCH4_ECC_MAX;
+
+				if (info->nand.ecc.strength == BCH8_MAX_ERROR)
+					pos = err_vec[i].error_loc[j];
+				else
+					/* Add 4 to take care 4 bit padding */
+					pos = err_vec[i].error_loc[j] +
+						BCH4_BIT_PAD;
+
+				/* Calculate bit position of error */
+				bit_pos = pos % 8;
+
+				/* Calculate byte position of error */
+				byte_pos = (error_max - pos - 1) / 8;
+
+				if (pos < error_max)
+					data[byte_pos] ^= 1 << bit_pos;
+				/* else, not interested to correct ecc */
+			}
+		}
+
+		/* Update number of correctable errors */
+		stat += err_vec[i].error_count;
+
+		/* Update page data with sector size */
+		data += info->nand.ecc.size;
+	}
+
+	for (i = 0; i < eccsteps; i++)
+		/* Return error if uncorrectable error present */
+		if (err_vec[i].error_uncorrectable)
+			return -EINVAL;
+
+	return stat;
+}
+
+/**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
  * @data: page data
@@ -1198,6 +1532,89 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 }
 
 /**
+ * omap_write_page_bch - BCH ecc based write page function for entire page
+ * @mtd:		mtd info structure
+ * @chip:		nand chip info structure
+ * @buf:		data buffer
+ * @oob_required:	must write chip->oob_poi to OOB
+ *
+ * Custom write page method evolved to support multi sector writing in one shot
+ */
+static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				  const uint8_t *buf, int oob_required)
+{
+	int i;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+
+	/* Enable GPMC ecc engine */
+	chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+
+	/* Write data */
+	chip->write_buf(mtd, buf, mtd->writesize);
+
+	/* Update ecc vector from GPMC result registers */
+	chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
+
+	for (i = 0; i < chip->ecc.total; i++)
+		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+	/* Write ecc vector to OOB area */
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
+}
+
+/**
+ * omap_read_page_bch - BCH ecc based page read function for entire page
+ * @mtd:		mtd info structure
+ * @chip:		nand chip info structure
+ * @buf:		buffer to store read data
+ * @oob_required:	caller requires OOB data read to chip->oob_poi
+ * @page:		page number to read
+ *
+ * For BCH ecc scheme, GPMC used for syndrome calculation and ELM module
+ * used for error correction.
+ * Custom method evolved to support ELM error correction & multi sector
+ * reading. On reading page data area is read along with OOB data with
+ * ecc engine enabled. ecc vector updated after read of OOB data.
+ * For non error pages ecc vector reported as zero.
+ */
+static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *oob = &chip->oob_poi[eccpos[0]];
+	uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
+	int stat;
+
+	/* Enable GPMC ecc engine */
+	chip->ecc.hwctl(mtd, NAND_ECC_READ);
+
+	/* Read data */
+	chip->read_buf(mtd, buf, mtd->writesize);
+
+	/* Read oob bytes */
+	chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
+	chip->read_buf(mtd, oob, chip->ecc.total);
+
+	/* Calculate ecc bytes */
+	chip->ecc.calculate(mtd, buf, ecc_calc);
+
+	memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+
+	stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
+
+	if (stat < 0)
+		mtd->ecc_stats.failed++;
+	else
+		mtd->ecc_stats.corrected += stat;
+
+	return 0;
+}
+
+/**
  * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
  */
@@ -1236,30 +1653,55 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
 		goto fail;
 	}
 
-	/* software bch library is only used to detect and locate errors */
-	info->bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
-	if (!info->bch)
-		goto fail;
-
-	info->nand.ecc.size    = 512;
-	info->nand.ecc.hwctl   = omap3_enable_hwecc_bch;
-	info->nand.ecc.correct = omap3_correct_data_bch;
-	info->nand.ecc.mode    = NAND_ECC_HW;
+	info->nand.ecc.size = 512;
+	info->nand.ecc.hwctl = omap3_enable_hwecc_bch;
+	info->nand.ecc.mode = NAND_ECC_HW;
+	info->nand.ecc.strength = max_errors;
+	if (info->is_elm_used && (mtd->writesize <= 4096)) {
+		enum bch_ecc bch_type;
 
-	/*
-	 * The number of corrected errors in an ecc block that will trigger
-	 * block scrubbing defaults to the ecc strength (4 or 8).
-	 * Set mtd->bitflip_threshold here to define a custom threshold.
-	 */
+		if (max_errors == BCH8_MAX_ERROR) {
+			bch_type = BCH8_ECC;
+			info->nand.ecc.bytes = BCH8_SIZE;
+		} else {
+			bch_type = BCH4_ECC;
+			info->nand.ecc.bytes = BCH4_SIZE;
+		}
 
-	if (max_errors == 8) {
-		info->nand.ecc.strength  = 8;
-		info->nand.ecc.bytes     = 13;
-		info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
+		info->nand.ecc.correct = omap_elm_correct_data;
+		info->nand.ecc.calculate = omap3_calculate_ecc_bch;
+		info->nand.ecc.read_page = omap_read_page_bch;
+		info->nand.ecc.write_page = omap_write_page_bch;
+		info->elm_dev = elm_request(bch_type);
+		if (!info->elm_dev) {
+			pr_err("Request to elm module failed\n");
+			goto fail;
+		}
 	} else {
-		info->nand.ecc.strength  = 4;
-		info->nand.ecc.bytes     = 7;
-		info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
+		/*
+		 * software bch library is only used to detect and
+		 * locate errors
+		 */
+		info->bch = init_bch(13, max_errors,
+				0x201b /* hw polynomial */);
+		if (!info->bch)
+			goto fail;
+
+		info->nand.ecc.correct = omap3_correct_data_bch;
+
+		/*
+		 * The number of corrected errors in an ecc block that will
+		 * trigger block scrubbing defaults to the ecc strength (4 or 8)
+		 * Set mtd->bitflip_threshold here to define a custom threshold.
+		 */
+
+		if (max_errors == 8) {
+			info->nand.ecc.bytes = 13;
+			info->nand.ecc.calculate = omap3_calculate_ecc_bch8;
+		} else {
+			info->nand.ecc.bytes = 7;
+			info->nand.ecc.calculate = omap3_calculate_ecc_bch4;
+		}
 	}
 
 	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
@@ -1275,7 +1717,7 @@ fail:
  */
 static int omap3_init_bch_tail(struct mtd_info *mtd)
 {
-	int i, steps;
+	int i, steps, offset;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
 	struct nand_ecclayout *layout = &info->ecclayout;
@@ -1297,11 +1739,22 @@ static int omap3_init_bch_tail(struct mtd_info *mtd)
 		goto fail;
 	}
 
+	/* ECC layout compatible with RBL for BCH8 */
+	if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE))
+		offset = 2;
+	else
+		offset = mtd->oobsize - layout->eccbytes;
+
 	/* put ecc bytes at oob tail */
 	for (i = 0; i < layout->eccbytes; i++)
-		layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i;
+		layout->eccpos[i] = offset + i;
+
+
+	if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE))
+		layout->oobfree[0].offset = 2 + layout->eccbytes * steps;
+	else
+		layout->oobfree[0].offset = 2;
 
-	layout->oobfree[0].offset = 2;
 	layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes;
 	info->nand.ecc.layout = layout;
 
@@ -1365,6 +1818,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
 	info->nand.options	= pdata->devsize;
 	info->nand.options	|= NAND_SKIP_BBTSCAN;
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	info->is_elm_used	= pdata->is_elm_used;
+#endif
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
 		err = -EINVAL;
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
index d4fce31..b732089 100644
--- a/include/linux/platform_data/elm.h
+++ b/include/linux/platform_data/elm.h
@@ -30,7 +30,8 @@ enum bch_ecc {
 #define BCH4_ECC_OOB_BYTES		7
 /* RBL requires 14 byte even though BCH8 uses only 13 byte */
 #define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
-#define BCH4_SIZE			(BCH4_ECC_OOB_BYTES)
+/* Uses 1 extra byte to handle erased pages */
+#define BCH4_SIZE			(BCH4_ECC_OOB_BYTES + 1)
 
 /**
  * struct elm_errorvec - error vector for elm
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 24d32ca..db8c68b 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -60,6 +60,7 @@ struct omap_nand_platform_data {
 	int			devsize;
 	enum omap_ecc           ecc_opt;
 	struct gpmc_nand_regs	reg;
+	bool			is_elm_used;
 };
 
 #endif
-- 
1.7.0.4



From avinashphilip at ti.com  Wed Oct 31 03:08:26 2012
From: avinashphilip at ti.com (Philip, Avinash)
Date: Wed, 31 Oct 2012 12:38:26 +0530
Subject: [PATCH v2 2/3] mtd: devices: elm: Add support for ELM error correction
In-Reply-To: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
References: <1351667307-447-1-git-send-email-avinashphilip@ti.com>
Message-ID: <1351667307-447-3-git-send-email-avinashphilip@ti.com>

The ELM hardware module can be used to speedup BCH 4/8/16 ECC scheme
error correction.
For now only 4 & 8 bit support is added

Signed-off-by: Philip, Avinash <avinashphilip at ti.com>
Cc: Grant Likely <grant.likely at secretlab.ca>
Cc: Rob Herring <rob.herring at calxeda.com>
Cc: Rob Landley <rob at landley.net>
---
Changes since v1:
	- change build attribute to CONFIG_MTD_NAND_OMAP_BCH
	- Reduced indentation using by passing elm_info , offset
	  to elm_read & elm_write
	- Removed syndrome manipulation functions.

:000000 100644 0000000... b88ee83... A	Documentation/devicetree/bindings/mtd/elm.txt
:100644 100644 395733a... 369a194... M	drivers/mtd/devices/Makefile
:000000 100644 0000000... bb36018... A	drivers/mtd/devices/elm.c
:000000 100644 0000000... d4fce31... A	include/linux/platform_data/elm.h
 Documentation/devicetree/bindings/mtd/elm.txt |   18 +
 drivers/mtd/devices/Makefile                  |    4 +-
 drivers/mtd/devices/elm.c                     |  418 +++++++++++++++++++++++++
 include/linux/platform_data/elm.h             |   54 ++++
 4 files changed, 493 insertions(+), 1 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/elm.txt b/Documentation/devicetree/bindings/mtd/elm.txt
new file mode 100644
index 0000000..b88ee83
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/elm.txt
@@ -0,0 +1,18 @@
+Error location module
+
+Required properties:
+- compatible: Must be "ti,elm"
+- reg: physical base address and size of the registers map.
+- interrupts: Interrupt number for the elm.
+- interrupt-parent: The parent interrupt controller
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the elm
+
+Example:
+elm: elm at 0 {
+	compatible	= "ti,elm";
+	reg = <0x48080000 0x2000>;
+	interrupt-parent = <&intc>;
+	interrupts = <4>;
+};
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 395733a..369a194 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,8 +17,10 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
+obj-$(CONFIG_MTD_NAND_OMAP_BCH)	+= elm.o
 obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
 obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
 
-CFLAGS_docg3.o			+= -I$(src)
\ No newline at end of file
+
+CFLAGS_docg3.o			+= -I$(src)
diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
new file mode 100644
index 0000000..bb36018
--- /dev/null
+++ b/drivers/mtd/devices/elm.c
@@ -0,0 +1,418 @@
+/*
+ * Error Location Module
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_data/elm.h>
+
+#define ELM_IRQSTATUS			0x018
+#define ELM_IRQENABLE			0x01c
+#define ELM_LOCATION_CONFIG		0x020
+#define ELM_PAGE_CTRL			0x080
+#define ELM_SYNDROME_FRAGMENT_0		0x400
+#define ELM_SYNDROME_FRAGMENT_6		0x418
+#define ELM_LOCATION_STATUS		0x800
+#define ELM_ERROR_LOCATION_0		0x880
+
+/* ELM Interrupt Status Register */
+#define INTR_STATUS_PAGE_VALID		BIT(8)
+
+/* ELM Interrupt Enable Register */
+#define INTR_EN_PAGE_MASK		BIT(8)
+
+/* ELM Location Configuration Register */
+#define ECC_BCH_LEVEL_MASK		0x3
+
+/* ELM syndrome */
+#define ELM_SYNDROME_VALID		BIT(16)
+
+/* ELM_LOCATION_STATUS Register */
+#define ECC_CORRECTABLE_MASK		BIT(8)
+#define ECC_NB_ERRORS_MASK		0x1f
+
+/* ELM_ERROR_LOCATION_0-15 Registers */
+#define ECC_ERROR_LOCATION_MASK		0x1fff
+
+#define ELM_ECC_SIZE			0x7ff
+
+#define SYNDROME_FRAGMENT_REG_SIZE	0x40
+#define ERROR_LOCATION_SIZE		0x100
+
+struct elm_info {
+	struct device *dev;
+	void __iomem *elm_base;
+	struct completion elm_completion;
+	struct list_head list;
+	enum bch_ecc bch_type;
+};
+
+static LIST_HEAD(elm_devices);
+
+static void elm_write_reg(struct elm_info *info, int offset, u32 val)
+{
+	writel(val, info->elm_base + offset);
+}
+
+static u32 elm_read_reg(struct elm_info *info, int offset)
+{
+	return readl(info->elm_base + offset);
+}
+
+/**
+ * elm_config - Configure ELM module
+ * @info:	elm info
+ */
+static void elm_config(struct elm_info *info)
+{
+	u32 reg_val;
+
+	reg_val = (info->bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
+	elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val);
+}
+
+/**
+ * elm_configure_page_mode - Enable/Disable page mode
+ * @info:	elm info
+ * @index:	index number of syndrome fragment vector
+ * @enable:	enable/disable flag for page mode
+ *
+ * Enable page mode for syndrome fragment index
+ */
+static void elm_configure_page_mode(struct elm_info *info, int index,
+		bool enable)
+{
+	u32 reg_val;
+
+	reg_val = elm_read_reg(info, ELM_PAGE_CTRL);
+	if (enable)
+		reg_val |= BIT(index);	/* enable page mode */
+	else
+		reg_val &= ~BIT(index);	/* disable page mode */
+
+	elm_write_reg(info, ELM_PAGE_CTRL, reg_val);
+}
+
+/**
+ * elm_load_syndrome - Load ELM syndrome reg
+ * @info:	elm info
+ * @err_vec:	elm error vectors
+ * @ecc:	buffer with calculated ecc
+ *
+ * Load syndrome fragment registers with calculated ecc in reverse order.
+ */
+static void elm_load_syndrome(struct elm_info *info,
+		struct elm_errorvec *err_vec, u8 *ecc)
+{
+	int i, offset;
+	u32 val;
+
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+
+		/* Check error reported */
+		if (err_vec[i].error_reported) {
+			elm_configure_page_mode(info, i, true);
+			offset = ELM_SYNDROME_FRAGMENT_0 +
+				SYNDROME_FRAGMENT_REG_SIZE * i;
+
+			/* BCH8 */
+			if (info->bch_type) {
+
+				/* syndrome fragment 0 = ecc[9-12B] */
+				val = cpu_to_be32(*(u32 *) &ecc[9]);
+				elm_write_reg(info, offset, val);
+
+				/* syndrome fragment 1 = ecc[5-8B] */
+				offset += 4;
+				val = cpu_to_be32(*(u32 *) &ecc[5]);
+				elm_write_reg(info, offset, val);
+
+				/* syndrome fragment 2 = ecc[1-4B] */
+				offset += 4;
+				val = cpu_to_be32(*(u32 *) &ecc[1]);
+				elm_write_reg(info, offset, val);
+
+				/* syndrome fragment 3 = ecc[0B] */
+				offset += 4;
+				val = ecc[0];
+				elm_write_reg(info, offset, val);
+			} else {
+				/* syndrome fragment 0 = ecc[20-52b] bits */
+				val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) |
+					((ecc[2] & 0xf) << 28);
+				elm_write_reg(info, offset, val);
+
+				/* sydrome fragment 1 = ecc[0-20b] bits */
+				offset += 4;
+				val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12;
+				elm_write_reg(info, offset, val);
+			}
+		}
+
+		/* Update ecc pointer with ecc byte size */
+		ecc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
+	}
+}
+
+/**
+ * elm_start_processing - start elm syndrome processing
+ * @info:	elm info
+ * @err_vec:	elm error vectors
+ *
+ * Set syndrome valid bit for syndrome fragment registers for which
+ * elm syndrome fragment registers are loaded. This enables elm module
+ * to start processing syndrome vectors.
+ */
+static void elm_start_processing(struct elm_info *info,
+		struct elm_errorvec *err_vec)
+{
+	int i, offset;
+	u32 reg_val;
+
+	/*
+	 * Set syndrome vector valid so that ELM module
+	 * will process it for vectors error is reported
+	 */
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+		if (err_vec[i].error_reported) {
+			offset = ELM_SYNDROME_FRAGMENT_6 +
+				SYNDROME_FRAGMENT_REG_SIZE * i;
+			reg_val = elm_read_reg(info, offset);
+			reg_val |= ELM_SYNDROME_VALID;
+			elm_write_reg(info, offset, reg_val);
+		}
+	}
+}
+
+/**
+ * elm_error_correction - locate correctable error position
+ * @info:	elm info
+ * @err_vec:	elm error vectors
+ *
+ * On completion of processing by elm module, error location status
+ * register updated with correctable/uncorrectable error information.
+ * In case of correctable errors, number of errors located from
+ * elm location status register & read the positions from
+ * elm error location register.
+ */
+static void elm_error_correction(struct elm_info *info,
+		struct elm_errorvec *err_vec)
+{
+	int i, j, errors = 0;
+	int offset;
+	u32 reg_val;
+
+	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+
+		/* Check error reported */
+		if (err_vec[i].error_reported) {
+			offset = ELM_LOCATION_STATUS + ERROR_LOCATION_SIZE * i;
+			reg_val = elm_read_reg(info, offset);
+
+			/* Check correctable error or not */
+			if (reg_val & ECC_CORRECTABLE_MASK) {
+				offset = ELM_ERROR_LOCATION_0 +
+					ERROR_LOCATION_SIZE * i;
+
+				/* Read count of correctable errors */
+				err_vec[i].error_count = reg_val &
+					ECC_NB_ERRORS_MASK;
+
+				/* Update the error locations in error vector */
+				for (j = 0; j < err_vec[i].error_count; j++) {
+
+					reg_val = elm_read_reg(info, offset);
+					err_vec[i].error_loc[j] = reg_val &
+						ECC_ERROR_LOCATION_MASK;
+
+					/* Update error location register */
+					offset += 4;
+				}
+
+				errors += err_vec[i].error_count;
+			} else {
+				err_vec[i].error_uncorrectable = true;
+			}
+
+			/* Clearing interrupts for processed error vectors */
+			elm_write_reg(info, ELM_IRQSTATUS, BIT(i));
+
+			/* Disable page mode */
+			elm_configure_page_mode(info, i, false);
+		}
+	}
+}
+
+/**
+ * elm_decode_bch_error_page - Locate error position
+ * @dev:	device pointer
+ * @ecc_calc:	calculated ECC bytes from GPMC
+ * @err_vec:	elm error vectors
+ *
+ * Called with one or more error reported vectors & vectors with
+ * error reported is updated in err_vec[].error_reported
+ *
+ */
+void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
+		struct elm_errorvec *err_vec)
+{
+	struct elm_info *info = dev_get_drvdata(dev);
+	u32 reg_val;
+
+	/* Enable page mode interrupt */
+	reg_val = elm_read_reg(info, ELM_IRQSTATUS);
+	elm_write_reg(info, ELM_IRQSTATUS, reg_val & INTR_STATUS_PAGE_VALID);
+	elm_write_reg(info, ELM_IRQENABLE, INTR_EN_PAGE_MASK);
+
+	/* Load valid ecc byte to syndrome fragment register */
+	elm_load_syndrome(info, err_vec, ecc_calc);
+
+	/* Enable syndrome processing for which syndrome fragment is updated */
+	elm_start_processing(info, err_vec);
+
+	/* Wait for ELM module to finish locating error correction */
+	wait_for_completion(&info->elm_completion);
+
+	/* Disable page mode interrupt */
+	reg_val = elm_read_reg(info, ELM_IRQENABLE);
+	elm_write_reg(info, ELM_IRQENABLE, reg_val & ~INTR_EN_PAGE_MASK);
+	elm_error_correction(info, err_vec);
+}
+EXPORT_SYMBOL(elm_decode_bch_error_page);
+
+static irqreturn_t elm_isr(int this_irq, void *dev_id)
+{
+	u32 reg_val;
+	struct elm_info *info = dev_id;
+
+	reg_val = elm_read_reg(info, ELM_IRQSTATUS);
+
+	/* All error vectors processed */
+	if (reg_val & INTR_STATUS_PAGE_VALID) {
+		elm_write_reg(info, ELM_IRQSTATUS,
+				reg_val & INTR_STATUS_PAGE_VALID);
+		complete(&info->elm_completion);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+struct device *elm_request(enum bch_ecc bch_type)
+{
+	struct elm_info *info;
+
+	list_for_each_entry(info, &elm_devices, list) {
+		if (info && info->dev) {
+				info->bch_type = bch_type;
+				elm_config(info);
+				return info->dev;
+		}
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(elm_request);
+
+static int __devinit elm_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct resource *res, *irq;
+	struct elm_info *info;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	info->dev = &pdev->dev;
+
+	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irq) {
+		dev_err(&pdev->dev, "no irq resource defined\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		return -ENODEV;
+	}
+
+	info->elm_base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!info->elm_base)
+		return -EADDRNOTAVAIL;
+
+	ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0,
+			pdev->name, info);
+	if (ret) {
+		dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start);
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+	if (pm_runtime_get_sync(&pdev->dev)) {
+		ret = -EINVAL;
+		pm_runtime_disable(&pdev->dev);
+		dev_err(&pdev->dev, "can't enable clock\n");
+		return ret;
+	}
+
+	init_completion(&info->elm_completion);
+	INIT_LIST_HEAD(&info->list);
+	list_add(&info->list, &elm_devices);
+	platform_set_drvdata(pdev, info);
+	return ret;
+}
+
+static int __devexit elm_remove(struct platform_device *pdev)
+{
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+
+#ifdef CONFIG_OF
+static const struct of_device_id elm_of_match[] = {
+	{ .compatible = "ti,elm" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, elm_of_match);
+#endif
+
+static struct platform_driver elm_driver = {
+	.driver	= {
+		.name	= "elm",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(elm_of_match),
+	},
+	.probe	= elm_probe,
+	.remove	= __devexit_p(elm_remove),
+};
+
+module_platform_driver(elm_driver);
+
+MODULE_DESCRIPTION("ELM driver for BCH error correction");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_ALIAS("platform: elm");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
new file mode 100644
index 0000000..d4fce31
--- /dev/null
+++ b/include/linux/platform_data/elm.h
@@ -0,0 +1,54 @@
+/*
+ * BCH Error Location Module
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ELM_H
+#define __ELM_H
+
+enum bch_ecc {
+	BCH4_ECC = 0,
+	BCH8_ECC,
+};
+
+/* ELM support 8 error syndrome process */
+#define ERROR_VECTOR_MAX		8
+
+#define BCH8_ECC_OOB_BYTES		13
+#define BCH4_ECC_OOB_BYTES		7
+/* RBL requires 14 byte even though BCH8 uses only 13 byte */
+#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
+#define BCH4_SIZE			(BCH4_ECC_OOB_BYTES)
+
+/**
+ * struct elm_errorvec - error vector for elm
+ * @error_reported:		set true for vectors error is reported
+ *
+ * @error_count:		number of correctable errors in the sector
+ * @error_uncorrectable:	number of uncorrectable errors
+ * @error_loc:			buffer for error location
+ *
+ */
+struct elm_errorvec {
+	bool error_reported;
+	bool error_uncorrectable;
+	int error_count;
+	int error_loc[ERROR_VECTOR_MAX];
+};
+
+void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
+		struct elm_errorvec *err_vec);
+struct device *elm_request(enum bch_ecc bch_type);
+#endif /* __ELM_H */
-- 
1.7.0.4



From robin at protonic.nl  Wed Oct 31 06:32:19 2012
From: robin at protonic.nl (Robin van der Gracht)
Date: Wed, 31 Oct 2012 11:32:19 +0100
Subject: [PATCH] mtd: nand: Take celltype into account when parsing Samsung
 ext. nand ID's
Message-ID: <1351679539-30651-1-git-send-email-robin@protonic.nl>

When using a Samsung nandflash with 2 level cells, the wrong page size,
erase size and oobsize is calculated.

I'm using a Samsung K9K8G08U0B nandflash (ID: 0xECD3519558). When booting the kernel i get:
NAND device: Manufacturer ID: 0xec, Chip ID: 0xd3 (Samsung NAND 1GiB 3,3V 8-bit), page size: 4096, OOB size: 128

This is wrong. My nand flash has a pagesize of 2048 and oobsize 64.

This patch should work for all Samsung 6 byte ID chips, found on:
http://www.linux-mtd.infradead.org/nand-data/nanddata.html

Signed-off-by: Robin van der Gracht <robin at protonic.nl>
---
 drivers/mtd/nand/nand_base.c |    3 ++-
 include/linux/mtd/nand.h     |    4 ++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec6841d..e292074 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2989,7 +2989,8 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
 	 * to do.
 	 */
-	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+			(chip->cellinfo & NAND_CI_CELLTYPE_4LVL)) {
 		/* Calc pagesize */
 		mtd->writesize = 2048 << (extid & 0x03);
 		extid >>= 2;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 24e9159..3e3860e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -227,6 +227,10 @@ typedef enum {
 /* Cell info constants */
 #define NAND_CI_CHIPNR_MSK	0x03
 #define NAND_CI_CELLTYPE_MSK	0x0C
+#define NAND_CI_CELLTYPE_2LVL	0x00
+#define NAND_CI_CELLTYPE_4LVL	0x04
+#define NAND_CI_CELLTYPE_8LVL	0x08
+#define NAND_CI_CELLTYPE_16LVL	0x0C
 
 /* Keep gcc happy */
 struct nand_chip;
-- 
1.7.5.4



From akinobu.mita at gmail.com  Wed Oct 31 07:53:19 2012
From: akinobu.mita at gmail.com (Akinobu Mita)
Date: Wed, 31 Oct 2012 20:53:19 +0900
Subject: [PATCH 1/9] random32: introduce random32_get_bytes() and
 prandom32_get_bytes()
In-Reply-To: <20121031032902.GD9475@thunk.org>
References: <1351408746-8623-1-git-send-email-akinobu.mita@gmail.com>
 <20121029203937.GC7098@thunk.org>
 <CAC5umyhje4oDtKzw6kYSXw99rVzZJOaeApfizGeDos3SnmUcjA@mail.gmail.com>
 <CAC5umyi=f+Q2Dxc4KS8nKd8uD3yvVNf8M9g1-nBt+6UsqSGHdg@mail.gmail.com>
 <20121031032902.GD9475@thunk.org>
Message-ID: <CAC5umyjO5t6VVeSQo0V=pA3HkZEzYfTg=iVhWRje5owBWXYC8g@mail.gmail.com>

2012/10/31 Theodore Ts'o <tytso at mit.edu>:
> On Tue, Oct 30, 2012 at 08:12:39PM +0900, Akinobu Mita wrote:
>> >>
>> >> How about prandom32_get_bytes_state() and prandom32_get_bytes() instead?
>> >
>> > I agree with your suggestion.  I'll rename them and try again.
>> >
>> > By the way, should we also rename the existing random32() and
>> > prandom32() in the future?
>
> I suppose the other way to go is to just use random32 as the common
> prefix, and just have random32() and random32_state().  My concern was
> that people might assume that prandom32() and random32() might imply
> that only prandom32() was the one using a pseudo-random number
> generator.  This might be easier since there are large number of uses
> of random32() in the source tree, but only a relative few using
> prandom32().

Using random32 as the common prefix sounds good idea.  I'm going to
prepare the following patch set:

[patch 1] rename prandom32 to randome32_state
[patch 2] introduce random32_get_bytes and random32_get_bytes_state
[patch 3-] proliferate random32_get_bytes and random32_get_bytes_state


From computersforpeace at gmail.com  Wed Oct 31 12:17:54 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 31 Oct 2012 09:17:54 -0700
Subject: [PATCH] mtd: nand: Take celltype into account when parsing Samsung
 ext. nand ID's
In-Reply-To: <1351679539-30651-1-git-send-email-robin@protonic.nl>
References: <1351679539-30651-1-git-send-email-robin@protonic.nl>
Message-ID: <50914F32.7020605@gmail.com>

Hi Robin,

On 10/31/2012 03:32 AM, Robin van der Gracht wrote:
> When using a Samsung nandflash with 2 level cells, the wrong page size,
> erase size and oobsize is calculated.
>
> I'm using a Samsung K9K8G08U0B nandflash (ID: 0xECD3519558). When booting the kernel i get:
> NAND device: Manufacturer ID: 0xec, Chip ID: 0xd3 (Samsung NAND 1GiB 3,3V 8-bit), page size: 4096, OOB size: 128
>
> This is wrong. My nand flash has a pagesize of 2048 and oobsize 64.
>
> This patch should work for all Samsung 6 byte ID chips, found on:
> http://www.linux-mtd.infradead.org/nand-data/nanddata.html
>
> Signed-off-by: Robin van der Gracht <robin at protonic.nl>

I believe this regression has already been fixed and accepted by David 
Woodhouse and is awaiting upstream submission - hopefully for the 3.7-rc 
cycle. This should be its ID, in linux-mtd.git (and linux-next):

commit bc86cf7af2ebda88056538e8edff852ee627f76a
mtd: nand: fix Samsung SLC NAND identification regression

http://lists.infradead.org/pipermail/linux-mtd/2012-October/044458.html

Please test this fix to see if it fixes your problem, if possible. BTW, 
I would prefer not to use your solution, as the new Samsung ID decode 
table actually applies to some 2-level (i.e., SLC) Samsung NAND, 
particularly K9FAG08U0M.

Brian


From computersforpeace at gmail.com  Wed Oct 31 12:20:01 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 31 Oct 2012 09:20:01 -0700
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <1349855329.6072.72.camel@shinybook.infradead.org>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
 <1349850682.6072.70.camel@shinybook.infradead.org>
 <CAN8TOE-ZLyCanBx8pqsbzY6jMQq+ysiVvdLmWvO8QdnyZg1QRg@mail.gmail.com>
 <1349855329.6072.72.camel@shinybook.infradead.org>
Message-ID: <CAN8TOE8yzJY67b=S=KyONe2pLYGJVe9vW4KXzsjvU7AU9aFpHg@mail.gmail.com>

Hi David,

On Wed, Oct 10, 2012 at 12:48 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
> On Tue, 2012-10-09 at 23:39 -0700, Brian Norris wrote:
>> I can see if that's possible, but I think it's unlikely. They don't
>> even bother following standards (ONFI). Is this an obstacle to
>> merging?
>
> No. I already pushed it.

This is a "bump" for a 3.7-rc pull request. This regression has been
noticed by others.

Thanks,
Brian


From dwmw2 at infradead.org  Wed Oct 31 12:30:09 2012
From: dwmw2 at infradead.org (David Woodhouse)
Date: Wed, 31 Oct 2012 16:30:09 +0000
Subject: [PATCH] mtd: nand: Take celltype into account when parsing
 Samsung ext. nand ID's
In-Reply-To: <50914F32.7020605@gmail.com>
References: <1351679539-30651-1-git-send-email-robin@protonic.nl>
 <50914F32.7020605@gmail.com>
Message-ID: <1351701009.8774.24.camel@shinybook.infradead.org>

On Wed, 2012-10-31 at 09:17 -0700, Brian Norris wrote:
> I believe this regression has already been fixed and accepted by David 
> Woodhouse and is awaiting upstream submission - hopefully for the 3.7-rc 
> cycle. This should be its ID, in linux-mtd.git (and linux-next):

Hm, did I not push that to Linus yet? I'll do so shortly. Anything else
we need to get in to 3.7 while I'm at it?

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6171 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20121031/25b9c682/attachment.bin>

From marex at denx.de  Wed Oct 31 12:45:00 2012
From: marex at denx.de (Marek Vasut)
Date: Wed, 31 Oct 2012 17:45:00 +0100
Subject: [PATCH for 3.7] mtd: nand: fix Samsung SLC NAND identification
 regression
In-Reply-To: <CAN8TOE8yzJY67b=S=KyONe2pLYGJVe9vW4KXzsjvU7AU9aFpHg@mail.gmail.com>
References: <1349850366-4731-1-git-send-email-computersforpeace@gmail.com>
 <1349855329.6072.72.camel@shinybook.infradead.org>
 <CAN8TOE8yzJY67b=S=KyONe2pLYGJVe9vW4KXzsjvU7AU9aFpHg@mail.gmail.com>
Message-ID: <201210311745.00677.marex@denx.de>

Dear Brian Norris,

> Hi David,
> 
> On Wed, Oct 10, 2012 at 12:48 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
> > On Tue, 2012-10-09 at 23:39 -0700, Brian Norris wrote:
> >> I can see if that's possible, but I think it's unlikely. They don't
> >> even bother following standards (ONFI). Is this an obstacle to
> >> merging?
> > 
> > No. I already pushed it.
> 
> This is a "bump" for a 3.7-rc pull request. This regression has been
> noticed by others.

[whine] my nand doesn't work ;-)

Thanks for keeping eye on this, Brian.

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Wed Oct 31 13:18:55 2012
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 31 Oct 2012 10:18:55 -0700
Subject: [PATCH] mtd: nand: Take celltype into account when parsing
 Samsung ext. nand ID's
In-Reply-To: <1351701009.8774.24.camel@shinybook.infradead.org>
References: <1351679539-30651-1-git-send-email-robin@protonic.nl>
 <50914F32.7020605@gmail.com>
 <1351701009.8774.24.camel@shinybook.infradead.org>
Message-ID: <CAN8TOE9epkK8GCbx5KoKKKQna83uWT-sJ9WFob1F3V0LU5h3+Q@mail.gmail.com>

On Wed, Oct 31, 2012 at 9:30 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
> On Wed, 2012-10-31 at 09:17 -0700, Brian Norris wrote:
>> I believe this regression has already been fixed and accepted by David
>> Woodhouse and is awaiting upstream submission - hopefully for the 3.7-rc
>> cycle. This should be its ID, in linux-mtd.git (and linux-next):
>
> Hm, did I not push that to Linus yet? I'll do so shortly. Anything else
> we need to get in to 3.7 while I'm at it?

I don't know of much, but this commit is actually relevant to the same
patch series, since I increased the max OOB size. In l2-mtd-2.6.git:

commit acc6ceeb2ee2f1c7dae1e25914b40f0c294f6b42
mtd: nand: Increase the ecc placement locations to 640

I'll leave it to the author (Vipin), Artem, and you to decide if it
needs to be pushed ahead to 3.7.

Brian


